時系列で、一変量の場合、下記記事のように、パターンや抽出のトレンドの分析がメインです。
ただし、週次のようにトレンドがないことが多く、複数変量もなく、データ量も少ない場合は、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)