PythonでProphetを使いたい(3:デフォルトの周期性)

時系列=トレンド + 周期性 + その他のうちの周期性、さらにその中のデフォルトの周期性の確認とチューニングをします。

▼こちらで作ったデータ、モデルをさらにチューニングしていきます。 esu-ko.hatenablog.com

デフォルトの周期性の確認

デフォルトでは年ごとの影響、曜日の影響、時間の影響を設定できます。元のモデルは曜日影響だけ載せたので、これの中身を見ていきます。

曜日周期はweeklyの中に格納されています。

pred['weekly'][0:6].plot()
df['season'][0:6].plot()

f:id:esu-ko:20200913170209p:plain

比較的、形としてはとらえられているようです。 続けて、推定された曜日ごとの数値と、実測値に占める割合を見てみます。

week = pred[['ds','weekly','weekly_lower','weekly_upper']]
week.assign(dow=(
    week['ds'].dt.dayofweek.apply(lambda x : str(x)+"_")
    + week['ds'].dt.day_name()
    )
).groupby('dow').mean().sort_index(ascending=False).plot.barh(y='weekly')

(pred['weekly']/ts).plot()

f:id:esu-ko:20200913170409p:plainf:id:esu-ko:20200913170422p:plain

月曜日は+の影響目、土日にはマイナスの影響をうけています。

また、noiseは置いておいて、真ん中ごろ(外部影響で上がったあと)から徐々に曜日影響の占める割合が減ってきており、トレンドで増加した影響が強くなってきているのがわかります。

周期性にもトレンドの影響を乗せる

この影響を乗せるために、seasonality_mode='multiplicative'を足します。 こうすることで、観測値 = トレンド + トレンド * 周期性 + その他のモデルになります

mdl_df['cap'] = 6
mdl = Prophet(
    yearly_seasonality=False,
    weekly_seasonality=True,
    daily_seasonality=False,
    growth = 'logistic',
    changepoint_prior_scale=0.5,
    #seasonalityを増加させる
    seasonality_mode='multiplicative'
    
)
mdl.fit(
    mdl_df
)
future = mdl.make_future_dataframe(periods=0,freq='D')
future['cap'] = 6
pred  = mdl.predict(future)

可視化

ts.plot()
pred.yhat.plot()

(pred['weekly'] * pred['trend']).plot()

f:id:esu-ko:20200913170704p:plain f:id:esu-ko:20200913170728p:plain

曜日影響にトレンドの影響をのせた値を推定しました。