web-dev-qa-db-ja.com

ケラスの多変量LSTMでマルチステップ時系列予測を処理する方法

Kerasで多変量LSTMを使用して多段階時系列予測を実行しようとしています。具体的には、元々、タイムステップごとに2つの変数(var1とvar2)があります。オンラインチュートリアル ここ に従った後、時間(t-2)と(t-1)のデータを使用して、時間ステップtでのvar2の値を予測することにしました。サンプルデータテーブルが示すように、最初の4列を入力として使用し、Yを出力として使用しています。私が開発したコードは ここ で見ることができますが、3つの質問があります。

   var1(t-2)  var2(t-2)  var1(t-1)  var2(t-1)  var2(t)
2        1.5       -0.8        0.9       -0.5     -0.2
3        0.9       -0.5       -0.1       -0.2      0.2
4       -0.1       -0.2       -0.3        0.2      0.4
5       -0.3        0.2       -0.7        0.4      0.6
6       -0.7        0.4        0.2        0.6      0.7
  1. Q1:上記のデータを使用してLSTMモデルをトレーニングしました。このモデルは、タイムステップtでのvar2の値を予測するのに適しています。ただし、タイムステップt +1でvar2を予測したい場合はどうなりますか。モデルはタイムステップtでvar1の値を教えてくれないので、難しいと感じます。それをしたい場合、モデルをビルドするために code をどのように変更する必要がありますか?
  2. Q2:この質問がたくさん聞かれるのを見てきましたが、それでも混乱しています。私の例では、[サンプル、タイムステップ、機能] 1または2の正しいタイムステップは何である必要がありますか?
  3. Q3:LSTMの勉強を始めたばかりです。私は読んだ ここ LSTMの最大の利点の1つは、時間依存性/スライディングウィンドウサイズをそれ自体で学習することです。それでは、なぜ時系列データを常に上記の表のような形式に変換する必要があるのでしょうか。

更新:LSTMの結果(青い線はトレーニングシーケンス、オレンジの線はグラウンドトゥルース、緑は予測) Enter image description here

6
Yongyao Jiang

質問1:

あなたのテーブルから、あなたは単一のシーケンス上にスライドウィンドウがあり、2つのステップで多くの小さなシーケンスを作成していることがわかります。

  • Tを予測するには、テーブルの最初の行を入力として使用します
  • T + 1を予測するには、2行目を入力として使用します。

テーブルを使用していない場合:質問3を参照してください

質問2:

そのテーブルを入力として使用していると仮定すると、入力として2つのタイムステップをとるスライディングウィンドウケースであることが明らかであり、timeStepsは2です。

おそらく、_var1_と_var2_が同じシーケンスの機能であるかのように作業する必要があります。

  • input_shape = (2,2)-2つのタイムステップと2つの機能/変数。

質問3:

そのようなテーブルを作ったり、スライディングウィンドウケースを作ったりする必要はありません。それが1つの可能なアプローチです。

モデルは実際に物事を学習し、このウィンドウ自体のサイズを決定することができます。

モデルが長時間の依存関係を学習でき、ウィンドウを使用できない場合は、シーケンスの最初と途中で異なる動作を識別することを学習する可能性があります。この場合、途中から始まるシーケンス(最初を含まない)を使用して予測する場合、モデルは最初であるかのように機能し、異なる動作を予測する可能性があります。ウィンドウを使用すると、この非常に長い影響を排除できます。どちらが良いかは、テストに依存するかもしれません。

ウィンドウを使用しない:

データに800ステップがある場合は、トレーニングのために800ステップすべてを一度にフィードします。

ここでは、2つのモデルを分離する必要があります。1つはトレーニング用、もう1つは予測用です。トレーニングでは、パラメーター_return_sequences=True_を利用します。これは、入力ステップごとに、出力ステップを取得することを意味します。

後で予測するために、出力が1つだけ必要な場合は、_return_sequences= False_を使用します。また、予測された出力を次の手順の入力として使用する場合は、_stateful=True_レイヤーを使用します。

トレーニング:

入力データを_(1, 799, 2)_、1シーケンスの形にし、1から799までのステップを実行します。同じシーケンスの両方の変数(2つの機能)。

ターゲットデータ(Y)を_(1, 799, 2)_の形にし、同じ手順を2から800にシフトします。

_return_sequences=True_を使用してモデルを構築します。 _timeSteps=799_を使用できますが、None(可変量のステップを許可)を使用することもできます。

_model.add(LSTM(units, input_shape=(None,2), return_sequences=True))
model.add(LSTM(2, return_sequences=True)) #it could be a Dense 2 too....
....
model.fit(X, Y, ....)
_

予測:

予測するために、今度は_return_sequences=False_を使用して同様のモデルを作成します。

重みをコピーします。

_newModel.set_weights(model.get_weights())
_

たとえば、長さ800の入力を作成して(形状:_(1,800,2)_)、次のステップだけを予測できます。

_step801 = newModel.predict(X)
_

さらに予測したい場合は、_stateful=True_レイヤーを使用します。 _return_sequences=False_(最後のLSTMでのみ、他はTrueを維持)と_stateful=True_(すべて)を使用して、同じモデルを再度使用します。 _input_shape_をbatch_input_shape=(1,None,2)で変更します。

_#with stateful=True, your model will never think that the sequence ended  
#each new batch will be seen as new steps instead of new sequences
#because of this, we need to call this when we want a sequence starting from zero:
statefulModel.reset_states()

#predicting
X = steps1to800 #input
step801 = statefulModel.predict(X).reshape(1,1,2)
step802 = statefulModel.predict(step801).reshape(1,1,2)
step803 = statefulModel.predict(step802).reshape(1,1,2)
    #the reshape is because return_sequences=True eliminates the step dimension   
_

実際には、1つの_stateful=True_モデルと_return_sequences=True_モデルですべてを実行でき、次の2つのことに注意できます。

  • トレーニングするときは、エポックごとにreset_states()。 (手動ループと_epochs=1_でトレーニングします)
  • 複数のステップから予測する場合は、出力の最後のステップのみを目的の結果として取得します。
9
Daniel Möller

実際には、ネットワークが自然に適合しないため、生の時系列データを単にフィードすることはできません。 RNNの現在の状態では、有用な何かを適切に学習するために、複数の「機能」(手動または自動で派生)を入力する必要があります。

通常、必要な前の手順は次のとおりです。

  1. トレンド除去
  2. 季節外れ
  3. スケール(正規化)

優れた情報源は この投稿 LSTMネットワークを使用して時系列予測コンテストで優勝したMicrosoftの研究者からのものです。

また、この投稿: CNTK-時系列予測

0
user2360130