はじめに
facebook社が開発したprophet(公式サイト)はトレンド・周期性・外部影響(線形)等の時系列要素の分解をしたモデルを学習・予測でき、時系列予測モデルを簡易に試せるライブラリとしてとても便利です。一方で事前分布(正則化)を調整したい、係数の符号を正に限定したい、時変係数を用いたいといった際用のパラメータがなく、改造をする方法も簡単に分からないことは不満に感じていました。本記事ではこの対策として、どのソースコードの修正すれば良いのかを探った結果を整理しています。
なお、prophetのバージョンは1.1.1を対象としています。
内部動作の確認結果
prophetでは統計モデリング言語のstan(wikipedia)を使ってベイズモデリングを記述しています。この構成を私が整理したものが図1です。stanをシェルから呼び出すcmdstan(公式サイト)があり、さらにそれをpythonで呼び出すためのcmdstanpy(公式サイト)を使ってstanにアクセスしており、それ以外の処理はpythonで記述されています。そのため、改造をする場合にはstanの範囲(ベイズモデリング)を変えるのか、pythonの範囲(それ以外)を変えるのかを整理する必要があります。
そのためにスクリプト(Github)の学習分を超概略で整理した結果が図2です。forecaster.pyの中にProphetクラスがあり、その中の__init__処理でモデル(学習済みモデルではなくstanモデルです)を読み込み、fitで学習します。これらの処理の実体はforecaster.pyではなくmodel.pyの中のCmdStanPyBackendクラスにあります。__init__ではprophet_model.binを読み込みますが、これはsetpy.py、つまりprophetのビルド・インストール時に作成するものです。そのため、ベイズモデリングの中身を改造したい場合にはprophet.stanを変更し、かつsetup.pyから実行する必要があることが分かります。
またfitではmodel.optimizeが出てきますが、これはcmpstanpyに用意されている関数で、APIリファレンスを確認すると最尤法の処理(アルゴリズムはAlgorithm to use. One of: ‘BFGS’, ‘LBFGS’, ‘Newton’)をすると記述があります。そのため学習処理の内cmpstanpyのoptimizeに流し込む変数を作る部分がpythonの所掌であることが読み取れます。
まとめ
prophetを改造するためには以下のスクリプトを変更する方針で望めば良いことが分かりました。次回は具体的な改造方法を記事にする予定です。
- forecaster.py及びmodel.py
cmdpystanのoptimizeに流し込むデータを改造する場合に変更 - prophet.stan
ベイスモデリングを改造する場合に変更(setup.pyの再実行から必要)