貿易関係ネットワーク分析 scikit-learn

貿易関係ネットワーク分析

貿易関係ネットワーク分析の例題として、いくつかの国とそれらの国々間の貿易量を示す仮想的なデータを用いて、scikit-learnでネットワーク分析を行います。

ここでは、ネットワークの可視化にはNetworkXMatplotlibを使用します。

まずは以下のスクリプトを使ってデータを生成してみましょう:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Copy code
import numpy as np
import networkx as nx
import matplotlib.pyplot as plt

# 仮想的な貿易量のデータを作成
countries = ['USA', 'China', 'Japan', 'Germany', 'UK']
trade_data = np.array([[0, 100, 50, 80, 20],
[100, 0, 70, 40, 10],
[50, 70, 0, 60, 30],
[80, 40, 60, 0, 50],
[20, 10, 30, 50, 0]])

# ネットワークの可視化用のグラフを作成
G = nx.from_numpy_matrix(trade_data, create_using=nx.Graph())

# ノードに国名を割り当てる
node_labels = {i: countries[i] for i in range(len(countries))}

# グラフを描画
plt.figure(figsize=(8, 6))
pos = nx.spring_layout(G, seed=42) # ノードの位置を決定
nx.draw(G, pos, with_labels=True, labels=node_labels, node_size=1000, node_color='skyblue', font_size=10)
edge_labels = {(i, j): trade_data[i][j] for i in range(len(countries)) for j in range(len(countries)) if trade_data[i][j] > 0}
nx.draw_networkx_edge_labels(G, pos, edge_labels=edge_labels, font_size=8)

plt.title('Trade Relationship Network')
plt.show()

このスクリプトでは、仮想的な貿易量のデータを作成し、それをネットワークXのグラフに変換しています。

ノードは各国を表し、エッジはそれらの国々間の貿易量を示しています。

ノードの色が青く、ノード間のエッジには貿易量が表示されます。

実行すると、可視化された貿易関係のネットワークが表示されますす。

ネットワークの構造を確認し、各国の貿易関係を分析することができます。

[実行結果]

なお、この例ではデータを手動で作成していますが、実際の貿易データを用いて同様のネットワーク分析を行うことも可能です。

顧客離反予測(チャーン予測) scikit-learn

顧客離反予測(チャーン予測)

顧客離反予測(チャーン予測)の例題として、以下のようなシナリオを考えます:

あるテレコム会社があり、顧客の情報と過去の利用データが得られています。

これを使って、顧客が離反するかどうかを予測し、リテンション戦略を立てたいとします。

scikit-learnを使ってロジスティック回帰モデルを構築し、結果をグラフ化してみましょう。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import confusion_matrix, roc_auc_score, roc_curve

# ダミーデータを生成するための関数(仮想的なデータです)
def generate_dummy_data(n_samples=1000):
np.random.seed(42)
age = np.random.normal(40, 10, n_samples)
usage_months = np.random.randint(1, 25, n_samples)
monthly_expense = np.random.normal(100, 50, n_samples)
churn = np.random.randint(0, 2, n_samples)

data = pd.DataFrame({'Age': age, 'UsageMonths': usage_months, 'MonthlyExpense': monthly_expense, 'Churn': churn})
return data

# ダミーデータを生成
data = generate_dummy_data()

# 特徴量とターゲットに分割
X = data.drop('Churn', axis=1)
y = data['Churn']

# 訓練データとテストデータに分割
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# ロジスティック回帰モデルを構築
model = LogisticRegression()
model.fit(X_train, y_train)

# テストデータを用いて予測
y_pred = model.predict(X_test)
y_prob = model.predict_proba(X_test)[:, 1] # 予測確率を取得

# ROC曲線をプロットして結果を可視化
fpr, tpr, thresholds = roc_curve(y_test, y_prob)
roc_auc = roc_auc_score(y_test, y_prob)

plt.figure(figsize=(8, 6))
plt.plot(fpr, tpr, color='blue', lw=2, label='ROC curve (AUC = {:.2f})'.format(roc_auc))
plt.plot([0, 1], [0, 1], color='gray', lw=2, linestyle='--')
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Receiver Operating Characteristic (ROC) Curve')
plt.legend(loc='lower right')
plt.show()

上記のコードでは、ダミーデータを作成してロジスティック回帰モデルを構築し、ROC曲線をプロットしています。

ROC曲線はモデルの性能を評価する際によく用いられる指標で、AUC (Area Under the Curve) の値が高いほど優れた予測モデルと言えます。

[実行結果]

ソースコード解説

上記のコードは、ロジスティック回帰モデルを使用して顧客離反予測(チャーン予測)を行い、その結果をROC曲線を用いて可視化しています。

以下にコードの詳細を説明します:

  1. ダミーデータを生成する関数 generate_dummy_data:

    • この関数は仮想的なデータを生成するためのもので、乱数を使って顧客の年齢 (Age)、利用期間 (UsageMonths)、月間支出 (MonthlyExpense)、および離反したかどうかを表すターゲット変数 (Churn) を作成します。
  2. ダミーデータの生成:

    • generate_dummy_data() 関数を呼び出して、ダミーデータを生成します。このデータは data という名前のPandas DataFrameに保存されます。
  3. 特徴量とターゲットの分割:

    • X = data.drop('Churn', axis=1) で特徴量 (Age, UsageMonths, MonthlyExpense) を取得します。
    • y = data['Churn'] でターゲット変数 Churn(離反したかどうかを表すラベル)を取得します。
  4. 訓練データとテストデータの分割:

    • train_test_split() を使ってデータを訓練データとテストデータに分割します。テストデータは全体の20%に設定されており、random_state=42 で乱数シードを固定して再現性を保証しています。
  5. ロジスティック回帰モデルの構築と学習:

    • LogisticRegression() を使用してロジスティック回帰モデルを初期化し、fit() メソッドで訓練データに適合させます。
  6. テストデータを用いた予測:

    • predict() メソッドを使用して、テストデータの特徴量を用いて離反の予測を行います。
    • predict_proba() メソッドを使用して、各テストサンプルがクラス1(離反)に属する確率を取得します。
  7. ROC曲線のプロットと結果の可視化:

    • roc_curve() 関数を用いて、予測確率と真のターゲット値を用いてROC曲線のデータを取得します。
    • roc_auc_score() 関数を用いて、ROC曲線の下の面積 (AUC) を計算します。
    • plt.figure() でグラフのサイズを設定し、plt.plot() を用いてROC曲線を描画します。
    • plt.plot([0, 1], [0, 1], color='gray', lw=2, linestyle='--') は対角線を描画し、ランダムな予測の場合の参考として用います。
    • ラベル、軸の範囲、タイトルなどのグラフの詳細設定を行います。
    • 最後に plt.show() でグラフを表示します。

結果として、ROC曲線が表示されます。

この曲線は、モデルの性能評価に使用され、AUCスコアが曲線下の面積を示します。

AUCが高いほど、モデルの性能が良いとされます。

結果解説

表示されるグラフは「Receiver Operating Characteristic (ROC) Curve(受信者動作特性曲線)」です。

ROC曲線は、二値分類モデル(ここではロジスティック回帰モデル)の性能評価に用いられるグラフで、以下の要素で構成されています:

  • X軸(横軸): False Positive Rate (FPR)

    • FPRは、実際には陰性(クラス0)であるもののうち、モデルが陽性(クラス1)と誤って予測したサンプルの割合を示します。計算式は FPR = FP / (FP + TN) であり、FPは偽陽性の数、TNは真陰性の数です。
  • Y軸(縦軸): True Positive Rate (TPR) または Recall

    • TPRは、実際には陽性(クラス1)であるもののうち、モデルが陽性と正しく予測したサンプルの割合を示します。計算式は TPR = TP / (TP + FN) であり、TPは真陽性の数、FNは偽陰性の数です。

ROC曲線の解釈:

  • 曲線の左下に近いほど、FPRが低く、真陰性率が高くなりますが、偽陽性率が高くなる傾向があります。
  • 曲線の右上に近いほど、FPRが高く、真陽性率が高くなりますが、偽陰性率が低くなる傾向があります。

AUC (Area Under the Curve):

  • ROC曲線の下の面積をAUCと呼びます。AUCは0から1の間の値を取り、モデルの性能を評価する指標です。

AUCが1に近いほど、モデルの性能が優れていると言えます。

このグラフを見ることで、モデルの性能がどれくらい優れているかが把握できます。

AUCが高いほど、モデルの予測精度が高いと言えます。ROC曲線が左上に近いほど、優れた分類モデルと言えます。

リハビリテーション支援 scikit-learn

リハビリテーション支援

リハビリテーション支援の例として、患者のリハビリテーション進捗データを使用して、適切な運動プランを提案する問題を考えます。

データには、患者の週ごとのリハビリテーションの目標と実績のデータが含まれています。

scikit-learnを使用して、患者の週ごとのリハビリテーション進捗を予測し、運動プランを提案するモデルを構築します。

まず、仮想的なデータを生成して、問題を定義します:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression

# 仮想的なリハビリテーション進捗データの生成
np.random.seed(0)
weeks = np.arange(1, 11)
target_progress = np.random.randint(10, 50, size=len(weeks))
actual_progress = target_progress + np.random.randint(-5, 5, size=len(weeks))

# データフレームに格納
rehab_data = pd.DataFrame({'Week': weeks, 'Target Progress': target_progress, 'Actual Progress': actual_progress})

# データの表示
print(rehab_data)

データを生成したら、線形回帰を使用してリハビリテーション進捗を予測し、結果をグラフ化します:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 線形回帰モデルの構築
X = rehab_data['Week'].values.reshape(-1, 1)
y = rehab_data['Actual Progress'].values
model = LinearRegression()
model.fit(X, y)

# 予測した進捗データの生成
predicted_progress = model.predict(X)

# グラフ化
plt.scatter(weeks, actual_progress, label='Actual Progress', color='b')
plt.plot(weeks, predicted_progress, label='Predicted Progress', color='r')
plt.xlabel('Week')
plt.ylabel('Rehabilitation Progress')
plt.title('Rehabilitation Progress Prediction')
plt.legend()
plt.show()

このコードでは、線形回帰を用いて週ごとのリハビリテーション進捗を予測しています。

散布図で実績の進捗を青で、予測した進捗を赤で表示します。グラフを通じて、リハビリテーションの進捗を予測することができます。

実際のデータを使用する場合は、適切なデータセットを用意してください。

[実行結果]

ソースコード解説

このソースコードは、リハビリテーション支援の例として、患者のリハビリテーション進捗データを使用して、週ごとの実績の進捗を予測し、結果をグラフ化するものです。

以下、各部分の詳細な説明です:

1. import文:必要なライブラリをインポートしています。

  • numpynp): 数値計算のためのライブラリ。
  • pandaspd): データフレーム操作のためのライブラリ。
  • matplotlib.pyplotplt): グラフ描画のためのライブラリ。
  • LinearRegression(線形回帰モデル): scikit-learnの線形回帰モデルを使用するためのクラス。

2. データ生成:

  • np.random.seed(0): 乱数のシードを設定して再現性を持たせます。
  • weeks = np.arange(1, 11): 1から10までの週の数値を生成し、weeksに代入します。
  • target_progress = np.random.randint(10, 50, size=len(weeks)): 10から49までのランダムな整数をweeksの数だけ生成し、target_progressに代入します。
  • actual_progress = target_progress + np.random.randint(-5, 5, size=len(weeks)): target_progressに対して、-5から5までのランダムな整数を足して、actual_progressに代入します。

3. データフレームの作成:

  • pd.DataFrame: weekstarget_progressactual_progressを列とするデータフレームrehab_dataを作成します。

4. データ表示:

  • print(rehab_data): rehab_dataを表示します。生成されたリハビリテーション進捗データが表示されます。

5. 線形回帰モデルの構築:

  • X = rehab_data['Week'].values.reshape(-1, 1): rehab_dataの’Week’列を入力データXとして取得し、1次元の配列から2次元の行列に変形します。
  • y = rehab_data['Actual Progress'].values: rehab_dataの’Actual Progress’列をターゲットデータyとして取得します。
  • model = LinearRegression(): 線形回帰モデルのインスタンスを作成します。
  • model.fit(X, y): モデルをデータに適合させます(トレーニング)。

6. 予測した進捗データの生成:

  • predicted_progress = model.predict(X): モデルを使用して、Xを入力として実績の進捗を予測し、predicted_progressに代入します。

7. グラフ化:

  • plt.scatter(weeks, actual_progress, label='Actual Progress', color='b'): 実際の進捗を青い散布図としてプロットします。
  • plt.plot(weeks, predicted_progress, label='Predicted Progress', color='r'): 予測した進捗を赤い線でプロットします。
  • plt.xlabel('Week'): x軸のラベルを設定します。
  • plt.ylabel('Rehabilitation Progress'): y軸のラベルを設定します。
  • plt.title('Rehabilitation Progress Prediction'): グラフのタイトルを設定します。
  • plt.legend(): 凡例を表示します。
  • plt.show(): グラフを表示します。

最終的に、実際の進捗を青い散布図で表し、線形回帰モデルによって予測された進捗を赤い線で表すグラフが描画されます。

結果解説

線形回帰モデルを使用して実績の進捗を予測し、その結果をグラフ化しました。

実際の進捗(青の散布図)と、線形回帰モデルによる予測された進捗(赤の線)が表示されます。

結果として、赤い線が青い点に近いことから、線形回帰モデルが実績の進捗をうまく予測していることが分かります。


この例では、10週間のリハビリテーション進捗データを用いて、線形回帰モデルにより次の週の進捗を予測しています。

実際のデータを使用する場合は、より多くのデータポイントを持つデータセットを使用することで、より精度の高い予測が期待できます。

また、他の機械学習アルゴリズムを試すことも検討すると良いでしょう。

レシピの評価 PyTorch

レシピの評価

PyTorchを使用してレシピの評価を行うためのサンプルコードを提供します。

ここでは、レシピの評価を予測するための単純なニューラルネットワークを訓練します。

この例では、レシピの特徴(例えば、調理時間、使用される食材の数、ステップの数など)を入力として使用し、評価(星の数)を出力として予測します。

まず、必要なライブラリをインポートします。

1
2
3
4
import torch
import torch.nn as nn
import torch.optim as optim
import matplotlib.pyplot as plt

次に、ニューラルネットワークの定義を行います。

1
2
3
4
5
6
7
8
9
10
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.fc1 = nn.Linear(3, 5) # 3 input features, 5 hidden nodes
self.fc2 = nn.Linear(5, 1) # 5 hidden nodes, 1 output node for rating

def forward(self, x):
x = torch.relu(self.fc1(x))
x = self.fc2(x)
return x

次に、訓練データとテストデータを定義します。ここでは、ダミーデータを使用します。

1
2
3
4
5
6
# Dummy data
train_features = torch.rand(100, 3) # 100 recipes, 3 features each
train_ratings = torch.randint(1, 6, (100, 1)).float() # ratings from 1 to 5

test_features = torch.rand(20, 3) # 20 recipes, 3 features each
test_ratings = torch.randint(1, 6, (20, 1)).float() # ratings from 1 to 5

次に、ネットワークを訓練します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
net = Net()
criterion = nn.MSELoss()
optimizer = optim.SGD(net.parameters(), lr=0.01)

# Store losses for plotting
losses = []

for epoch in range(500): # number of epochs
optimizer.zero_grad()
outputs = net(train_features)
loss = criterion(outputs, train_ratings)
loss.backward()
optimizer.step()

losses.append(loss.item())

# Plot the loss over time
plt.plot(losses)
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.show()

最後に、テストデータを使用してネットワークの性能を評価します。

1
2
3
4
5
with torch.no_grad():
predictions = net(test_features)
loss = criterion(predictions, test_ratings)

print('Test loss: ', loss.item())
[実行結果]

このコードは、レシピの評価を予測するための基本的なニューラルネットワークを訓練します。

実際の問題では、より多くの特徴量を使用し、より複雑なネットワークを訓練することがあります。

また、データの前処理や特徴量の選択、ハイパーパラメータの調整など、さまざまな手法を使用してモデルの性能を向上させることが可能です。

ソースコード解説

このコードは、PyTorchを使用して評価データを元にレシピの評価を予測するためのニューラルネットワークモデルを定義し、学習とテストを行っています。

以下では、処理の各ステップを詳しく説明します。

1. モデルの定義:

Netクラスは、3つの入力特徴を持つニューラルネットワークを定義しています。
1つ目の隠れ層には5つのノードがあります。
forwardメソッドは、入力データを順伝播させるための関数です。
1つ目の隠れ層の活性化関数にReLU(Rectified Linear Unit)を使用しています。

2. ダミーデータの作成:

ランダムな特徴量とランダムな評価を持つ100個のトレーニング用レシピデータと20個のテスト用レシピデータを作成しています。
特徴量は各レシピに対する入力データであり、評価は各レシピのターゲット(正解ラベル)です。

3. モデルの学習:

Netモデルを初期化し、平均二乗誤差(MSE)を損失関数、SGD(Stochastic Gradient Descent)をオプティマイザとして使用しています。
500エポック(学習回数)を実行し、各エポックの損失を保存しています。
モデルのパラメータはoptimizer.step()によって更新されます。

4. 損失のプロット:

学習中の損失値をプロットしています。
エポック数が増えるにつれて損失が減少することが期待されます。
損失のグラフを確認することで、学習が進行するにつれてモデルのパフォーマンスが向上しているかどうかを視覚的に確認できます。

5. テスト:

学習が完了した後、モデルを使用してテストデータを予測します。
テストデータの予測結果と実際の評価との間のMSE(平均二乗誤差)を計算しています。
MSEは予測と実際の評価の差を表す指標であり、予測精度を評価する際に一般的に使用されます。

コード全体の実行結果として、学習中の損失がグラフ化され、テストデータに対する予測誤差(MSE)が表示されます。
学習が進行するにつれて損失が減少し、テストデータに対する予測がどの程度の精度で行われるかがわかります。
また、MSEの値が小さいほど予測が正確であることを意味します。

結果解説

このコードを実行すると、以下の結果が表示されます。

1. グラフ: 損失のプロット

  • グラフが表示されます。
    x軸はエポック数を表し、y軸は損失値(MSE)を表します。
    エポック数が増えるにつれて損失がどのように減少しているかを示します。
    学習が進行するにつれて損失が減少することが期待されます。
    損失が減少し続けることで、モデルがトレーニングデータに適応していることが示されます。

2. テスト損失の値

  • 学習が完了した後、テストデータを用いてモデルの評価を行います。
    その結果として、テストデータに対する予測と実際の評価との間のMSE(平均二乗誤差)が表示されます。
    MSEは予測と実際の評価の差を表す指標であり、値が小さいほど予測が正確であることを示します。
    テスト損失の値が小さい場合は、モデルがテストデータに対してより正確な予測を行っていることを示します。

なお、具体的な数値によって結果がどのように表示されるかはデータや学習の状況により異なりますが、一般的には損失のグラフが学習回数に応じて減少し、テスト損失が小さくなることが期待されます。

これは、モデルがデータに適応し、過学習(オーバーフィッティング)を避けるように学習が進行していることを示します。

信用リスク評価 PyTorch

信用リスク評価

信用リスク評価のためのPyTorchのサンプルコードを提供します。

以下のコードは、単純なニューラルネットワークを使用して二値分類(信用リスクあり/なし)を行います。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import torch
import torch.nn as nn
import torch.optim as optim
import matplotlib.pyplot as plt

# データの準備(仮のデータ)
# 例として、収入と借入金額を特徴量とし、信用リスクの有無をラベルとします
income = torch.tensor([100, 50, 75, 125, 80, 90, 60, 95, 120, 115], dtype=torch.float32)
debt = torch.tensor([0, 100, 50, 200, 150, 50, 100, 80, 150, 180], dtype=torch.float32)
labels = torch.tensor([0, 1, 0, 1, 1, 0, 1, 0, 1, 1], dtype=torch.float32)

# ニューラルネットワークの定義
class CreditRiskModel(nn.Module):
def __init__(self):
super(CreditRiskModel, self).__init__()
self.fc1 = nn.Linear(2, 5)
self.fc2 = nn.Linear(5, 1)
self.sigmoid = nn.Sigmoid()

def forward(self, x):
x = torch.relu(self.fc1(x))
x = self.sigmoid(self.fc2(x))
return x

# モデルの初期化
model = CreditRiskModel()

# 損失関数と最適化アルゴリズムの定義
criterion = nn.BCELoss()
optimizer = optim.SGD(model.parameters(), lr=0.01)

# 学習ループ
losses = []
for epoch in range(100):
# フォワードプロパゲーション
outputs = model(torch.stack([income, debt], dim=1))
loss = criterion(outputs.squeeze(), labels)

# バックワードプロパゲーションとパラメータの更新
optimizer.zero_grad()
loss.backward()
optimizer.step()

# 損失の記録
losses.append(loss.item())

# 損失のグラフ表示
plt.plot(losses)
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.title('Training Loss')
plt.show()

# 予測結果のグラフ表示
with torch.no_grad():
predictions = model(torch.stack([income, debt], dim=1)).squeeze().numpy()
plt.scatter(income.numpy(), debt.numpy(), c=predictions, cmap='coolwarm')
plt.xlabel('Income')
plt.ylabel('Debt')
plt.title('Credit Risk Evaluation')
plt.colorbar(label='Predicted Probability')
plt.show()

このコードでは、収入と借入金額を特徴量とし、信用リスクの有無をラベルとしています。

ニューラルネットワークを定義し、損失関数と最適化アルゴリズムを設定しています。

学習ループを通じてモデルをトレーニングし、損失の推移をグラフ化しています。

また、最終的な予測結果をグラフ化しています。

予測結果は、収入と借入金額の散布図として表示され、色の濃淡で予測された確率が示されます。

[実行結果]


このサンプルコードは、単純な信用リスク評価の例です。

実際の信用リスク評価には、より多くの特徴量やより複雑なモデルが必要になる場合があります。

また、データの前処理やモデルのチューニングも重要な要素です。

ご参考までに、このサンプルコードをベースにして、実際のデータセットやより複雑なモデルを使用して信用リスク評価を行うことができます。



ソースコード解説

このソースコードは、PyTorchを使用して簡単な信用リスク評価モデルを構築し、学習・評価するためのコードです。

以下でソースコードの詳細を説明します:

1. 必要なライブラリのインポート

1
2
3
4
import torch
import torch.nn as nn
import torch.optim as optim
import matplotlib.pyplot as plt

この部分では、PyTorchのモジュールとMatplotlibをインポートしています。

PyTorchはニューラルネットワークの構築と学習に使用され、Matplotlibは学習中の損失値の可視化と予測結果のグラフ表示に使用されます。

2. データの準備

1
2
3
income = torch.tensor([100, 50, 75, 125, 80, 90, 60, 95, 120, 115], dtype=torch.float32)
debt = torch.tensor([0, 100, 50, 200, 150, 50, 100, 80, 150, 180], dtype=torch.float32)
labels = torch.tensor([0, 1, 0, 1, 1, 0, 1, 0, 1, 1], dtype=torch.float32)

この部分では、学習に使用する仮のデータを定義しています。

incomeは収入を示す特徴量、debtは借入金額を示す特徴量、labelsはそれに対応する信用リスクの有無を示すラベルです。

3. ニューラルネットワークの定義

1
2
3
4
5
6
7
8
9
10
11
class CreditRiskModel(nn.Module):
def __init__(self):
super(CreditRiskModel, self).__init__()
self.fc1 = nn.Linear(2, 5)
self.fc2 = nn.Linear(5, 1)
self.sigmoid = nn.Sigmoid()

def forward(self, x):
x = torch.relu(self.fc1(x))
x = self.sigmoid(self.fc2(x))
return x

この部分では、CreditRiskModelという名前のカスタムのPyTorchモデルを定義しています。

モデルは全結合層(Linear)で構成され、2つの入力ユニット(特徴量が2つ)から5つのユニットを持つ隠れ層に接続され、その後1つの出力ユニットに接続されます。

活性化関数としてReLUとシグモイド関数が使われます。

4. モデルの初期化

1
model = CreditRiskModel()

ここで、先ほど定義したCreditRiskModelのインスタンスを作成します。

5. 損失関数と最適化アルゴリズムの定義

1
2
criterion = nn.BCELoss()
optimizer = optim.SGD(model.parameters(), lr=0.01)

損失関数としては、Binary Cross Entropy Loss(二値分類のクロスエントロピー損失)であるnn.BCELoss()が使用されます。

最適化アルゴリズムとしては、確率的勾配降下法(SGD)が使用され、学習率は0.01です。

6. 学習ループ

1
2
3
4
5
6
7
8
9
10
11
12
13
losses = []
for epoch in range(100):
# フォワードプロパゲーション
outputs = model(torch.stack([income, debt], dim=1))
loss = criterion(outputs.squeeze(), labels)

# バックワードプロパゲーションとパラメータの更新
optimizer.zero_grad()
loss.backward()
optimizer.step()

# 損失の記録
losses.append(loss.item())

ここでは、モデルを学習するためのループが100エポック(学習のイテレーション回数)で実行されます。

ループ内で行われる主なステップは次の通りです:

  • フォワードプロパゲーション:学習データをモデルに入力して予測値を計算します。
  • 損失の計算:予測値と正解ラベルとの誤差を計算します。
  • バックワードプロパゲーション:誤差を使って勾配を計算します。
  • パラメータの更新:SGDによって、モデルのパラメータを勾配に従って更新します。
  • 損失の記録:各エポックでの損失値をlossesリストに保存します。

7. 損失のグラフ表示

1
2
3
4
5
plt.plot(losses)
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.title('Training Loss')
plt.show()

この部分では、学習中の損失値の推移をグラフで表示しています。

エポック数に対する損失の変化を確認できます。

8. 予測結果のグラフ表示

1
2
3
4
5
6
7
8
with torch.no_grad():
predictions = model(torch.stack([income, debt], dim=1)).squeeze().numpy()
plt.scatter(income.numpy(), debt.numpy(), c=predictions, cmap='coolwarm')
plt.xlabel('Income')
plt.ylabel('Debt')
plt.title('Credit Risk Evaluation')
plt.colorbar(label='Predicted Probability')
plt.show()

最後に、学習済みモデルを使用して予測を行い、収入と借入金額の散布図を作成します。

ここでは、with torch.no_grad()のコンテキストマネージャを使用して、計算グラフの構築を無効にし、勾配計算を行わないようにしています。

これは、予測時には勾配情報が不要であるためです。

model(torch.stack([income, debt], dim=1))により、学習済みモデルに入力データを与えて予測値を取得しています。

squeeze()は、サイズが1の次元を削除して、1次元のテンソルに変換します。

最後に、この予測値をNumPy配列に変換してpredictionsとして保存しています。

その後、plt.scatter()を使用して収入と借入金額を散布図として表示しています。

点の色はc=predictionsによって予測された信用リスクの確率に対応しており、色は’coolwarm’カラーマップを使用して表現されます。

このように、可視化を通じて予測結果の確認と理解を行っています。


以上で、ソースコード全体の詳細な説明が終わりました。

これは簡単な2つの特徴量を持つ信用リスク評価モデルの構築と学習を行う例です。

実際のアプリケーションでは、より複雑なデータやモデルを使用することが一般的ですが、このコードは基本的な流れを示しています。

結果解説

信用リスク評価の結果を示すグラフは、収入と借入金額の2つの特徴量を使用して作成されています。

以下に、グラフの詳細な説明を提供します。

このグラフは、収入と借入金額の2つの軸を持つ散布図です。

各データポイントは、収入と借入金額の値を持ち、その色の濃淡は予測された信用リスクの確率を示しています。

具体的には、収入がx軸に表示され、借入金額がy軸に表示されます。

データポイントの色の濃淡は、予測された信用リスクの確率を示しています。

色のスケールは、予測された確率の値に基づいて設定されており、濃い色ほど高い確率を示します。


このグラフを見ることで、収入と借入金額の組み合わせが信用リスクの予測にどのように関連しているかを視覚的に理解することができます。

例えば、収入が高く、借入金額が低い場合は、低い信用リスクの確率を示す明るい色が表示されるでしょう。

逆に、収入が低く、借入金額が高い場合は、高い信用リスクの確率を示す濃い色が表示されるでしょう。

このようなグラフを使用することで、信用リスクの予測結果を直感的に理解することができます。

データポイントの分布や色の変化を観察することで、信用リスクの要因や傾向を把握することができます。

これにより、信用リスクの評価や意思決定に役立つ情報を得ることができます。

PyTorch

PyTorchを使用して医療診断支援を行うためのサンプルコードを提供します。

この例では、糖尿病の診断を行うためのシンプルなニューラルネットワークを訓練します。

また、訓練結果をグラフ化するためにmatplotlibを使用します。

1. ライブラリのインポート

まず、必要なライブラリをインポートします。

1
2
3
4
5
6
import torch
from torch import nn, optim
import torch.nn.functional as F
from sklearn.datasets import load_diabetes
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt

このコードでは、PyTorchの他に、scikit-learnからデータセットを読み込むためにload_diabetes関数と、トレーニングデータとテストデータを分割するためにtrain_test_split関数を使用します。

また、結果を可視化するためにmatplotlibも使用しています。

2. データの準備

糖尿病データセットをロードし、訓練データとテストデータに分割します。

1
2
3
4
5
6
7
diabetes = load_diabetes()
X_train, X_test, y_train, y_test = train_test_split(diabetes.data, diabetes.target, test_size=0.2, random_state=0)

X_train = torch.tensor(X_train, dtype=torch.float32)
X_test = torch.tensor(X_test, dtype=torch.float32)
y_train = torch.tensor(y_train, dtype=torch.float32)
y_test = torch.tensor(y_test, dtype=torch.float32)

データセットを読み込んで、トレーニングデータとテストデータに分割します。

そして、PyTorchのテンソルに変換しています。

3. ニューラルネットワークモデルの定義:

ニューラルネットワークのモデルを定義します。

1
2
3
4
5
6
7
8
9
10
11
12
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.fc1 = nn.Linear(10, 32)
self.fc2 = nn.Linear(32, 1)

def forward(self, x):
x = F.relu(self.fc1(x))
x = self.fc2(x)
return x

model = Net()

Netという名前のクラスを定義しています。

このネットワークは、2つの全結合層(nn.Linear)から構成されています。

入力サイズが10で、出力サイズが32の最初の層(fc1)があり、その後に32から1の出力サイズの2番目の層(fc2)が続きます。

活性化関数としてReLU関数を使用しています。

4. 損失関数とオプティマイザの設定:

損失関数と最適化手法を定義します。

1
2
criterion = nn.MSELoss()
optimizer = optim.Adam(model.parameters())

損失関数には平均二乗誤差(Mean Squared Error, MSE)を使用し、オプティマイザにはAdamアルゴリズムを使用してモデルのパラメータを最適化します。

5. トレーニングとテスト:

モデルの訓練を行います。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
epochs = 500
train_losses, test_losses = [], []
for e in range(epochs):
optimizer.zero_grad()
output = model(X_train)
loss = criterion(output.squeeze(), y_train)
loss.backward()
optimizer.step()
train_losses.append(loss.item())

with torch.no_grad():
output = model(X_test)
loss = criterion(output.squeeze(), y_test)
test_losses.append(loss.item())

500エポックのトレーニングループがあります。

各エポックでは、まず勾配をゼロにリセットし(optimizer.zero_grad())、トレーニングデータをモデルに入力して出力を得ます。

その出力と正解ラベルとの平均二乗誤差を計算し、逆伝搬を行って勾配を計算します(loss.backward())。

その後、オプティマイザを用いてモデルのパラメータを更新します(optimizer.step())。

トレーニングおよびテストのロスはそれぞれtrain_lossestest_lossesに記録されます。

6. ロスの可視化:

最後に、訓練とテストの損失をグラフ化します。

1
2
3
4
5
plt.plot(train_losses, label='Training loss')
plt.plot(test_losses, label='Test loss')
plt.legend()
plt.grid()
plt.show()

トレーニングとテストのロスをmatplotlibを使って可視化します。

トレーニングロスは青色、テストロスはオレンジ色でプロットされます。

これにより、ニューラルネットワークモデルをトレーニングしてそのパフォーマンスを評価し、過学習などの問題を視覚的に確認することができます。

[実行結果]

結果解説

このコードによって表示されるグラフには、トレーニングロスとテストロスの履歴がプロットされています。

これらのロスはエポックごとに計算され、トレーニングとテストの進捗を示す重要な情報を提供します。


横軸はエポック数を表し、縦軸は平均二乗誤差(MSE)の値を表します。

MSEは予測値と実際の値との差の2乗の平均であり、モデルの性能を評価する指標の一つです。

MSEが小さいほど、モデルの予測が実際の値に近いことを意味します。

グラフには2つの曲線が表示されます:

1. トレーニングロス(Training loss):

この曲線は青色でプロットされています。

エポック数が増えるにつれて、トレーニングデータセットに対するモデルのロスがどのように変化しているかを示します。

トレーニングロスが減少している場合、モデルはトレーニングデータに適応しており、学習が進んでいることを示します。

2. テストロス(Test loss):

この曲線はオレンジ色でプロットされています。

エポック数が増えるにつれて、テストデータセットに対するモデルのロスがどのように変化しているかを示します。

テストロスが減少している場合、モデルはテストデータに対しても良い予測結果を出力しており、汎化性能があると言えます。


グラフを見ることで、トレーニングとテストのロスがどのように変化しているかを比較できます。

トレーニングロスとテストロスが収束している場合は、過学習が少ない良いモデルと言えます。

逆に、トレーニングロスは減少しているが、テストロスが増加している場合は、過学習が発生している可能性があります。

また、ロスが収束していない場合は、モデルのトレーニングが不十分であることを示します。

トレーニングロスとテストロスの遷移を観察することで、モデルのパフォーマンスや学習の進捗を理解し、必要に応じてハイパーパラメータの調整やモデルの改善を行うことができます。

トラフィック予測 PyTorch

トラフィック予測

トラフィック予測は時系列データの予測タスクになります。

ここでは、LSTM (Long Short-Term Memory) モデルを使用してPyTorchでトラフィック予測を行うサンプルコードを示します。

データセットとしては、シカゴの交通量データを仮想的に生成します。

まず、以下のコードを使用してPyTorchと必要なライブラリをインポートします。

1
2
3
4
5
import torch
import torch.nn as nn
import torch.optim as optim
import numpy as np
import matplotlib.pyplot as plt

次に、トラフィックデータを生成します。

1
2
3
4
5
6
7
8
9
10
11
12
# 仮想的なトラフィックデータを生成
np.random.seed(0)
num_points = 500
time_steps = np.linspace(0, 20, num_points)
traffic_data = np.sin(time_steps) + np.random.uniform(-0.5, 0.5, num_points)

# データを正規化
traffic_data = (traffic_data - np.min(traffic_data)) / (np.max(traffic_data) - np.min(traffic_data))

# トレーニングデータとテストデータに分割
train_data = traffic_data[:400]
test_data = traffic_data[400:]

次に、LSTMモデルを定義します。

1
2
3
4
5
6
7
8
9
10
11
12
13
class LSTMModel(nn.Module):
def __init__(self, input_size, hidden_size, output_size):
super(LSTMModel, self).__init__()
self.hidden_size = hidden_size
self.lstm = nn.LSTM(input_size, hidden_size, batch_first=True)
self.fc = nn.Linear(hidden_size, output_size)

def forward(self, x):
h0 = torch.zeros(1, x.size(0), self.hidden_size).to(x.device)
c0 = torch.zeros(1, x.size(0), self.hidden_size).to(x.device)
out, _ = self.lstm(x, (h0, c0))
out = self.fc(out[:, -1, :])
return out

データの準備とモデルの定義ができたら、次にトレーニングを行います。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# ハイパーパラメータ
input_size = 1
hidden_size = 32
output_size = 1
num_epochs = 100
learning_rate = 0.01

# モデルと損失関数、オプティマイザの定義
model = LSTMModel(input_size, hidden_size, output_size)
criterion = nn.MSELoss()
optimizer = optim.Adam(model.parameters(), lr=learning_rate)

# トレーニングループ
train_data = torch.tensor(train_data, dtype=torch.float32).view(-1, 1, 1)
test_data = torch.tensor(test_data, dtype=torch.float32).view(-1, 1, 1)

for epoch in range(num_epochs):
model.train()
outputs = model(train_data)
loss = criterion(outputs, train_data)
optimizer.zero_grad()
loss.backward()
optimizer.step()

if (epoch + 1) % 10 == 0:
print(f'Epoch [{epoch + 1}/{num_epochs}], Loss: {loss.item():.4f}')

# テストデータでの予測
model.eval()
with torch.no_grad():
test_outputs = model(test_data)
test_outputs = test_outputs.view(-1).numpy()
test_data = test_data.view(-1).numpy()

# グラフ化
plt.figure(figsize=(10, 6))
plt.plot(time_steps[400:], test_data, label='Actual Data', color='blue')
plt.plot(time_steps[400:], test_outputs, label='Predicted Data', color='red')
plt.xlabel('Time')
plt.ylabel('Traffic Data')plt.legend()
plt.show()

このコードは、トラフィックデータをLSTMモデルでトレーニングし、予測結果をグラフで表示します。

時間の経過に伴うトラフィックデータの予測と実測を比較することができます。

[実行結果]

ソースコード解説

このソースコードは、PyTorchを使用してトラフィックデータの予測を行うためのサンプルコードです。

以下でコードの詳細を説明します。

  1. データ生成:

    • np.random.seed(0) でランダムシードを設定して再現性を確保します。
    • num_points は生成するデータの点の数を指定します。
    • time_steps は時間の経過を表す連続した値を生成します。
    • traffic_datanp.sin(time_steps) にランダムなノイズを加えてトラフィックデータを仮想的に生成します。
    • 生成したトラフィックデータを [0, 1] の範囲に正規化します。
  2. LSTMモデルの定義:

    • LSTMModel クラスは nn.Module クラスを継承しています。
    • モデルの構造として、LSTM層を使用して時系列データを学習し、最後に全結合層を用いて予測を行います。
  3. ハイパーパラメータの設定:

    • input_size, hidden_size, output_size はモデルの入力次元数、隠れ状態の次元数、出力次元数を設定します。
    • num_epochs はトレーニングのエポック数を指定します。
    • learning_rate はオプティマイザの学習率を設定します。
  4. モデルの初期化:

    • LSTMModel クラスを使用して、定義したモデルを初期化します。
    • nn.MSELoss() を使用して、損失関数として平均二乗誤差を設定します。
    • optim.Adam() を使用して、Adamオプティマイザを定義します。
  5. トレーニングループ:

    • トレーニングデータをPyTorchのテンソルに変換して、LSTMモデルに渡します。
    • モデルをトレーニングして損失を計算し、バックプロパゲーションとオプティマイザの更新を行います。
  6. テストデータでの予測:

    • トレーニングが終了した後、テストデータをモデルに渡して予測を行います。
    • 予測結果をNumpy配列に変換して、グラフ表示のためのデータにします。
  7. グラフ化:

    • Matplotlibを使用して、実測データと予測データをグラフ上にプロットします。

グラフは、実際のトラフィックデータ(青色)とモデルによる予測データ(赤色)が表示されています。

トレーニングを通じてモデルがデータに適応し、テストデータで予測性能がどのようになるかを確認することができます。

結果解説

この結果は、トラフィック予測のトレーニング中にエポックごとの損失値が表示されています。

エポック数が増えるにつれて損失が減少していることがわかります。

損失は、モデルがトレーニングデータに適応するように最適化される指標であり、小さいほどモデルがデータに適合していることを意味します。

具体的には、次のように解釈できます:

  • Epoch [10/100], Loss: 0.0858:
    10回目のエポックのトレーニングでは、平均二乗誤差(Mean Squared Error)が約0.0858となっています。
  • Epoch [20/100], Loss: 0.0834:
    20回目のエポックのトレーニングでは、損失がわずかに減少して約0.0834となっています。
  • Epoch [30/100], Loss: 0.0707:
    30回目のエポックのトレーニングでは、損失がさらに減少して約0.0707となっています。
  • …(以下、同様の解釈)

エポックが進むにつれて、モデルはトレーニングデータの特徴をよりよく捉えるようになり、損失が小さくなっていることがわかります。

ただし、損失が小さいからと言って、必ずしもモデルが良い予測結果を得られるわけではありません。

過学習に陥っている可能性もあるため、テストデータでの性能を確認することも重要です。


グラフを見ると、予測データが実測データに近づいていることが分かるでしょうか?

モデルがトラフィックデータをうまく学習できたため、未知のデータに対してもある程度の予測ができていることが示唆されています。

ただし、実際の応用では、さまざまなハイパーパラメータやモデルアーキテクチャの調整、さらにはより多くのデータや特徴量の考慮などが必要になる場合があります。

病状診断 PyTorch

病状診断

病状診断は医療分野に属する複雑な問題であり、実際の医療診断には十分なデータセットや専門知識が必要です。

ここでは、サンプルとしてシンプルな乳がんの診断を行うコードを示します。

乳がんの診断は二値分類問題で、PyTorchを使用して簡単なニューラルネットワークを構築して実行します。

このサンプルでは、乳がんのデータセットであるBreast Cancer Wisconsin (Diagnostic) Data Setを使用します。

データセットはscikit-learnライブラリから利用できます。

また、結果を分かりやすくするためにMatplotlibを使用してグラフ化します。

まず、必要なライブラリをインポートします。

1
2
3
4
5
6
import torch
import torch.nn as nn
import torch.optim as optim
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt

次に、データセットをロードして前処理を行います。

1
2
3
4
5
6
7
8
9
10
# データセットの読み込み
data = load_breast_cancer()
X, y = data.data, data.target

# データをPyTorchのテンソルに変換
X = torch.tensor(X, dtype=torch.float32)
y = torch.tensor(y, dtype=torch.float32).view(-1, 1)

# 訓練データとテストデータに分割
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

次に、簡単なニューラルネットワークモデルを定義します。

1
2
3
4
5
6
7
8
9
10
11
12
13
class SimpleModel(nn.Module):
def __init__(self):
super(SimpleModel, self).__init__()
self.fc1 = nn.Linear(30, 16)
self.fc2 = nn.Linear(16, 8)
self.fc3 = nn.Linear(8, 1)
self.sigmoid = nn.Sigmoid()

def forward(self, x):
x = self.sigmoid(self.fc1(x))
x = self.sigmoid(self.fc2(x))
x = self.sigmoid(self.fc3(x))
return x

次に、モデルを訓練して、結果をグラフ化します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# モデルの初期化
model = SimpleModel()

# 損失関数とオプティマイザの設定
criterion = nn.BCELoss()
optimizer = optim.Adam(model.parameters(), lr=0.01)

# 訓練ループ
num_epochs = 100
train_losses = []
test_losses = []

for epoch in range(num_epochs):
# 訓練
model.train()
optimizer.zero_grad()
outputs = model(X_train)
loss = criterion(outputs, y_train)
loss.backward()
optimizer.step()
train_losses.append(loss.item())

# テスト
model.eval()
with torch.no_grad():
outputs = model(X_test)
loss = criterion(outputs, y_test)
test_losses.append(loss.item())

# グラフのプロット
plt.plot(train_losses, label='Train Loss')
plt.plot(test_losses, label='Test Loss')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.legend()
plt.show()

このコードでは、訓練データとテストデータに対する損失の推移を可視化しています。

訓練データとテストデータの損失が共に減少していることが確認できれば、モデルがうまく機能していることが分かります。

ただし、このサンプルはあくまで簡単なものであり、実際の医療診断にはより高度なモデルや専門知識が必要です。

[実行結果]

ソースコード解説

このソースコードは、PyTorchを使用して単純なニューラルネットワークモデルを定義し、乳がんデータセットを使ってそのモデルを訓練し、訓練とテストの損失をプロットするプログラムです。

  1. データの準備:

    • ライブラリのインポート: 必要なライブラリをインポートします。
      PyTorchのニューラルネットワーク関連のモジュール(torch, torch.nn, torch.optim)やデータセットの読み込みに使うScikit-learn関連のモジュール(sklearn.datasets, sklearn.model_selection)をインポートしています。
    • データセットの読み込み: Scikit-learnのload_breast_cancer()関数を使って乳がんデータセットをロードします。
      このデータセットは、乳がんの診断に関連する特徴量と対応するラベル(0: 悪性、1: 良性)を持つものです。
  2. データの前処理:

    • データをPyTorchのテンソルに変換: NumPy配列からPyTorchのテンソルに変換します。
      特徴量Xは浮動小数点数のテンソルに変換され、ラベルyは浮動小数点数のテンソルに変換され、さらに1次元テンソルに変形(.view(-1, 1))されます。
    • 訓練データとテストデータに分割: train_test_split()関数を使ってデータを訓練データとテストデータに分割します。
      ここでは、全体の20%をテストデータとして使用し、乱数のシードを固定して再現性を確保しています。
  3. ニューラルネットワークモデルの定義:

    • SimpleModelクラス: PyTorchのnn.Moduleを継承した単純なニューラルネットワークモデルを定義しています。
      このモデルは、3つの全結合層(nn.Linear)とそれらの間の活性化関数(nn.Sigmoid)で構成されています。
  4. モデルの初期化:

    • model = SimpleModel(): SimpleModelクラスからモデルをインスタンス化します。
  5. 損失関数とオプティマイザの設定:

    • criterion = nn.BCELoss(): 二値交差エントロピー損失関数(Binary Cross Entropy Loss)を使用します。
      この損失関数は、二値分類問題に適しています。
    • optimizer = optim.Adam(model.parameters(), lr=0.01): Adamオプティマイザを使用して、モデルのパラメータを最適化します。
      学習率(lr)は0.01です。
  6. 訓練ループ:

    • num_epochs = 100: エポック数を100に設定します。
      エポックとは、データセット全体を一度学習することを意味します。
    • train_lossestest_losses: 訓練中に各エポックの訓練損失とテスト損失を保存するためのリストです。
  7. 訓練とテストの実行:

    • model.train(): モデルを訓練モードに設定します。
    • 訓練データで順伝播を行い、損失を計算します。
      そして逆伝播とオプティマイザのステップ(パラメータ更新)を行います。
    • model.eval(): モデルを評価モードに設定します。
      これにより、ドロップアウトなどの評価時にのみ適用されるレイヤーが適切に動作します。
    • テストデータで順伝播を行い、テスト損失を計算します。
      逆伝播は行いません。
  8. グラフのプロット:

    • 訓練とテストの損失をエポックごとにプロットします。
      プロットされたグラフは、訓練損失とテスト損失のエポックごとの変化を可視化するのに役立ちます。

このプログラムは、単純なニューラルネットワークを使って乳がんデータセットを分類するタスクを行っており、訓練とテストの損失を監視することでモデルの学習の進行状況を確認できます。

顧客行動予測 PyTorch

顧客行動予測

PyTorchを使用して顧客行動予測を行うサンプルコードを示します。

ここでは、顧客の過去の購入履歴から次に購入する商品を予測するというシナリオを考えてみましょう。

まずは、必要なライブラリをインポートします。

1
2
3
4
5
import torch
import torch.nn as nn
import torch.optim as optim
import numpy as np
import matplotlib.pyplot as plt

次に、顧客の購入履歴データを模擬的に作成します。

ここでは、10人の顧客が10種類の商品を購入した履歴をランダムに生成します。

1
2
3
4
np.random.seed(0)
num_customers = 10
num_products = 10
purchase_history = np.random.randint(2, size=(num_customers, num_products))

次に、ニューラルネットワークのモデルを定義します。

ここでは、単純な全結合層のみのネットワークを使用します。

1
2
3
4
5
6
7
8
9
10
11
12
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.fc1 = nn.Linear(num_products, 50)
self.fc2 = nn.Linear(50, num_products)

def forward(self, x):
x = torch.relu(self.fc1(x))
x = torch.sigmoid(self.fc2(x))
return x

net = Net()

次に、学習の設定を行います。

損失関数には二値交差エントロピーを、最適化手法にはAdamを使用します。

1
2
criterion = nn.BCELoss()
optimizer = optim.Adam(net.parameters(), lr=0.001)

そして、学習を行います。

ここでは、100エポック学習を行うことにします。

1
2
3
4
5
6
7
8
9
10
11
12
for epoch in range(100):
inputs = torch.from_numpy(purchase_history).float()
targets = torch.from_numpy(purchase_history).float()

optimizer.zero_grad()
outputs = net(inputs)
loss = criterion(outputs, targets)
loss.backward()
optimizer.step()

if epoch % 10 == 0:
print(f'Epoch {epoch}, Loss: {loss.item()}')

最後に、学習結果をグラフ化します。

1
2
3
4
5
6
7
8
9
predicted = net(torch.from_numpy(purchase_history).float()).detach().numpy()
plt.figure(figsize=(10, 5))
plt.subplot(1, 2, 1)
plt.imshow(purchase_history, cmap='binary')
plt.title('Actual')
plt.subplot(1, 2, 2)
plt.imshow(predicted, cmap='binary')
plt.title('Predicted')
plt.show()
[実行結果]

このコードは、顧客の購入履歴を元に次に購入する商品を予測するものです。

ただし、これは非常に単純化された例であり、実際の問題ではより複雑なモデルやデータ前処理が必要になることをご理解ください。

ソースコード解説

コードの詳細を説明します。

1. import 文:

必要なライブラリをインポートします。
torch はPyTorchの主要なライブラリです。
nn はニューラルネットワークを定義するためのサブパッケージ、optim は最適化アルゴリズムを含むサブパッケージ、numpy は数値計算用ライブラリ、matplotlib.pyplot はデータをグラフ化するためのライブラリです。

2. ランダムな顧客の購買履歴データの生成:

np.random.randint(2, size=(num_customers, num_products)) を使用して、0と1のランダムな値で構成されるnum_customers x num_products の行列 purchase_history を生成しています。
これは仮想的なデータであり、各行が各顧客の購買履歴を表しています。

3. ニューラルネットワークモデルの定義:

Net クラスを定義しています。
nn.Module を継承しています。
このモデルは、入力として num_products 個の特徴を受け取り、2つの全結合層 (fc1fc2) を通して処理されます。
fc1 は入力次元から50次元への変換を行い、torch.relu 関数によって活性化されます。
次に、fc2 は50次元から出力次元(num_products)への変換を行い、torch.sigmoid 関数によって0から1の範囲にスケーリングされます。

4. ニューラルネットワークモデルのインスタンス化:

net = Net() を使用して、定義した Net クラスのインスタンス net を作成します。

5. 損失関数と最適化アルゴリズムの定義:

この例では、損失関数に二値交差エントロピー(BCELoss)を使用しています。
最適化アルゴリズムにはAdamを使用しています。
学習率は0.001です。

6. モデルの訓練:

データをPyTorchのTensorに変換し、100エポックの間でモデルを訓練しています。
各エポックで、最適化アルゴリズムによって損失が最小化されるようにモデルの重みを更新しています。

7. 予測と結果のグラフ化:

訓練が終了した後、学習済みのモデルを使って購買履歴データを入力として予測を行い、predicted という変数に予測結果を格納しています。
そして、元の購買履歴データと予測結果を2つのサブプロットを持つグラフとして表示しています。

上記のコードは非常にシンプルな顧客行動予測の例ですが、実際の問題にはさらなるデータの前処理やモデルの改善が必要になることがあります。

CartPole PyTorch

CartPole

OpenAI GymのCartPoleという環境でActor-Critic法を用いた強化学習のサンプルコードを示します。

このコードは、棒を立て続けるためにカートを左右に動かすというタスクを解くためのものです。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import gym
import numpy as np
import torch
import torch.nn as nn
import torch.optim as optim
from torch.distributions import Categorical
import matplotlib.pyplot as plt

class Policy(nn.Module):
def __init__(self):
super(Policy, self).__init__()
self.affine1 = nn.Linear(4, 128)
self.affine2 = nn.Linear(128, 2)

self.saved_log_probs = []
self.rewards = []

def forward(self, x):
x = torch.relu(self.affine1(x))
action_scores = self.affine2(x)
return torch.softmax(action_scores, dim=1)

def select_action(state):
state = torch.from_numpy(state).float().unsqueeze(0)
probs = policy(state)
m = Categorical(probs)
action = m.sample()
policy.saved_log_probs.append(m.log_prob(action))
return action.item()

def finish_episode():
R = 0
policy_loss = []
returns = []
for r in policy.rewards[::-1]:
R = r + 0.99 * R
returns.insert(0, R)
returns = torch.tensor(returns)
returns = (returns - returns.mean()) / (returns.std() + 1e-6)
for log_prob, R in zip(policy.saved_log_probs, returns):
policy_loss.append(-log_prob * R)
optimizer.zero_grad()
policy_loss = torch.cat(policy_loss).sum()
policy_loss.backward()
optimizer.step()
del policy.rewards[:]
del policy.saved_log_probs[:]

policy = Policy()
optimizer = optim.Adam(policy.parameters(), lr=1e-2)

env = gym.make('CartPole-v1')
rewards_history = [] # 保存用の総報酬のリスト
for episode in range(500):
state = env.reset()
total_reward = 0 # エピソードの総報酬
for t in range(10000): # 学習の無限ループを防ぐための上限
action = select_action(state)
state, reward, done, _ = env.step(action)
policy.rewards.append(reward)
total_reward += reward
if done:
break

finish_episode()
rewards_history.append(total_reward) # エピソードごとの総報酬を保存
if episode % 50 == 0:
print('Episode {}\tLast length: {:5d}\tTotal Reward: {}'.format(episode, t, total_reward))

# 総報酬の推移をグラフ化
plt.plot(range(len(rewards_history)), rewards_history)
plt.xlabel('Episode')
plt.ylabel('Total Reward')
plt.title('Total Reward per Episode')
plt.show()

このコードは、CartPoleの環境で棒を立て続けるためにカートを左右に動かすタスクを解くためのものです。

ここでは、ニューラルネットワークを用いてポリシー(行動を選択する確率分布)を表現し、そのポリシーを改善するためにエピソード(一連の行動と報酬)の結果を用いて学習を行っています。

[実行結果]

このコードは基本的な強化学習のフレームワークを示していますが、実際の問題ではより複雑な環境やポリシー、学習アルゴリズムを用いることが多いです。

また、このコードは学習の進行状況を表示するためのロギングや、学習済みのモデルを保存する機能などは省略しています。

これらの機能は実際の開発では重要な要素となります。

ソースコード解説

このソースコードは、強化学習の一種であるPolicy Gradientを用いて、OpenAI GymのCartPole-v1という環境を学習するものです。

CartPoleは、棒を倒さないように台車を左右に動かすというタスクです。


まず、必要なライブラリをインポートします。

gymは強化学習の環境を提供するライブラリ、numpyは数値計算、torchは深層学習のライブラリ、matplotlib.pyplotはグラフ描画のためのライブラリです。


次に、Policyという名前のニューラルネットワークを定義しています。

このネットワークは、状態を入力として受け取り、各アクションの確率を出力します。

このネットワークは2つの全結合層から構成されています。

ReLU活性化関数を用いて非線形性を導入し、softmax関数を用いて出力を確率に変換しています。


select_action関数は、与えられた状態に基づいてアクションを選択します。

この関数は、現在のポリシーを用いてアクションの確率を計算し、その確率に基づいてアクションをサンプリングします。


finish_episode関数は、エピソードが終了したときに呼び出され、ポリシーネットワークの更新を行います。

この関数は、エピソード中に収集された報酬とログ確率を用いて、ポリシーロスを計算し、そのロスを用いてネットワークのパラメータを更新します。


その次にメインの学習ループがあります。

ここでは、環境をリセットし、アクションを選択し、そのアクションを環境に適用し、報酬と新しい状態を受け取り、その報酬を累積します。

エピソードが終了したら(つまり、棒が倒れたら)、エピソードを終了し、ポリシーを更新します。


最後に、エピソードごとの総報酬をプロットして、学習の進行を視覚化します。

これにより、エージェントが時間とともにどの程度学習しているかを確認できます。

どちらかを選択

ソースコードの各部分の説明をします。

  • Policy クラス: ポリシーネットワークを定義するクラスです。nn.Module を継承しており、入力の次元数が4であり、全結合層を2つ持ちます。forward メソッドでは、入力に対してReLU活性化関数を適用し、最後の層の出力をソフトマックス関数によって確率分布として表現します。

  • select_action 関数: 状態に基づいて行動を選択する関数です。状態をテンソルに変換し、ポリシーネットワークを介して行動の確率分布を取得します。確率分布から行動をサンプリングし、その行動の対数確率を保存します。

  • finish_episode 関数: エピソードの終了時に呼び出される関数です。累積報酬を計算し、ポリシーロスを計算します。ポリシーロスは、対数確率と累積報酬の要素ごとの積の総和です。また、ポリシーロスをバックプロパゲーションしてパラメータを更新します。

  • policy インスタンス: Policy クラスのインスタンスであり、ポリシーネットワークを表します。

  • optimizer インスタンス: optim.Adam を使用してポリシーネットワークのパラメータを最適化するためのオプティマイザです。

  • env インスタンス: gym.make を使用してCartPole環境を作成します。

  • rewards_history リスト: エピソードごとの総報酬を保存するためのリストです。

  • エピソードのループ: エピソードごとに以下の処理を実行します。

    • 状態のリセット
    • エピソードの総報酬を初期化
    • タイムステップのループ: 最大タイムステップ数まで繰り返します。
      • select_action 関数を呼び出して行動を選択し、状態、報酬、終了状態を取得します。
      • 報酬を保存し、総報酬に加算します。
      • エピソード終了時にはループを終了します。
    • finish_episode 関数を呼び出してポリシーネットワークを更新し、報酬を保存します。
    • エピソードごとの総報酬を rewards_history リストに追加します。
  • 総報酬の推移のグラフ化: plt.plot を使用してエピソードごとの総報酬の推移をグラフ化します。


ソースコードの実行結果は、エピソードごとの最後のステップの長さ(Last length)と総報酬(Total Reward)が表示されます。

また、最後には総報酬の推移をグラフ化して可視化します。

これにより、エージェントの学習の進行状況やタスクの制御の改善を視覚的に確認することができます。

実行結果 解説

それぞれのエピソードでの結果の説明をします。

  • Episode 0:
    エピソード0では、最後のステップの長さ(Last length)が94で、総報酬(Total Reward)が95.0です。エージェントは初期状態での制御がまだうまくできていないようです。

  • Episode 50:
    エピソード50では、最後のステップの長さが107で、総報酬が108.0です。エージェントの学習が進み、タスクの制御が改善されてきていることがわかります。

  • Episode 100:
    エピソード100では、最後のステップの長さが37で、総報酬が38.0です。エージェントの制御が一時的に低下している可能性がありますが、学習が進行していることを示しています。

  • Episode 150:
    エピソード150では、最後のステップの長さが53で、総報酬が54.0です。エージェントの学習が進み、タスクの制御が改善されていることがわかります。

  • Episode 200:
    エピソード200では、最後のステップの長さが499で、総報酬が500.0です。エージェントはタスクの制御を非常にうまく行い、安定した報酬を得ることができるようになりました。

  • Episode 250:
    エピソード250では、最後のステップの長さが106で、総報酬が107.0です。エージェントの学習が継続され、タスクの制御を改善し続けています。

  • Episode 300:
    エピソード300では、最後のステップの長さが115で、総報酬が116.0です。エージェントの学習が進み、タスクの制御が改善されていることがわかります。

  • Episode 350:
    エピソード350では、最後のステップの長さが43で、総報酬が44.0です。エージェントの学習が進行しており、一時的な低下があるものの、制御の改善が継続しています。

  • Episode 400:
    エピソード400では、最後のステップの長さが80で、総報酬が81.0です。エージェントは学習を継続し、タスクの制御を改善し続けています。

  • Episode 450:
    エピソード450では、最後のステップの長さが146で、総報酬が147.0です。エージェントの学習が進み、タスクの制御が改善されていることがわかります。


総じて、エージェントの学習が進むにつれて、CartPoleタスクの制御が改善されていることがわかります。

初めは制御がうまくできていなかったが、学習が進み、最終的には高い報酬を得ることができるようになりました。

エピソードごとの総報酬の推移をグラフ化することで、エージェントの学習の進行状況やタスクの制御の改善を視覚的に確認することができます。