04.10.2
【ベンチマーク】曜日パターンのある日次データ
seasonal_periods=7 や seasonal_order=(1,1,1,7) で週次の季節性を明示したモデルは MASE が 1 を下回って安定し、曜日を持たない SES と ARIMA は毎日 ±15 前後ずれて 1 を超えます。残差の ACF を見るとその差は MASE 以上にはっきりしていて、曜日を無視したモデルにはラグ 7 と 14 に自己相関のスパイクが残ります。売上・アクセス数・問い合わせ件数など、「平日と週末で挙動が違う」データは実務で頻繁に遭遇する。ここでは曜日パターンを持つ合成データを生成し、前処理とモデルの組み合わせがどの程度の精度差を生むかを検証する。
1. データの特徴 #
このシナリオでは、月曜〜金曜は水準が +20、土日は −10 と 30 ポイントの段差があり、全体は 1 日 0.05 ずつ右肩上がりで、標準偏差 5 のノイズが乗っています。曜日の段差 30 はノイズの 6 倍なので、週次の季節性(周期 7)をモデルが明示的に持つかどうかが精度の分かれ目になります。前処理では対数変換と差分のほか、resample("W").mean() で週次に丸める方法も試しますが、週次化は曜日の情報そのものを消すので日次の予測には戻れません。
何が起きているか(ステップで見る) #
コードを読む前に、この手法が図の上で何をしているかを追ってみましょう。「再生」を押すか、スライダーを動かすと 1 手順ずつ進みます。
見るポイント:曜日ごとに色分け・平均すると、ノイズに隠れた週のパターンが取り出せる。
2. 合成データの生成 #
次のコードは dates.dayofweek から平日と週末を判定して曜日効果を作り、トレンドとノイズを足した 730 日の系列を描きます。上段は全期間の折れ線、下段は直近 8 週を平日(青)と週末(橙)で色分けした棒グラフです。
| |
3. 比較するパイプライン #
| 前処理 | モデル | 季節性の扱い |
|---|---|---|
| なし | 季節ナイーブ (sp=7) | 明示 |
| なし | SES | なし |
| なし | Holt-Winters 加法 (sp=7) | 明示 |
| なし | ARIMA(1,1,1) | なし |
| なし | SARIMAX(1,1,1)(1,1,1,7) | 明示 |
| 対数変換 | 季節ナイーブ / SES / HW / ARIMA / SARIMAX | 同上 |
| 週次リサンプリング | 季節ナイーブ / SES / HW / ARIMA | 週次化で曜日情報消失 |
| 差分 | 季節ナイーブ / SES / HW / ARIMA / SARIMAX | 同上 |
4. 実験と結果 #
次のコードは前処理 preprocess_ts とモデル forecast_ts を定義し、なし・対数・差分の 3 前処理 × 5 モデルで 28 日先を予測して MASE を集めます。週次リサンプリングだけは 4 週先の予測として別に回し、最後に 4 行 × 5 列のヒートマップに並べます。
| |
読み方のポイント #
週次の季節性(sp=7)を指定した季節ナイーブ・HW加法・SARIMAX の列は、なし・対数・差分のどの行でも MASE が 1 を下回って緑で安定します。SES と ARIMA(1,1,1) は曜日を内部に持たないため、予測が平日と週末の中間(平均)に落ち着き、平日で約 −10、週末で約 +20 の外れを毎日繰り返して赤になります。対数変換は水準 100 前後で振幅も一定のデータには効果がなく、「なし」の行とほぼ同じ値です。週次リサンプリングの行は 4 週先の週平均を当てる別の問題を解いているので、値が小さく見えても日次予測の代わりにはならず、曜日情報を消した時点で「金曜のピークに在庫を積む」といった判断には使えなくなります。
5. 誤差パターン分析 #
MASE の数字が同じでも、残差に曜日の波が残っているかどうかで予測区間の信頼性が変わります。次のコードは SARIMAX・ARIMA・SES の 3 つについて、左にテスト 28 日の実測と予測、右に残差の ACF(ラグ 14 まで)を並べ、ラグ 7 と 14 にスパイクが立つかを確かめます。
| |
SARIMAX の残差はホワイトノイズに近く、ACF の 14 本の棒は信頼区間の帯の中に収まり、左の図では予測の破線が平日と週末の段差を実測どおりにたどります。ARIMA(1,1,1) と SES の残差にはラグ 7 と 14 に明確な正のスパイクが残り、左の図では予測が平日と週末の中間を水平に走ります。これは MASE の数字以上に深刻な問題です。モデルが周期 7 の構造を取りこぼしているため、get_forecast().conf_int() が返す予測区間も残差が独立だという前提を満たさず信頼できません。
6. よくある失敗パターン #
最初の失敗は週次リサンプリングで日次予測を代替することで、resample("W").mean() は平日 +20 と週末 −10 の山谷を週平均の約 +11 に均してしまい、「金曜にピークが来る」「日曜に 30 落ちる」という日次の情報を二度と取り出せません。週次で十分な意思決定(月間の在庫計画など)にだけ resample("W") の系列を使います。二つ目は seasonal_periods=7 や seasonal_order=(…, 7) を設定し忘れることで、Holt-Winters や SARIMAX を使っていても sp を渡さなければ SES や ARIMA と同じく曜日を学習せず、ヒートマップの赤いセルと同じ結果になります。三つ目は MASE だけで満足することで、ARIMA(1,1,1) の MASE が 1.5 程度で「まあ使える」と判断しても、残差 ACF のラグ 7 にスパイクがあれば予測区間は信頼できず、plot_acf での確認を省けません。
- ウォークフォワード検証 — 時系列の正しい評価手法
- MASE — 季節ナイーブ基準の指標
- ホルト・ウィンター法 — 季節性を含む指数平滑法
- ARIMA モデル — 自己回帰と移動平均を組み合わせた古典的な予測モデル