トラフィック予測 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となっています。
  • …(以下、同様の解釈)

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

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

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


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

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

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