【時系列予測】 Prophet vs LSTM vs GRU vs CNN で比較をする

時系列データへのアプローチとして、Prophet と LSTM、GRU、一次元CNNの書き方のメモがてら、同じデータセットに対してどんな予測をするのか比較をしてみたいと思います。

 

おしながき

・データを用意

・Prophet で学習・予測

・LSTM で学習・予測

・GRU で学習・予測

・CNN で学習・予測

・比較する

 

データを用意

 

AirPassenger のデータセットを使用します。1949年から、1960年までの月ごとの乗客数のデータです。

https://www.kaggle.com/rakannimer/air-passengers

データを読み込み、自己相関を確認します。

 

年単位での周期性が見られます。LSTMやGRUで設定するシーケンス長は12にしようと思います。

 

Prophet

まずは Prophet で予測するとどうなるか確認します。

テスト用に、最後の30サンプルは学習で使用しないように省いておきます。

 

未知の最後30サンプルについては、ハイパーパラメータ未調整のProphetではさっぱり予想できていませんね。

 

次はニューラルネットワーク系を見てみます。

 

LSTM

データを学習する前に、正規化をしておきます。

 

最後30サンプルをテストデータとし、残りを 7 : 3 に分割して、データローダーを作成します。

繰り返し使うので、関数にまとめておきます。

 

また、GRU, CNN 共通部分として、学習ループと検証ループも関数を作成しておきます。

 

LSTM クラスを作成します。隠れ層のノード数は 16, シーケンス長は 12、LSTM層1層で作成します。

 

バッチサイズは 16、最適化手法は Adam で 1000 エポック回してみます。

 

ロスの推移を確認します。

 

学習済モデルで、学習・検証・テスト全データについて推論して、もとのデータフレームに予測値を追加します。

その際に、部分時系列にしているので、はじめの12サンプルは null になってしまうため、そこは 0 で埋めてあげます。

また、データを正規化して学習しているため、予測値は逆変換する点にも注意です。

未調整Prophetよりかはマシですが、未知の30サンプルについては予測できていないですね、、あと1時系列分遅れているように見えるのは、、。

 

次はGRUでみてみます。

GRU

GRU層の出力がLSTM層の出力と違って記憶セルcがなくなるだけで、GRU は LSTM とほぼ同じように書けます。

 

ロスを確認します。

予測値を算出します。

お、テストデータについてもこれまでに比べてだいぶまともに予測できているに感じます。ただしワンテンポ遅れている。

 

CNN

 

最後に CNN を見てみます。画像は Conv2d でしたが、今回のようなデータには Conv1d を使います。

AirPassengers のデータは周期をまたぐごとにだんだんと分散が大きくなるようになっていますが、CNNではそれを捉えられていませんね。

 

比較する

今、df にはそれぞれのモデルでの予測値が格納されているので、まとめてプロットしてみましょう。

このようになりました、今回で言えば、GRUが一番それっぽく予測していますね。

ただし、どの予測もワンテンポ遅れた感じになっているのが気になります。単純に、前日の値を次の日の予測に使っている感じにモデルができたのか、それともどこかでうっかりミスをしてるのか。教師データ作成はきちんとミスってないことを確認したのですが・・。

 

LSTMなど上手く言っていないのは、シーケンス長の短さも関係するのでしょうか。12しかさかのぼっていないので、複雑な機構にしている恩恵を受けられていないのかもしれません。

 

おわり