ウェブサイト検索

Keras のディープラーニングによる時系列予測


時系列予測は、機械学習で構成することも対処することも難しい問題です。

この投稿では、Keras 深層学習ライブラリを使用して、Python で時系列予測用のニューラル ネットワーク モデルを開発する方法を説明します。

この投稿を読むと、次のことがわかります。

  • 航空旅客の一変量時系列予測問題について
  • 時系列予測を回帰問題として表現し、そのニューラル ネットワーク モデルを開発する方法
  • タイムラグのある時系列予測をフレーム化し、そのニューラルネットワークモデルを開発する方法

私の新しい本『Deep Learning for Time Series Forecasting』 でプロジェクトを開始しましょう。ステップバイステップのチュートリアルPython ソース コードファイルが含まれています。すべての例について。

始めましょう。

  • 2016 年 7 月: 初版発行
  • 2016 年 10 月更新: グラフをより正確なバージョンに置き換えました。
  • 2017 年 3 月更新: Keras 2.0.2、TensorFlow 1.0.1、および Theano 0.9.0 用に更新されました。
  • 2019 年 4 月更新: データセットへのリンクを更新しました。
  • 2019 年 9 月更新: Keras 2.2.5 用に更新
  • 2022 年 7 月更新: TensorFlow 2.x 用に更新

問題の説明

この投稿で取り上げる問題は、国際線旅客の予測問題です。

これは、1 年と 1 か月後の国際線旅客数を 1,000 人単位で予測する問題です。データの範囲は 1949 年 1 月から 1960 年 12 月、つまり 12 年間で、144 件の観測があります。

  • データセットをダウンロードします (「airline-passengers.csv」として保存します)。

以下は、ファイルの最初の数行のサンプルです。

"Month","Passengers"
"1949-01",112
"1949-02",118
"1949-03",132
"1949-04",129

このデータセットは、Pandas ライブラリを使用して簡単にロードできます。各観測が 1 か月という同じ間隔で区切られているため、日付には興味がありません。したがって、データセットを読み込むときに、最初の列を除外できます。

ロードすると、データセット全体を簡単にプロットできます。データセットをロードしてプロットするコードを以下に示します。

import pandas as pd
import matplotlib.pyplot as plt
dataset = pd.read_csv('airline-passengers.csv', usecols=[1], engine='python')
plt.plot(dataset)
plt.show()

プロットでは上昇傾向が見られます。

データセットには、おそらく北半球の夏休み期間に対応する周期性も見られます。

物事を単純にして、データをそのまま使用してみましょう。

通常は、データを再スケールして固定化するためのさまざまなデータ準備手法を調査することをお勧めします。

多層パーセプトロン回帰

時系列予測問題を回帰問題として表現したいとします。

つまり、今月の乗客数(千人単位)から、来月の乗客数は何人になるでしょうか?

単一列のデータを 2 列のデータセットに変換する簡単な関数を作成できます。最初の列には今月 (t) の乗客数が含まれ、2 番目の列には予測される来月 (t+1) の乗客数が含まれます。

始める前に、まず使用する必要があるすべての関数とクラスをインポートしましょう。これは、Keras 深層学習ライブラリがインストールされた SciPy 環境が動作していることを前提としています。

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense

前のセクションのコードを使用して、データセットを Pandas データフレームとして読み込むこともできます。次に、データフレームから NumPy 配列を抽出し、整数値をニューラル ネットワークでのモデリングにより適した浮動小数点値に変換できます。

...
# load the dataset
dataframe = pd.read_csv('airline-passengers.csv', usecols=[1], engine='python')
dataset = dataframe.values
dataset = dataset.astype('float32')

データをモデル化し、トレーニング データセットでのモデルのスキルを推定した後、新しい未確認データでのモデルのスキルを把握する必要があります。通常の分類または回帰問題の場合、相互検証を使用してこれを行います。

時系列データでは、値の順序が重要です。使用できる簡単な方法は、順序付けされたデータセットをトレーニング データセットとテスト データセットに分割することです。以下のコードは、分割点のインデックスを計算し、観測値の 67% がモデルのトレーニングに使用され、残りの 33% がモデルのテスト用に残されたデータをトレーニング データセットに分割します。

...
# split into train and test sets
train_size = int(len(dataset) * 0.67)
test_size = len(dataset) - train_size
train, test = dataset[0:train_size,:], dataset[train_size:len(dataset),:]
print(len(train), len(test))

これで、上で説明したように、新しいデータセットを作成する関数を定義できます。この関数は 2 つの引数を取ります。データセット (データセットに変換する NumPy 配列) と、look_back (予測するための入力変数として使用する以前のタイム ステップの数)この場合、次の期間はデフォルトで 1 に設定されます。

このデフォルトでは、X が特定の時点 (t) の乗客数、Y が次回の時点 (t + 1) の乗客数であるデータセットが作成されます。 。

これは構成可能です。次のセクションでは、異なる形状のデータセットの構築について説明します。

...
# convert an array of values into a dataset matrix
def create_dataset(dataset, look_back=1):
	dataX, dataY = [], []
	for i in range(len(dataset)-look_back-1):
		a = dataset[i:(i+look_back), 0]
		dataX.append(a)
		dataY.append(dataset[i + look_back, 0])
	return np.array(dataX), np.array(dataY)

データセットの最初の数行に対するこの関数の効果を見てみましょう。

X		Y
112		118
118		132
132		129
129		121
121		135

これらの最初の 5 行を前のセクションでリストした元のデータセット サンプルと比較すると、数値に X=t および Y=t+1 のパターンが見られます。

この関数を使用して、モデリング用のトレーニング データセットとテスト データセットを準備してみましょう。

...
# reshape into X=t and Y=t+1
look_back = 1
trainX, trainY = create_dataset(train, look_back)
testX, testY = create_dataset(test, look_back)

これで、多層パーセプトロン モデルをトレーニング データに適合させることができます。

1 つの入力、8 つのニューロンを含む 1 つの隠れ層、および出力層を備えた単純なネットワークを使用します。モデルは平均二乗誤差を使用して近似されます。平方根を取ると、データセットの単位で誤差スコアが得られます。

いくつかの大まかなパラメータを試して、以下の構成に落ち着きましたが、リストされているネットワークは決して最適化されていません。

...
# create and fit Multilayer Perceptron model
model = Sequential()
model.add(Dense(8, input_shape=(look_back,), activation='relu'))
model.add(Dense(1))
model.compile(loss='mean_squared_error', optimizer='adam')
model.fit(trainX, trainY, epochs=200, batch_size=2, verbose=2)

モデルが適合すると、トレーニングおよびテスト データセット上でモデルのパフォーマンスを推定できます。これにより、新しいモデルを比較することができます。

...
# Estimate model performance
trainScore = model.evaluate(trainX, trainY, verbose=0)
print('Train Score: %.2f MSE (%.2f RMSE)' % (trainScore, math.sqrt(trainScore)))
testScore = model.evaluate(testX, testY, verbose=0)
print('Test Score: %.2f MSE (%.2f RMSE)' % (testScore, math.sqrt(testScore)))

最後に、トレーニング データセットとテスト データセットの両方のモデルを使用して予測を生成し、モデルのスキルを視覚的に示すことができます。

データセットの準備方法により、元のデータセットと X 軸を揃えるために予測をシフトする必要があります。準備が完了すると、データがプロットされ、元のデータセットが青、トレーニング データセットの予測が緑、未確認のテスト データセットの予測が赤で表示されます。

...
# generate predictions for training
trainPredict = model.predict(trainX)
testPredict = model.predict(testX)
# shift train predictions for plotting
trainPredictPlot = np.empty_like(dataset)
trainPredictPlot[:, :] = np.nan
trainPredictPlot[look_back:len(trainPredict)+look_back, :] = trainPredict
# shift test predictions for plotting
testPredictPlot = np.empty_like(dataset)
testPredictPlot[:, :] = np.nan
testPredictPlot[len(trainPredict)+(look_back*2)+1:len(dataset)-1, :] = testPredict
# plot baseline and predictions
plt.plot(dataset)
plt.plot(trainPredictPlot)
plt.plot(testPredictPlot)
plt.show()

これをすべてまとめた完全な例を以下に示します。

# Multilayer Perceptron to Predict International Airline Passengers (t+1, given t, t-1, t-2)
import numpy as np
import matplotlib.pyplot as plt
from pandas import read_csv
import math
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense

# convert an array of values into a dataset matrix
def create_dataset(dataset, look_back=1):
	dataX, dataY = [], []
	for i in range(len(dataset)-look_back-1):
		a = dataset[i:(i+look_back), 0]
		dataX.append(a)
		dataY.append(dataset[i + look_back, 0])
	return np.array(dataX), np.array(dataY)

# load the dataset
dataframe = read_csv('airline-passengers.csv', usecols=[1], engine='python')
dataset = dataframe.values
dataset = dataset.astype('float32')
# split into train and test sets
train_size = int(len(dataset) * 0.67)
test_size = len(dataset) - train_size
train, test = dataset[0:train_size,:], dataset[train_size:len(dataset),:]
# reshape dataset
look_back = 3
trainX, trainY = create_dataset(train, look_back)
testX, testY = create_dataset(test, look_back)
# create and fit Multilayer Perceptron model
model = Sequential()
model.add(Dense(12, input_shape=(look_back,), activation='relu'))
model.add(Dense(8, activation='relu'))
model.add(Dense(1))
model.compile(loss='mean_squared_error', optimizer='adam')
model.fit(trainX, trainY, epochs=400, batch_size=2, verbose=2)
# Estimate model performance
trainScore = model.evaluate(trainX, trainY, verbose=0)
print('Train Score: %.2f MSE (%.2f RMSE)' % (trainScore, math.sqrt(trainScore)))
testScore = model.evaluate(testX, testY, verbose=0)
print('Test Score: %.2f MSE (%.2f RMSE)' % (testScore, math.sqrt(testScore)))
# generate predictions for training
trainPredict = model.predict(trainX)
testPredict = model.predict(testX)
# shift train predictions for plotting
trainPredictPlot = np.empty_like(dataset)
trainPredictPlot[:, :] = np.nan
trainPredictPlot[look_back:len(trainPredict)+look_back, :] = trainPredict
# shift test predictions for plotting
testPredictPlot = np.empty_like(dataset)
testPredictPlot[:, :] = np.nan
testPredictPlot[len(trainPredict)+(look_back*2)+1:len(dataset)-1, :] = testPredict
# plot baseline and predictions
plt.plot(dataset)
plt.plot(trainPredictPlot)
plt.plot(testPredictPlot)
plt.show()

サンプルを実行すると、モデルのパフォーマンスがレポートされます。

: アルゴリズムや評価手順の確率的性質、または数値精度の違いにより、結果が異なる場合があります。例を数回実行して、平均結果を比較することを検討してください。

パフォーマンス推定の平方根を取ると、モデルの平均誤差はトレーニング データセットでは 22 乗客 (千単位)、テスト データセットでは 46 乗客 (千単位) であることがわかります。

...
Epoch 395/400
46/46 - 0s - loss: 513.2617 - 13ms/epoch - 275us/step
Epoch 396/400
46/46 - 0s - loss: 494.1868 - 12ms/epoch - 268us/step
Epoch 397/400
46/46 - 0s - loss: 483.3908 - 12ms/epoch - 268us/step
Epoch 398/400
46/46 - 0s - loss: 501.8111 - 13ms/epoch - 281us/step
Epoch 399/400
46/46 - 0s - loss: 523.2578 - 13ms/epoch - 280us/step
Epoch 400/400
46/46 - 0s - loss: 513.7587 - 12ms/epoch - 263us/step
Train Score: 487.39 MSE (22.08 RMSE)
Test Score: 2070.68 MSE (45.50 RMSE)

プロットから、モデルがトレーニング データセットとテスト データセットの両方にうまく適合していないことがわかります。基本的には、出力と同じ入力値を予測しました。

ウィンドウ法を使用した多層パーセプトロン

また、最近の複数のタイム ステップを使用して次のタイム ステップの予測を行えるように、問題を表現することもできます。

これはウィンドウ法と呼ばれ、ウィンドウのサイズは問題ごとに調整できるパラメーターです。

たとえば、シーケンス内の次の時刻 (t + 1) の値を予測するために現在の時刻 (t) が与えられた場合、現在の時刻 (t) だけでなく、前の 2 つの時刻 (t-1 および t-) も使用できます。 2)。

回帰問題として表現すると、入力変数は t-2、t-1、および t であり、出力変数は t+1 です。

前のセクションで使用した create_dataset() 関数を使用すると、look_back 引数を 1 から 3 に増やすことで、時系列問題のこの定式化を作成できます。

この定式化を使用したデータセットのサンプルは次のようになります。

X1	X2	X3	Y
112	118	132	129
118	132	129	121
132	129	121	135
129	121	135	148
121	135	148	148

前のセクションの例を、より大きなウィンドウ サイズで再実行できます。追加情報を処理できるようにネットワーク容量を増加します。最初の隠れ層は 14 ニューロンに増加し、2 番目の隠れ層には 8 つのニューロンが追加されます。エポック数も 400 に増加します。

完全を期すために、ウィンドウ サイズの変更のみを含むコード全体のリストを以下に示します。

# Multilayer Perceptron to Predict International Airline Passengers (t+1, given t, t-1, t-2)
import numpy as np
import matplotlib.pyplot as plt
from pandas import read_csv
import math
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense

# convert an array of values into a dataset matrix
def create_dataset(dataset, look_back=1):
	dataX, dataY = [], []
	for i in range(len(dataset)-look_back-1):
		a = dataset[i:(i+look_back), 0]
		dataX.append(a)
		dataY.append(dataset[i + look_back, 0])
	return np.array(dataX), np.array(dataY)

# load the dataset
dataframe = read_csv('airline-passengers.csv', usecols=[1], engine='python')
dataset = dataframe.values
dataset = dataset.astype('float32')
# split into train and test sets
train_size = int(len(dataset) * 0.67)
test_size = len(dataset) - train_size
train, test = dataset[0:train_size,:], dataset[train_size:len(dataset),:]
# reshape dataset
look_back = 3
trainX, trainY = create_dataset(train, look_back)
testX, testY = create_dataset(test, look_back)
# create and fit Multilayer Perceptron model
model = Sequential()
model.add(Dense(12, input_dim=look_back, activation='relu'))
model.add(Dense(8, activation='relu'))
model.add(Dense(1))
model.compile(loss='mean_squared_error', optimizer='adam')
model.fit(trainX, trainY, epochs=400, batch_size=2, verbose=2)
# Estimate model performance
trainScore = model.evaluate(trainX, trainY, verbose=0)
print('Train Score: %.2f MSE (%.2f RMSE)' % (trainScore, math.sqrt(trainScore)))
testScore = model.evaluate(testX, testY, verbose=0)
print('Test Score: %.2f MSE (%.2f RMSE)' % (testScore, math.sqrt(testScore)))
# generate predictions for training
trainPredict = model.predict(trainX)
testPredict = model.predict(testX)
# shift train predictions for plotting
trainPredictPlot = np.empty_like(dataset)
trainPredictPlot[:, :] = np.nan
trainPredictPlot[look_back:len(trainPredict)+look_back, :] = trainPredict
# shift test predictions for plotting
testPredictPlot = np.empty_like(dataset)
testPredictPlot[:, :] = np.nan
testPredictPlot[len(trainPredict)+(look_back*2)+1:len(dataset)-1, :] = testPredict
# plot baseline and predictions
plt.plot(dataset)
plt.plot(trainPredictPlot)
plt.plot(testPredictPlot)
plt.show()

: アルゴリズムや評価手順の確率的性質、または数値精度の違いにより、結果が異なる場合があります。例を数回実行して、平均結果を比較することを検討してください。

この例を実行すると、次の出力が得られます。

Epoch 395/400
46/46 - 0s - loss: 419.0309 - 14ms/epoch - 294us/step
Epoch 396/400
46/46 - 0s - loss: 429.3398 - 14ms/epoch - 300us/step
Epoch 397/400
46/46 - 0s - loss: 412.2588 - 14ms/epoch - 298us/step
Epoch 398/400
46/46 - 0s - loss: 424.6126 - 13ms/epoch - 292us/step
Epoch 399/400
46/46 - 0s - loss: 429.6443 - 14ms/epoch - 296us/step
Epoch 400/400
46/46 - 0s - loss: 419.9067 - 14ms/epoch - 301us/step
Train Score: 393.07 MSE (19.83 RMSE)
Test Score: 1833.35 MSE (42.82 RMSE)

前のセクションと比べて誤差が大幅に減少していないことがわかります。

グラフを見ると、予測の構造がさらに詳しくわかります。

繰り返しますが、ウィンドウ サイズとネットワーク アーキテクチャは調整されていません。これは、予測問題を組み立てる方法を示す単なるデモンストレーションです。

パフォーマンス スコアの平方根を取ると、トレーニング データセットの平均誤差は 20 乗客 (月あたり数千人) で、未確認のテスト セットの平均誤差は 43 乗客 (月あたり数千人) であったことがわかります。

まとめ

この投稿では、Keras 深層学習ライブラリを使用して時系列予測問題用のニューラル ネットワーク モデルを開発する方法を発見しました。

このチュートリアルを完了すると、次のことがわかります。

  • 国際線旅客予測時系列データセットについて
  • 時系列予測問題を回帰問題としてフレーム化し、ニューラル ネットワーク モデルを開発する方法
  • ウィンドウ アプローチを使用して時系列予測問題を組み立て、ニューラル ネットワーク モデルを開発する方法

ニューラル ネットワークまたはこの投稿を使用した時系列予測についてご質問がありますか?
以下のコメント欄でご質問ください。最善を尽くしてお答えします。

関連記事