IT業務効率化

自己相関関数からSARIMAモデルの次数を予測できるか?

結論

結局はgrid searchで最適解を求める方法が良さそう。ただしarma_order_select_icはその補助的な役割を果たせる可能性はある。

grid searchのコード例はこちら

https://momonoki2017.blogspot.com/2018/03/python9sarima.html

まずはarma_order_select_ic

https://www.statsmodels.org/stable/generated/statsmodels.tsa.stattools.arma_order_select_ic.html

statsmodelsのライブラリの1つにARMAモデルの字数を自動で推定するメソッドが存在する。まずはこれを利用してみることにする。

必要なライブラリのインポート

import numpy as np
import pandas as pd
import statsmodels.api as sm
import matplotlib.pyplot as plt
from sklearn.metrics import mean_absolute_error
from sklearn.metrics import mean_squared_error
from sklearn.metrics import r2_score
%matplotlib inline  # jupyterで作業しています

データの読み込みから、ARMAモデルの自動推定

dateparse = lambda dates: pd.datetime.strptime(dates, '%Y-%m-%dT%H:%M:%S.%f0')
df = pd.read_csv('../data/wyebiya_daisyokudou_data.csv', date_parser=dateparse, index_col="date")
start_at, end_at = df.index.min(), df.index.max()
df = df.reindex(pd.date_range(start_at, end_at, freq="D"))
df.fillna(df.mean(), inplace=True)

train_end = "2019-11-30"
test_start = "2019-12-01"
train = df[:train_end]
test = df[test_start:]

# 自動ARMAパラメータ推定関数
sm.tsa.arma_order_select_ic(train, ic='aic', trend='nc')

 

{'aic':              0            1            2
 0          NaN  1357.717723  1256.605028
 1  1017.120051  1005.552142  1003.632244
 2  1010.237450  1002.849477  1010.052260
 3  1006.122733  1004.259675  1005.862837
 4  1007.287752  1004.643520   994.767015,
 'aic_min_order': (4, 2)}

AIC:赤池情報量基準

赤池情報量基準とは最適な統計モデルを決めるための指標であり、0に近い方がいい。

自己相関関数と見比べてみる

fig, ax1 = plt.subplots(figsize=(8, 4))
fig, ax2 = plt.subplots(figsize=(8, 4))

sm.graphics.tsa.plot_acf(train.values, lags=20, ax=ax1);
sm.graphics.tsa.plot_pacf(train.values, lags=20, ax=ax2);

自己相関数はMAモデルの次数を推定するために利用できる。相関が最も高くなっているのはラグが1の時である。そのためMAモデルの字数qは1であるかと思えたのでだが、AICで算出した値とは異なる様である。

また偏自己相関関数はARモデルの字数を推定するために利用できる。相関が最も高くなっているのは、こちらもラグが1の時である。しかしAICで算出したモデルとは異なる。

なぜAICと自己相関関数によるARMA推定の結果が異なるのか

MAモデルを推定する時の自己相関関数とARモデルを推定する時の偏自己相関関数を使う方法は、季節性を考慮していないために発生するのだと推測します。

https://logics-of-blue.com/python-time-series-analysis/

上記の記事を辿ったところ、私の場合も同様に、作成したモデルの中に周期性が残ってしまっていました。

故にこのままarma_order_select_icを利用した次数を元に他の次数を決めようと思います。

1階差分はとった方がいいのか?

1階差分をとることによって傾向を除去することができます。

https://momonoki2017.blogspot.com/2018/03/python7.html

こちらのブログの差分系列と原系列を見比べた内容が非常にわかりやすいです。

差分をとることによって右肩上がりだった上昇傾向を除外することに成功しています。

私はこれをみた時に「上昇傾向など傾向のあるものは、必ず1階差分以上とった方が良い」と仮説を立てました。sarimaxを利用した時、次数の「d」を指定することで差分をとることができます。ここでd=0にした時に予測がうまくいかないだろうと。

ただしd階差分の指定を0にしても傾向を捉えた予測が実際には可能でした。

全てにfitしているわけではないですが、明らかに上昇傾向を捉えることはできています。

結論

結局はgrid searchでスコアを確認し、最適な値を求めることがよさそうです。

参考

ABOUT ME
hirayuki
今年で社会人3年目になります。 日々体当たりで仕事を覚えています。 テーマはIT・教育です。 少しでも技術に親しんでもらえるよう、noteで4コマ漫画も書いています。 https://note.mu/hirayuki