休暇中にKerasを実際に体験しようとしています。まず、株式データの時系列予測の教科書の例から始めようと思いました。したがって、私がやろうとしていることは、過去48時間分の平均価格変動(前回からのパーセント)を与えられ、次の1時間の平均価格変動が何であるかを予測します。
ただし、テストセット(またはトレーニングセット)に対して検証する場合、予測された系列の振幅は大きくずれており、常に正または常に負になるようにシフトされることがあります。つまり、0%の変化からシフトされます。この種のことには正しいと思います。
問題を示すために、次の最小限の例を考え出しました。
df = pandas.DataFrame.from_csv('test-data-01.csv', header=0)
df['pct'] = df.value.pct_change(periods=1)
seq_len=48
vals = df.pct.values[1:] # First pct change is NaN, skip it
sequences = []
for i in range(0, len(vals) - seq_len):
sx = vals[i:i+seq_len].reshape(seq_len, 1)
sy = vals[i+seq_len]
sequences.append((sx, sy))
row = -24
trainSeqs = sequences[:row]
testSeqs = sequences[row:]
trainX = np.array([i[0] for i in trainSeqs])
trainy = np.array([i[1] for i in trainSeqs])
model = Sequential()
model.add(LSTM(25, batch_input_shape=(1, seq_len, 1)))
model.add(Dense(1))
model.compile(loss='mse', optimizer='adam')
model.fit(trainX, trainy, epochs=1, batch_size=1, verbose=1, shuffle=True)
pred = []
for s in trainSeqs:
pred.append(model.predict(s[0].reshape(1, seq_len, 1)))
pred = np.array(pred).flatten()
plot(pred)
plot([i[1] for i in trainSeqs])
axis([2500, 2550,-0.03, 0.03])
ご覧のとおり、最後の48時間を選択し、次のステップをタプルに入れて1時間進め、手順を繰り返して、トレーニングとテストのシーケンスを作成します。モデルは非常に単純な1つのLSTMと1つの高密度レイヤーです。
個々の予測点のプロットがトレーニングシーケンスのプロット(結局、これはトレーニングされたものと同じセットです)とかなりうまく重なり、テストシーケンスの一種の一致を期待していました。ただし、トレーニングデータで次の結果が得られます。
何が起こっているのか考えはありますか?私は何かを誤解しましたか?
Update:シフトして押しつぶしたことの意味をわかりやすくするために、実際のデータに一致するようにシフトバックし、振幅に一致するように乗算して、予測値をプロットしました。
plot(pred*12-0.03)
plot([i[1] for i in trainSeqs])
axis([2500, 2550,-0.03, 0.03])
予測が実際のデータにうまく適合していることがわかるように、それは押しつぶされて何らかの形でオフセットされているだけであり、その理由はわかりません。
私はあなたが過剰適合していると思います、データの次元は1であり、25単位のLSTMは、このような低次元のデータセットではかなり複雑に見えるためです。これが私が試すことのリストです:
UPDATE。コメントセクションで説明した内容を要約します。
明確にするために、最初のプロットは検証セットの予測系列を示していませんが、トレーニングセットの予測系列を示しています。したがって、私の最初の過剰適合の解釈は不正確である可能性があります。適切な質問は次のようになると思います。このような低次元のデータセットから将来の価格変動を予測することは実際に可能ですか?機械学習アルゴリズムは魔法ではありません。パターンが存在する場合にのみ、データ内のパターンを検出します。
過去の価格変更だけでは、将来の価格変更についてあまり情報がない場合は、次のようにします。
タイムステップtとt + 1の値が一般により相関している場合、モデルはこの相関についてより自信を持っており、予測の振幅はより大きくなると思います。
これらすべてを試して、過剰適合を試みてください(実際のデータセットではmseはほぼゼロである必要があります)。次に、正則化を適用します。
更新
なぜあなたが通りかかったのか説明させてください
plot(pred*12-0.03)
ぴったり。
さて、LSTMレイヤーをブラックボックスと見なして忘れましょう。 25個の値が返されます-それだけです。この値はDenseレイヤーに進み、25値のベクトル関数に適用されます。
y = w * x + b
ここでwおよびb --NNによって定義され、最初はゼロに近いベクトル。 x --LSTMレイヤー後の値およびy --target(単一値)。
エポックが1つしかない場合、wとbはデータにまったく適合しません(実際にはほぼゼロです)。しかし、あなたが適用した場合はどうなりますか
plot(pred*12-0.03)
あなたの予測値に?あなたは(どういうわけか)ターゲット変数に適用しますwおよびb。これで、wとbは単一の値であり、ベクトルではなく、単一の値に適用されます。しかし、それらは(ほぼ)高密度レイヤーと同じ働きをします。
したがって、エポックの数を増やして、より適切に適合させます。
UPDATE2ちなみに、データにいくつかの外れ値があります。 MAEを損失/精度の指標として使用することもできます。
今週も同じ問題があり、解決策を見つけました。私のために働いた唯一のことは、ここで説明されているウィンドウ正規化方法を使用することでした:
https://www.altumintelligence.com/articles/a/Time-Series-Prediction-Using-LSTM-Deep-Neural-Networks
(sp500予測に関する部分を確認してください)
良い一日を過ごしてください :)