Pythonで時系列解析がしたい(ARIMA)

時系列で、一変量の場合、下記記事のように、パターンや抽出のトレンドの分析がメインです。

esu-ko.hatenablog.com

ただし、週次のようにトレンドがないことが多く、複数変量もなく、データ量も少ない場合は、ARIMAを使うことがあります。

基本のコード

ARIMAは

  • ARの数p
  • 階差の数d
  • MAの数q

をorderに渡すことでパラメータの推定ができます。

予測値は.forecastで取得でき、step引数でいくつ崎までか、alphaで信頼区間を指定できます。

結果は、予測の平均と指定のalphaのばらつき、それを足し引きしたタプルの三つがstep分帰ってきます。

from statsmodels.tsa.arima_model import ARIMA

#モデルの構築
#AR=1のモデル
mdl = ARIMA(input_ts, order=(1, 0, 0)).fit(dist=False)

#各パラメータの中身
print(mdl.summary())

#5期先まで予測
fcast = mdl.forecast(step=5)
print(fcast[0][0])
#下限
print(fcast[0][0]-fcast[0][1])

最適なパラメータ

ARMAまでは以下で、最適なp,qを探索できます。 ARIMA以上でやる場合は、総当たりでaicなどを比較する必要があります。(がARIMAでそこまで頑張る理由はビジネス上はあまりない気がします)

import statsmodels.api as sm

#icで何を基準にするか決められる
sm.tsa.arma_order_select_ic(input_Ts, ic='aic', trend='nc')

使い所

明らかにトレンドがない、データ量が少ない時にAR(1)とかでモデルをつくり、予測を繰り返してトレンド転換や、異常検知に使うのが一番コスパがいいかな、と思います。

from statsmodels.tsa.arima_model import ARIMA
import pandas as pd
#予測結果を格納する
res = []
idx = []

#何期分を予測に使うか
data_num = 7

# 何期先まで予測するか:ここではQの予測
forecast_step = 4

#予測可能な期間のループを回す
for i in range(0,input_df.shape[0]-data_num):

    
    #7期分を使ってモデルを構築(AR(1)で決め打ち)
    input_ts = input_df.loc[i:i + data_num-1,['y']].values
    mdl = ARIMA(input_ts, order=(1, 0, 0)).fit(dist=False)
    #予測を取得
    idx.append(i + data_num + forecast_step-1)
    fcast = mdl.forecast(step = forecast_step)[ forecast_step-1]
    res.append([fcast[0][0],fcast[1][0]])

#予測データをデータフレーム化
pred=pd.DataFrame(res,columns=['avg','std'],index=idx)
pred['min'] = pred['avg'] - pred['std']
pred['max'] = pred['avg'] + pred['std']

#可視化や、異常検知ようにもとのデータと結合
output_df = pd.concat([df['y'],pred],axis=1)