汝、先を見通す力を欲するか?...良かろう、我を使うがよい!我が名はProphet、これから起こる未来を見せてやろう
毎回タイトルがふざけててすいません。
内容はまじめなのでご安心ください。
今回は時系列予測アルゴリズムについての紹介です。
Prophetという語は日本語で言うと預言者(または予言者)です。
宗教書か異世界・ファンタジー小説ぐらいにしか出てこない単語なので、雰囲気を出してみました。
仕事で売上予測することになった、株価予測したいなど、時系列データを分析したいけど方法がわからない。
そんなあなたへこそ是非ともご紹介したい。
簡単に使えて性能がいいモノがあります。
最近といっても5年以上前ですが、
2018年Metaから時系列分析方法に関する論文が出ました。
ネーミングセンスは中二病感はありますが、結構使えます。
論文
TAYLOR, Sean J.; LETHAM, Benjamin. Forecasting at scale. The American Statistician, 2018, 72.1: 37-45. pdf
@article{taylor2018forecasting,
title={Forecasting at scale},
author={Taylor, Sean J and Letham, Benjamin},
journal={The American Statistician},
volume={72},
number={1},
pages={37--45},
year={2018},
publisher={Taylor \& Francis}
}
公式っぽいページ:
Meta Forecasting at scale.
- https://peerj.com/preprints/3190/
- https://facebook.github.io/prophet/docs/quick_start.html
- https://github.com/facebook/prophet
このブログでは簡単に使い方を紹介します。
prophetとは
モデルとしては下の式で表されるようにトレンド、周期項、外部項、ノイズに分解するものです。
ここで各項は下のようになっています。
-
: トレンドg(t) -
: 季節性変動項(周期項)s(t) -
: 外部依存項(祝日、イベントなど)h(t) -
: 誤差項\epsilon
周期的なものとしては例えば1年365.25日とか、1週間の7日とか1か月の30.4375(=365.25/12)日とかです。
その他にも隔週開催イベントや4半期ごとの入れ替えなどありうると思いますので、状況に応じて設定できます。
ノイズはもちろん周期項や外部依存項があるので1週間の効果を別にして分析をすることができます。
周期項
理系の大学生ならフーリエ変換というものを知っていると思いますが、
周期的な信号は倍数の周波数(nf=n/P)の波の重ね合わせで表現できます。
ここではN個としています。この項にあてはめてaとbの係数を求めることで周期成分とします。
prophetのチュートリアルをやってみるとわかりますが、
7と365周期は初期設定で入っているようです。
外部項
祝日はそれぞれの国の政府が法律で決めるもので、偶に代わります。
祝日に来場者数が増えるなどの知見があるならば、
その情報を分析に入れることができます。
オプションの引数名がholidaysになっていますが、
他の値も入れられます。
トレンド
トレンドというのはベースラインが上下したり、上昇傾向・下降傾向に変化しているという情報です。
この中では変化点(change point)をおいて推定することでトレンドを表現しています。
使ってみる
インストールはこれだけです。
pip install pandas prophet matplotlib plotly
ローカルで動かす場合は下のコードを試してみてください。
スポーツに関するデータだそうです。
import pandas as pd
from prophet import Prophet
import os
import matplotlib.pyplot as plt
from prophet.plot import plot_plotly, plot_components_plotly
url = 'https://raw.githubusercontent.com/facebook/prophet/main/examples/example_wp_log_peyton_manning.csv'
file_path = 'example_wp_log_peyton_manning.csv'
if not os.path.exists(file_path):
df = pd.read_csv(url)
df.to_csv(file_path, index=False)
else:
df = pd.read_csv(file_path)
print(df.head())
m = Prophet()
m.fit(df)
print(m)
future = m.make_future_dataframe(periods=365)
print(future.tail())
forecast = m.predict(future)
print(forecast[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].tail())
#forecast.to_csv('forecast.csv', index=False)
fig1 = m.plot(forecast)
fig1.savefig('fig1.png')
fig2 = m.plot_components(forecast)
fig2.savefig('fig2.png')
plt.show()
これを実行すると下のような図が表示されます。
通常の観測データはノイズや様々な要因が絡み合ってできるものなので、
全てこのモデルで説明できるわけではないですが、
本質的なトレンドや周期的な動きがグラフから読み取れます。
うすい青い部分は揺らぎ(標準偏差)です。
周期項で述べたようにデフォルトで7日と365日の周期の分析結果が表示されます。
下の図は各項を分離したグラフです。
月曜が高くなっているとか9月以降2月ころまで高くなっているなどの情報が読み取れます。
観客動員数とか、クリック数などマイナスの結果は解釈できない場合などありますが、
普通に使っていると予測値が0以下になってしまうこともあります。
ある一定以上で予測してほしいなど下限を設けることもできます。
さきほどのdfを使って、わざと下に下げ、予測下限を1.5、上限を6としてみました。
この場合はデータを下にシフトしただけなのでマイナスのデータもありますが、指定した範囲内で予測できています。
df['y'] = 10 - df['y']
df['cap'] = 6
df['floor'] = 1.5
future['cap'] = 6
future['floor'] = 1.5
m = Prophet(growth='logistic')
m.fit(df)
fcst = m.predict(future)
fig = m.plot(fcst)
今回の記事はここまでです。
時系列予測については、まだ紹介したいことが多くあるので、また第2段をまとめておきます。
下にProphetを使う上で参考になりそうな記事を紹介します。
参照リンク
- Prophet入門【Python編】Facebookの時系列予測ツール
- Prophetを使ってサクッと時系列データ予測をやる
- Prophetの使い方メモ
- Prophetによる時系列データ予測: Analyst-in-the-Loop
- 【Python 入門】Prophet を使った時系列データ分析と Plotly による可視化!
- Pythonで時系列解析・超入門(その4)Prophetモデルで予測する方法
- Pythonで簡単に時系列予測が行えるライブラリを試して比較してみた(Prophet、NeuralProphet、StatsForecast、Greykite)
- Prophetのモデル式を1から理解する
Discussion