時系列-LSTMモデル
現在、時系列の統計モデリングに精通していますが、現在、機械学習が大流行しているため、一部の機械学習モデルにも精通していることが不可欠です。時系列領域で最も人気のあるモデルである長短期記憶モデルから始めましょう。
LSTMは、リカレントニューラルネットワークのクラスです。したがって、LSTMにジャンプする前に、ニューラルネットワークとリカレントニューラルネットワークを理解することが不可欠です。
ニューラルネットワーク
人工ニューラルネットワークは、生物学的ニューラルネットワークに触発された、接続されたニューロンの層状構造です。これは1つのアルゴリズムではなく、さまざまなアルゴリズムの組み合わせであり、データに対して複雑な操作を行うことができます。
リカレントニューラルネットワーク
これは、時間データを処理するように調整されたニューラルネットワークのクラスです。RNNのニューロンにはセルの状態/メモリがあり、入力はこの内部状態に従って処理されます。これは、ニューラルネットワーク内のループの助けを借りて実現されます。RNNには、情報を保持できるようにする「tanh」レイヤーのリカレントモジュールがあります。ただし、長い間ではないため、LSTMモデルが必要です。
LSTM
これは、データの長期的な依存関係を学習できる特殊な種類のリカレントニューラルネットワークです。これは、モデルの繰り返しモジュールが相互作用する4つのレイヤーの組み合わせを持っているために実現されます。
上の図は、黄色のボックスに4つのニューラルネットワークレイヤー、緑色の円に点ごとの演算子、黄色の円に入力、青色の円にセルの状態を示しています。LSTMモジュールには、セル状態と3つのゲートがあり、各ユニットから情報を選択的に学習、非学習、または保持する機能を提供します。LSTMのセル状態は、わずかな線形相互作用のみを許可することにより、情報が変更されることなくユニットを通過するのに役立ちます。各ユニットには、セルの状態に情報を追加または削除できる入力、出力、および忘却ゲートがあります。忘却ゲートは、シグモイド関数を使用する前のセル状態からのどの情報を忘れるべきかを決定します。入力ゲートは、それぞれ「シグモイド」と「タン」の点ごとの乗算演算を使用して、現在のセル状態への情報フローを制御します。最後に、出力ゲートは、どの情報を次の非表示状態に渡すかを決定します
LSTMモデルの内部動作を理解したので、それを実装しましょう。LSTMの実装を理解するために、簡単な例、つまり直線から始めます。LSTMが直線の関係を学習して予測できるかどうかを見てみましょう。
まず、直線を描いたデータセットを作成しましょう。
[402]で:
x = numpy.arange (1,500,1)
y = 0.4 * x + 30
plt.plot(x,y)
アウト[402]:
[<matplotlib.lines.Line2D at 0x1eab9d3ee10>]
[403]で:
trainx, testx = x[0:int(0.8*(len(x)))], x[int(0.8*(len(x))):]
trainy, testy = y[0:int(0.8*(len(y)))], y[int(0.8*(len(y))):]
train = numpy.array(list(zip(trainx,trainy)))
test = numpy.array(list(zip(trainx,trainy)))
これでデータが作成され、トレーニングとテストに分割されました。時系列データを、時間「t」での値を予測するために見られる本質的に見られるラグの数であるルックバック期間の値に従って、教師あり学習データの形式に変換してみましょう。
したがって、このような時系列-
time variable_x
t1 x1
t2 x2
: :
: :
T xT
ルックバック期間が1の場合、-に変換されます。
x1 x2
x2 x3
: :
: :
xT-1 xT
[404]:
def create_dataset(n_X, look_back):
dataX, dataY = [], []
for i in range(len(n_X)-look_back):
a = n_X[i:(i+look_back), ]
dataX.append(a)
dataY.append(n_X[i + look_back, ])
return numpy.array(dataX), numpy.array(dataY)
[405]で:
look_back = 1
trainx,trainy = create_dataset(train, look_back)
testx,testy = create_dataset(test, look_back)
trainx = numpy.reshape(trainx, (trainx.shape[0], 1, 2))
testx = numpy.reshape(testx, (testx.shape[0], 1, 2))
次に、モデルをトレーニングします。
トレーニングデータの小さなバッチがネットワークに表示されます。トレーニングデータ全体がバッチでモデルに表示され、エラーが計算される1回の実行は、エポックと呼ばれます。エポックは、エラーが減少するまで実行されます。
[]で:
from keras.models import Sequential
from keras.layers import LSTM, Dense
model = Sequential()
model.add(LSTM(256, return_sequences = True, input_shape = (trainx.shape[1], 2)))
model.add(LSTM(128,input_shape = (trainx.shape[1], 2)))
model.add(Dense(2))
model.compile(loss = 'mean_squared_error', optimizer = 'adam')
model.fit(trainx, trainy, epochs = 2000, batch_size = 10, verbose = 2, shuffle = False)
model.save_weights('LSTMBasic1.h5')
[407]で:
model.load_weights('LSTMBasic1.h5')
predict = model.predict(testx)
それでは、予測がどのようになるか見てみましょう。
[408]で:
plt.plot(testx.reshape(398,2)[:,0:1], testx.reshape(398,2)[:,1:2])
plt.plot(predict[:,0:1], predict[:,1:2])
アウト[408]:
[<matplotlib.lines.Line2D at 0x1eac792f048>]
ここで、同様の方法で正弦波または余弦波をモデル化する必要があります。以下のコードを実行し、モデルパラメータを試して、結果がどのように変化するかを確認できます。
[409]で:
x = numpy.arange (1,500,1)
y = numpy.sin(x)
plt.plot(x,y)
アウト[409]:
[<matplotlib.lines.Line2D at 0x1eac7a0b3c8>]
[410]で:
trainx, testx = x[0:int(0.8*(len(x)))], x[int(0.8*(len(x))):]
trainy, testy = y[0:int(0.8*(len(y)))], y[int(0.8*(len(y))):]
train = numpy.array(list(zip(trainx,trainy)))
test = numpy.array(list(zip(trainx,trainy)))
[411]で:
look_back = 1
trainx,trainy = create_dataset(train, look_back)
testx,testy = create_dataset(test, look_back)
trainx = numpy.reshape(trainx, (trainx.shape[0], 1, 2))
testx = numpy.reshape(testx, (testx.shape[0], 1, 2))
[]で:
model = Sequential()
model.add(LSTM(512, return_sequences = True, input_shape = (trainx.shape[1], 2)))
model.add(LSTM(256,input_shape = (trainx.shape[1], 2)))
model.add(Dense(2))
model.compile(loss = 'mean_squared_error', optimizer = 'adam')
model.fit(trainx, trainy, epochs = 2000, batch_size = 10, verbose = 2, shuffle = False)
model.save_weights('LSTMBasic2.h5')
[413]で:
model.load_weights('LSTMBasic2.h5')
predict = model.predict(testx)
[415]で:
plt.plot(trainx.reshape(398,2)[:,0:1], trainx.reshape(398,2)[:,1:2])
plt.plot(predict[:,0:1], predict[:,1:2])
アウト[415]:
[<matplotlib.lines.Line2D at 0x1eac7a1f550>]
これで、任意のデータセットに移動する準備が整いました。