Facebook Prophet
「ARIMAは強力だが、ビジネスの実務で使うにはやや敷居が高い。Prophetはその課題を解決するために作られた。」
田中VPoEがProphetの論文を開く。
「トレンドの変化点を自動検出し、祝日効果をそのまま組み込める。しかもパラメータチューニングがほぼ不要。Store Salesの祝日データを活かすなら、Prophetは有力な選択肢だ。」
Prophetとは
Facebook(Meta)が開発した時系列予測ライブラリ。加法的モデルで以下を組み合わせる。
y(t) = g(t) + s(t) + h(t) + ε(t)
g(t): トレンド成分(区分線形 or ロジスティック成長)
s(t): 季節成分(フーリエ級数で表現)
h(t): 祝日・イベント効果
ε(t): 誤差項
Prophetの強み
| 強み | 説明 |
|---|---|
| トレンド変化点 | 自動で成長率の変化を検出 |
| 祝日効果 | 祝日リストを渡すだけで効果を推定 |
| 欠損値対応 | 欠損があってもそのまま学習可能 |
| 解釈性 | 各成分の寄与を可視化できる |
| 使いやすさ | パラメータチューニングがほぼ不要 |
基本的な使い方
from prophet import Prophet
import pandas as pd
# データの準備(Prophet形式: ds, y)
grocery = train[train['family'] == 'GROCERY I'].groupby('date')['sales'].sum()
prophet_df = grocery.reset_index()
prophet_df.columns = ['ds', 'y']
# モデルの構築
model = Prophet(
yearly_seasonality=True,
weekly_seasonality=True,
daily_seasonality=False,
changepoint_prior_scale=0.05, # トレンド変化の柔軟性
seasonality_prior_scale=10, # 季節性の柔軟性
)
# 学習
model.fit(prophet_df[prophet_df['ds'] < '2017-08-01'])
# 未来の日付を生成して予測
future = model.make_future_dataframe(periods=15)
forecast = model.predict(future)
# 予測結果の確認
print(forecast[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].tail(15))
祝日効果の組み込み
Store Salesの複雑な祝日データをProphetに組み込む。
# 祝日データの変換
holidays_raw = pd.read_csv('holidays_events.csv', parse_dates=['date'])
# 国定祝日のみ抽出してProphet形式に変換
national_holidays = holidays_raw[
(holidays_raw['locale'] == 'National') &
(holidays_raw['type'].isin(['Holiday', 'Additional']))
].copy()
prophet_holidays = pd.DataFrame({
'holiday': national_holidays['description'],
'ds': national_holidays['date'],
'lower_window': -1, # 祝日の1日前から効果開始
'upper_window': 0, # 祝日当日まで
})
# 地震をイベントとして追加
earthquake = pd.DataFrame({
'holiday': ['Earthquake'],
'ds': [pd.Timestamp('2016-04-16')],
'lower_window': [0],
'upper_window': [14], # 2週間の影響
})
prophet_holidays = pd.concat([prophet_holidays, earthquake])
# 祝日付きモデル
model_with_holidays = Prophet(
yearly_seasonality=True,
weekly_seasonality=True,
holidays=prophet_holidays,
changepoint_prior_scale=0.05,
)
model_with_holidays.fit(prophet_df[prophet_df['ds'] < '2017-08-01'])
トレンド変化点の分析
# トレンド変化点の可視化
from prophet.plot import add_changepoints_to_plot
fig = model.plot(forecast)
add_changepoints_to_plot(fig.gca(), model, forecast)
plt.title('トレンド変化点の検出')
plt.show()
# 検出された変化点の確認
print("検出された変化点:")
for cp in model.changepoints:
print(f" {cp.strftime('%Y-%m-%d')}")
# changepoint_prior_scaleの調整
# 大きい値: 変化点を多く検出(オーバーフィットのリスク)
# 小さい値: 変化点を少なく検出(アンダーフィットのリスク)
成分の可視化
# 各成分のプロット
fig = model_with_holidays.plot_components(forecast)
plt.tight_layout()
plt.show()
# 表示される成分:
# 1. trend: 長期的な成長・衰退
# 2. weekly: 曜日別の効果(日曜高い、等)
# 3. yearly: 月別の効果(12月高い、等)
# 4. holidays: 各祝日の効果
パラメータチューニング
from prophet.diagnostics import cross_validation, performance_metrics
# クロスバリデーション
cv_results = cross_validation(
model_with_holidays,
initial='730 days', # 最初の学習期間
period='30 days', # 毎30日ごとに評価
horizon='15 days', # 15日先を予測
)
# 性能指標の算出
metrics = performance_metrics(cv_results)
print(metrics[['horizon', 'mae', 'rmse', 'mape']].tail())
# パラメータグリッドサーチ
param_grid = {
'changepoint_prior_scale': [0.01, 0.05, 0.1, 0.5],
'seasonality_prior_scale': [1, 5, 10, 15],
}
best_mape = float('inf')
best_params = {}
for cps in param_grid['changepoint_prior_scale']:
for sps in param_grid['seasonality_prior_scale']:
m = Prophet(
changepoint_prior_scale=cps,
seasonality_prior_scale=sps,
holidays=prophet_holidays,
)
m.fit(prophet_df[prophet_df['ds'] < '2017-08-01'])
cv = cross_validation(m, initial='730 days', period='60 days', horizon='15 days')
metrics = performance_metrics(cv)
avg_mape = metrics['mape'].mean()
if avg_mape < best_mape:
best_mape = avg_mape
best_params = {'cps': cps, 'sps': sps}
print(f"最適パラメータ: {best_params}")
print(f"最良MAPE: {best_mape:.4f}")
Prophetの限界
| 限界 | 説明 |
|---|---|
| 外部回帰変数 | add_regressorで追加可能だが、未来の値が必要 |
| 多変量 | 単一系列のみ。系列間の関係を考慮しない |
| 短期予測 | 日次の細かいパターンは苦手 |
| 大量系列 | 1,782系列を個別に学習するのは時間がかかる |
まとめ
| 項目 | ポイント |
|---|---|
| Prophet | トレンド + 季節性 + 祝日の加法モデル |
| 祝日効果 | lower/upper_windowで影響範囲を指定 |
| 変化点 | changepoint_prior_scaleで柔軟性を制御 |
| 評価 | cross_validationで信頼性の高い評価 |
チェックリスト
- Prophetの3成分(トレンド、季節性、祝日)を説明できる
- 祝日データをProphet形式に変換できる
- トレンド変化点の可視化と解釈ができる
- クロスバリデーションで性能評価ができる
次のステップへ
Prophetで季節性と祝日効果をモデル化できた。次はLightGBMを使い、特徴量エンジニアリングで予測精度をさらに向上させよう。
推定読了時間: 30分