BETA

Prophetのモデルまとめ

投稿日:2019-10-30
最終更新:2019-10-30

アホ大学生が書いたので自己責任で、ゼミ用のパワポからコピペしただけだったり前に書いた記事を合成したキメラ記事です。

Prophetとは

Facebookが開発した時系列予測ツールであり、PythonとRに対応している

予測はデータサイエンス的には一般的な問題で重要であるにも関わらず、質の良い時系列予測を行える人が少ないから、ちゃんとした予測をより簡単に行えるようにしたらしい

今回は論文を読んでみた(Forecasting at scale)

Prophetの良い点

複数の期間の季節性(例えば年・月・週などの異なる周期の項)に簡単に対応でき、傾向について仮定を立てることができる。

測定値の周期が一定である必要はなく、欠損値を補間する必要もない(例:外れ値の除去等)。

フィッティングが非常に高速であるため、多くのモデル仕様をインタラクティブに調査できる。

予測モデルには予測に仮定を簡単に適用するための変数が複数あり、モデルを簡単に拡張して新しい要素を加えることが出来る。

Prophetは判断的予測と統計的予測の良い所をうまく取り入れている

  • 統計的予測
    過去のデータに基づいてモデルをフィットさせる予測
    大規模の問題に対してすぐ計算できる
  • 判断的予測
    特定の時系列でうまく行く予測
    多くの情報を入れることができ、変化状況に対応しやすい

Prophetのモデル

分解可能な時系列モデルを使用している

主にtrend, seasonality, holidaysの3つ
$$y(t)=g(t)+s(t)+h(t)+ε_t$$

g(t) がtrend、s(t) がseasonality、h(t) がholidays、 $ε_t$が誤差項。 この式の形は一般化加法モデル(Generalized Additive Model(GAM))と似た形となっている。

それぞれの成分が予測問題に対してどう影響あるか等が見える
→成分ごとに色々仮説立てやすいよね

g(t) トレンドモデル

Prophetでは2つのTrend modelを持っている

  • 飽和成長モデル(saturating growth model)
  • 区分的線形モデル(piecewise linear model)

基本的なロジスティック成長モデル(saturating growth model)は以下の形
$$g(t)=\frac{C}{(1+exp(-k(t-m)))}
$$
Cは容量、kは成長率、mはoffset変数

容量はある時点によって変化するので、$C(t)$とする

成長率も常に一定ではない

成長モデルの中に成長率が明確に変化している傾向変化点を定義する事でtrendの変化を組み込んでいる

ある時点における傾向変化点を$s_j$とする

また、$j$における変化率のベクトルを$δ_j$とする

どんな時点においても基本のレートを$k$とし、その時点の変化率を合計した物を$k+\sum_{j:t>s_j}{δ_j}$とする

ここで、$a(t)∈{0,1}^S$というベクトルを定義する

$a(t) = \begin{cases}
1, if   t\geq s_j ,\\
0,  otherwize
\end{cases}$

こうする事で、ある時点tにおける変化率(?)は$k+a(t)^Tδ$と表せる

が求まると、offset変数である$m$はある期間の末点に合う必要があるので、$m$も求まる
傾向変化点における正しい調節(?)は

$\gamma_j= ( s_j - m - \sum_{l<j}{\gamma_l})(1-\frac{k+\sum_{l<i}{\delta_l}}{k+\sum_{l≦i}{\delta_l}})$ で求めることが出来る

従って、ロジスティック成長モデルは以下のようにあらわせる。
$g(t) = \frac{C(t)}{1 + exp(-(k + a(t)^T\delta)(t - (m + a(t)^T \gamma)))}$

ここで示されたロジスティック成長モデルはシグモイド曲線だけに対応したロジスティック成長曲線を示す

線形の場合は$g(t) = (k+a(t)^T\delta + (m+ a(t)^T\gamma)$と表される

変更点の自動選択

変更点$s_j$は製品の販売日や成長が変更されるイベントの日を指定する事で設定される。
Prophetでは多くの数の変更点を設定する。
変更点の自動選択は、先ほど定義した
$$g(t) = (k+a(t)^T\delta + (m+ a(t)^T\gamma)$$
或いは
$$g(t) = \frac{C(t)}{1 + exp(-(k + a(t)^T\delta)(t - (m + a(t)^T \gamma)))}$$
の式であらかじめスパースを設定する事で簡単に設定できる。

不確実なトレンド予測

モデルが過去を超えた履歴を利用して予測をする時、トレンドは不確実なものになる。
Prophetでは不確実なトレンド予測を生成モデルを前に広げることで推定している。
トレンドを生成するためのモデルには変更点が過去の履歴よりも多く、それぞれの点はレート変更$\delta_j ~ Laplace(0, \Gamma)$を持っており、Prophetでは将来の変化する率をデータから推測された分散で置き換えることにより、将来のレート変更を予測する。

s(t) 季節性

季節効果に対応するためには、モデルににおける関数を指定する必要がある

フーリエ級数に基づいて周期効果に対して柔軟性のあるモデルは以下のように表せる

$s(t) = \sum^N_{n=1}{a_n cos(\frac{2πnt}{P}) + b_n sin(\frac{2πnt}{P})}$
Pは期間を示している(P=365.25なら一年)

季節効果をfitさせるには2N個の変数$β=[a_1, b_1, ..., a_N, b_N]^T$を推定する必要がある
これは、季節ベクトルの行列によって求める事が出来る
例えばN=10の時、
$$X(t) = [cos(\frac{2π(1)t}{365.25}, ..., sin(\frac{2π(10)t}{365.25}]$$
となる
つまり季節効果は$s(t)=X(t)β$となる
Nが大きくなるとoverfittingしやすくなるが、seasonal patternにfitしやすくなる

h(t) 祝日・イベント効果

祝日やイベント効果は予測に対して大きな影響を与える

それぞれの祝日$i$ごとに、$D_i$をその休日の過去と未来の集合とする(?)
ある時点$t$が祝日$i$であるか判別する関数$Z(t)$を作る
そしてそれぞれの祝日に変数$K_i$を割り当てる
$K_i$は予測内の変化に対応している
これらはseasonalityと同様の方法で求められる

従って$Z(t) = [1(t∈D_1), ..., 1(t∈D_L)]$と表される

よって$h(t) = Z(t)K$
と表される

Model Fitting

それぞれの時点における季節性と祝日の特徴量が行列$X$に含まれており、傾向変化点を示す$a(t)$が行列$A$に含まれているとき、
$y(t)=g(t)+s(t)+h(t)+ε_t$はStanのコードで書ける(論文参照)

モデルのFittingにはStanのL-BFGSを使って事後推定値の最大値を見つける
或いは完全な事後推論を行って、予測の不確実性にモデルパラメーターの不確実性を含めることもできる
その結果季節性を反映する事が出来た(論文参照)

Automating Evaluation of Forecast

筆者はここで力尽きたようだ

参考

https://facebook.github.io/prophet/
https://peerj.com/preprints/3190/
https://data.gunosy.io/entry/change-point-detection-prophet
http://funyakofunyao.click/2017/04/30/prophet%E7%B5%B1%E8%A8%88%E3%83%A2%E3%83%87%E3%83%AB%E6%A6%82%E8%A6%81/

間違い等指摘してくれると嬉しいです。

技術ブログをはじめよう Qrunch(クランチ)は、プログラマの技術アプトプットに特化したブログサービスです
駆け出しエンジニアからエキスパートまで全ての方々のアウトプットを歓迎しております!
or 外部アカウントで 登録 / ログイン する
クランチについてもっと詳しく

この記事が掲載されているブログ

大学生の書きなぐりブログ 間違ってる事も書いてるので自己責任で勉強しましょう

よく一緒に読まれる記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう
目次をみる
技術ブログをはじめよう Qrunch(クランチ)は、プログラマの技術アプトプットに特化したブログサービスです
or 外部アカウントではじめる
10秒で技術ブログが作れます!