04.15.2
Prophetのアルゴリズム
growth="linear" と "flat"、yearly_seasonality と weekly_seasonality と daily_seasonality の切り替え、holidays の DataFrame 指定を 1 つずつ変えて 90 日先の予測図を 7 枚並べます。設定を 1 つ変えるごとに m.plot の青い線と帯がどう変わるかを見ることで、「トレンドは区分線形」「季節性はフーリエ級数」「休日は日付ごとのダミー変数」という内部構造が図から読めるようになります。Prophetを実行してみる で fit → make_future_dataframe → predict → plot の 4 手順を先に動かしておくと、このページは「同じ 4 手順で引数だけを変える」実験として読めます。
Prophet がどのようにしてモデルを作成しているのかを、引数を 1 つずつ変えながら詳しく見ていきます。
Taylor, Sean J., and Benjamin Letham. “Forecasting at scale.” The American Statistician 72.1 (2018): 37-45.
直感 #
Prophet のモデルは \(y(t) = g(t) + s(t) + h(t) + \epsilon_t\) という足し算です。トレンド \(g(t)\) は何本かの直線をつないだ折れ線(区分線形)で、折れる位置が「変化点」です。季節性 \(s(t)\) は周期 \(P\) の sin と cos を何次か足したフーリエ級数で、週次なら \(P = 7\)、年次なら \(P = 365.25\) です。休日効果 \(h(t)\) は指定した日付だけ 1 になるダミー変数に係数を掛けたもので、イベント日の跳ねを個別に表します。この 3 つは互いに独立に引数で付け外しできるので、以下では「トレンドだけ変える」「季節性だけ変える」「休日だけ加える」の順で、予測図がどう変わるかを確かめます。
| |
実験に使用するデータ #
1 年間(2020/1/1〜2020/12/31)のデータを用意します。トレンドは log(10 + i + 10 cos(i)) でゆるやかに伸び、cos(weekday · π/28) · 3 で曜日ごとに値が変わり、土日(weekday が 5 か 6)はさらに +0.5 されます。加えて horidays_index にランダムに選んだ 10 日だけ +2 のイベントが起き、その日は非常に大きな値になります。
| |

何が起きているか(ステップで見る) #
コードを読む前に、この手法が図の上で何をしているかを追ってみましょう。「再生」を押すか、スライダーを動かすと 1 手順ずつ進みます。
見るポイント:水準 → 傾き → 季節 と要素を足すほど、未来への伸ばし方が豊かになる。
トレンドの指定 #
growth 引数でトレンド \(g(t)\) の形を選びます。"linear" は変化点で傾きが変わる折れ線、"flat" は水平線、ほかに上限を指定する "logistic" があります。まず週次季節性だけを有効にして、"linear" と "flat" の予測を比べます。
growth=“linear” #
| |
Initial log joint probability = -2.99674
Iter log prob ||dx|| ||grad|| alpha alpha0 # evals Notes
99 1040.17 0.000845008 95.4398 0.3546 0.3546 128
Iter log prob ||dx|| ||grad|| alpha alpha0 # evals Notes
166 1045.08 8.28451e-05 66.0092 1.087e-06 0.001 252 LS failed, Hessian reset
184 1045.09 1.58284e-05 61.1258 3.535e-07 0.001 307 LS failed, Hessian reset
199 1045.09 1.20349e-07 45.161 0.0243 1 330
Iter log prob ||dx|| ||grad|| alpha alpha0 # evals Notes
264 1045.71 0.000316932 140.641 3.665e-06 0.001 456 LS failed, Hessian reset
292 1045.82 5.70302e-05 48.9256 1.155e-06 0.001 533 LS failed, Hessian reset
299 1045.82 7.71897e-06 40.8043 0.3543 1 544
Iter log prob ||dx|| ||grad|| alpha alpha0 # evals Notes
305 1045.82 5.91182e-07 46.3158 2.336e-08 0.001 594 LS failed, Hessian reset
317 1045.82 2.63213e-06 51.4268 5.486e-08 0.001 649 LS failed, Hessian reset
343 1045.82 1.59952e-05 25.621 2.535e-07 0.001 728 LS failed, Hessian reset
353 1045.82 6.70942e-07 31.5639 1.825e-08 0.001 779 LS failed, Hessian reset
355 1045.82 3.11455e-08 40.1124 0.08424 1 783
Optimization terminated normally:
Convergence detected: relative gradient magnitude is below tolerance

青い予測線は対数トレンドの伸びを数本の直線で追い、週次の波を乗せたまま coral の予測期間へ最後の傾きで伸びていきます。10 本のイベントのスパイクは黒い点として線から大きく上に外れ、帯の外に出ています。
growth=“flat” #
| |
Initial log joint probability = -3.30635
Iter log prob ||dx|| ||grad|| alpha alpha0 # evals Notes
8 725.322 0.00030891 0.0789655 0.955 0.955 14
Optimization terminated normally:
Convergence detected: relative gradient magnitude is below tolerance

水平な青い線に 7 日周期の波が乗り、右上がりの黒い点の列から前半は上に、後半は下に外れています。log prob も "linear" の 1045 から 725 へ下がり、当てはまりが悪化したことが数値でも分かります。"flat" は水準が本当に一定とみなせる系列(稼働率や比率など)にだけ使う設定です。
季節変化の指定 #
季節性 \(s(t)\) は yearly_seasonality・weekly_seasonality・daily_seasonality の 3 つで付け外しします。トレンドは "linear" に戻し、季節性を「全部なし」「週次だけ」「全部あり」の 3 通りで比べます。
seasonalityが全てFalse #
| |
Initial log joint probability = -2.99674
Iter log prob ||dx|| ||grad|| alpha alpha0 # evals Notes
99 1014.78 0.000250992 97.5427 1.468 0.01468 134
Iter log prob ||dx|| ||grad|| alpha alpha0 # evals Notes
199 1020 0.00045602 60.8104 1 1 268
Iter log prob ||dx|| ||grad|| alpha alpha0 # evals Notes
208 1020.1 0.000167489 76.8606 1.772e-06 0.001 314 LS failed, Hessian reset
299 1020.33 0.000353008 41.1849 2.43 0.243 446
Iter log prob ||dx|| ||grad|| alpha alpha0 # evals Notes
352 1020.86 8.23232e-05 43.9782 1.438e-06 0.001 586 LS failed, Hessian reset
399 1020.99 0.000244078 56.987 1 1 657
Iter log prob ||dx|| ||grad|| alpha alpha0 # evals Notes
488 1021.04 3.90795e-05 57.3821 6.974e-07 0.001 856 LS failed, Hessian reset
499 1021.04 1.23592e-05 41.4144 1 1 876
Iter log prob ||dx|| ||grad|| alpha alpha0 # evals Notes
510 1021.04 4.89524e-06 59.8544 1.187e-07 0.001 929 LS failed, Hessian reset
571 1021.06 1.29427e-06 39.655 2.478e-08 0.001 1071 LS failed, Hessian reset
598 1021.07 1.94887e-05 41.0613 3.113e-07 0.001 1157 LS failed, Hessian reset
599 1021.07 4.80514e-06 27.1307 0.643 0.643 1158
Iter log prob ||dx|| ||grad|| alpha alpha0 # evals Notes
645 1021.07 8.81062e-06 74.3981 1.365e-07 0.001 1264 LS failed, Hessian reset
660 1021.07 2.61181e-07 41.0723 5.687e-09 0.001 1321 LS failed, Hessian reset
661 1021.07 9.2387e-08 26.7092 0.8838 0.8838 1322
Optimization terminated normally:
Convergence detected: relative gradient magnitude is below tolerance

weekly_seasonality=True #
| |
Initial log joint probability = -2.99674
Iter log prob ||dx|| ||grad|| alpha alpha0 # evals Notes
99 1040.17 0.000845008 95.4398 0.3546 0.3546 128
Iter log prob ||dx|| ||grad|| alpha alpha0 # evals Notes
166 1045.08 8.28451e-05 66.0092 1.087e-06 0.001 252 LS failed, Hessian reset
184 1045.09 1.58284e-05 61.1258 3.535e-07 0.001 307 LS failed, Hessian reset
199 1045.09 1.20349e-07 45.161 0.0243 1 330
Iter log prob ||dx|| ||grad|| alpha alpha0 # evals Notes
264 1045.71 0.000316932 140.641 3.665e-06 0.001 456 LS failed, Hessian reset
292 1045.82 5.70302e-05 48.9256 1.155e-06 0.001 533 LS failed, Hessian reset
299 1045.82 7.71897e-06 40.8043 0.3543 1 544
Iter log prob ||dx|| ||grad|| alpha alpha0 # evals Notes
305 1045.82 5.91182e-07 46.3158 2.336e-08 0.001 594 LS failed, Hessian reset
317 1045.82 2.63213e-06 51.4268 5.486e-08 0.001 649 LS failed, Hessian reset
343 1045.82 1.59952e-05 25.621 2.535e-07 0.001 728 LS failed, Hessian reset
353 1045.82 6.70942e-07 31.5639 1.825e-08 0.001 779 LS failed, Hessian reset
355 1045.82 3.11455e-08 40.1124 0.08424 1 783
Optimization terminated normally:
Convergence detected: relative gradient magnitude is below tolerance

yearly_seasonality=True #
| |
Initial log joint probability = -2.99674
Iter log prob ||dx|| ||grad|| alpha alpha0 # evals Notes
99 1076.96 1.35095e-06 94.027 0.3775 0.3775 136
Iter log prob ||dx|| ||grad|| alpha alpha0 # evals Notes
125 1076.96 2.65686e-06 89.152 2.895e-08 0.001 203 LS failed, Hessian reset
164 1076.96 2.28191e-08 91.6592 0.4114 0.4114 258
Optimization terminated normally:
Convergence detected: relative gradient magnitude is below tolerance

休日・イベント効果 #
休日効果 \(h(t)\) は、holidays に渡した日付だけ 1 になるダミー変数に係数 \(\kappa\) を掛けたものです。データに仕込んだ 10 日のイベント(+2)を、指定なし・指定ありで比べます。
休日・イベントの指定なし(holidays=None)
#
| |
Initial log joint probability = -2.99674
Iter log prob ||dx|| ||grad|| alpha alpha0 # evals Notes
99 1040.17 0.000845008 95.4398 0.3546 0.3546 128
Iter log prob ||dx|| ||grad|| alpha alpha0 # evals Notes
166 1045.08 8.28451e-05 66.0092 1.087e-06 0.001 252 LS failed, Hessian reset
184 1045.09 1.58284e-05 61.1258 3.535e-07 0.001 307 LS failed, Hessian reset
199 1045.09 1.20349e-07 45.161 0.0243 1 330
Iter log prob ||dx|| ||grad|| alpha alpha0 # evals Notes
264 1045.71 0.000316932 140.641 3.665e-06 0.001 456 LS failed, Hessian reset
292 1045.82 5.70302e-05 48.9256 1.155e-06 0.001 533 LS failed, Hessian reset
299 1045.82 7.71897e-06 40.8043 0.3543 1 544
Iter log prob ||dx|| ||grad|| alpha alpha0 # evals Notes
305 1045.82 5.91182e-07 46.3158 2.336e-08 0.001 594 LS failed, Hessian reset
317 1045.82 2.63213e-06 51.4268 5.486e-08 0.001 649 LS failed, Hessian reset
343 1045.82 1.59952e-05 25.621 2.535e-07 0.001 728 LS failed, Hessian reset
353 1045.82 6.70942e-07 31.5639 1.825e-08 0.001 779 LS failed, Hessian reset
355 1045.82 3.11455e-08 40.1124 0.08424 1 783
Optimization terminated normally:
Convergence detected: relative gradient magnitude is below tolerance

休日・イベントの指定あり #
| |
Initial log joint probability = -2.99674
Iter log prob ||dx|| ||grad|| alpha alpha0 # evals Notes
99 1343.59 0.00181622 336.302 0.9914 0.9914 120
Iter log prob ||dx|| ||grad|| alpha alpha0 # evals Notes
199 1366.61 0.00129331 915.041 0.2388 0.9805 232
Iter log prob ||dx|| ||grad|| alpha alpha0 # evals Notes
265 1372.99 0.000111116 289.963 4.926e-07 0.001 351 LS failed, Hessian reset
299 1374.36 0.00236219 89.8611 1 1 393
Iter log prob ||dx|| ||grad|| alpha alpha0 # evals Notes
399 1375.61 0.00707432 82.6526 1 1 509
Iter log prob ||dx|| ||grad|| alpha alpha0 # evals Notes
431 1375.93 8.82293e-05 240.658 4.05e-07 0.001 581 LS failed, Hessian reset
453 1376.02 6.12661e-05 95.4391 1.44e-06 0.001 644 LS failed, Hessian reset
471 1376.06 1.2062e-05 14.2904 2.239e-07 0.001 709 LS failed, Hessian reset
485 1376.1 1.9227e-05 69.5783 2.446e-07 0.001 772 LS failed, Hessian reset
493 1376.12 3.43778e-05 51.3583 1.873e-06 0.001 837 LS failed, Hessian reset
499 1376.13 2.95479e-05 34.8029 0.5524 0.5524 847
Iter log prob ||dx|| ||grad|| alpha alpha0 # evals Notes
509 1376.13 8.88412e-06 44.6026 5.452e-07 0.001 897 LS failed, Hessian reset
521 1376.14 1.6737e-05 27.0944 1.441e-07 0.001 947 LS failed, Hessian reset
531 1376.14 7.82708e-06 47.5548 1.997e-07 0.001 1000 LS failed, Hessian reset
567 1376.28 3.47594e-05 113.402 3.767e-07 0.001 1079 LS failed, Hessian reset
599 1376.35 0.000359311 95.2959 1 1 1118
Iter log prob ||dx|| ||grad|| alpha alpha0 # evals Notes
604 1376.35 4.84989e-06 13.344 1.606e-07 0.001 1168 LS failed, Hessian reset
612 1376.35 2.91053e-08 12.4075 0.04535 1 1191
Optimization terminated normally:
Convergence detected: relative gradient magnitude is below tolerance

実行結果の読み方 #
休日を指定した図では、イベント日の 10 個の黒い点に青い線が届き、帯の外に残る点がなくなります。log prob も 1045 → 1376 と 7 枚の中で最大の改善で、「残差に残っていた 10 本のスパイクを 1 個の係数 \(\kappa \approx 2\) で説明できた」ことを表しています。一方、年周期を入れた図(log prob 1077)は数値では改善しているように見えても予測期間の形が 2020 年の丸写しで、当てはまりの良さと予測の良さは別物だと 2 枚を並べて確認できます。
使いどころと落とし穴 #
Prophet の 3 成分はそれぞれ得意な形が決まっています。トレンド \(g(t)\) は折れ線なので、指数的な成長には growth="logistic" と cap 列で上限を与えないと予測期間で発散します。季節性 \(s(t)\) はフーリエ級数なので、滑らかな周期は得意ですが、このデータの「土日だけ +0.5」のような段差は 3 次では角が丸まり、weekly_seasonality=5 のように次数を上げるか、add_regressor で土日ダミーを渡した方が正確です。休日効果 \(h(t)\) は日付が分かっているイベントに限られ、未来の日付も holidays に入れておかないと予測期間に反映されません。そして年周期は 2 年以上、できれば 3 年以上のデータがないと、この例のように 1 年分の形を丸写しした過学習になります。
- Prophetを実行してみる — 基本的な使い方を合成データで試す
- Prophetのパラメーター — changepoint_prior_scale など主要パラメーターの役割を整理
- ARIMA モデル — 差分・自己回帰・移動平均を組み合わせた古典的予測