前回の記事ではProphetが時系列データのトレンドを折れ線モデルで表現できることを紹介しました。
しかし現実の問題の中には折れ線モデルでは表現できないトレンドを持つ場合があります。
代表的なものは人口の変動であり、これは経済学者マルサスが主張したように指数関数的に増大します。
あるインターネット上のサービスへの参加人数(つまりFacebookのユーザ数などです)も人口の変動のような指数トレンドを持つと考えることができます。
Prophetはこのような非線形に成長するデータもトレンドを分析することもできます。
【非線形成長モデルとは】
Prophetはトレンドをロジスティック関数でモデル化します。
ロジスティック関数とはマルサスの指数関数をより現実的に修正したものであり、次の式で表されます。
\displaystyle g(t)=\frac{C}{1+\exp(-k(t-b))}
ロジスティック関数はマルサスのモデルのように無秩序に指数関数的に増大するのではなく、環境収容力Cから遠い場合には指数関数的に増大するが、そのうち減速して最終的には環境収容力に収束します。
容器の大きさや栄養を一定とした条件下で菌の数が増大する様子がこの関数でモデル化できることが知られています。
kは成長率、bは時刻合わせのための調整パラメータです。

wikipedia ロジスティック方程式より引用
ただしProphet原論文によると、このロジスティック関数でFacebookのサービスの成長のトレンドを表現するにあたり二つの課題があったそうです。
一つは環境収容力Cが一定ではないこと。たとえばインターネットにアクセスできる人が増えればそれだけCも増えなければなりません。
ProphetはこれをCを時刻を変数とする関数C(t)とすることで対応しました。
Cはデータから学習する値ではありません。外部条件から分析者がProphetに設定してあげるものです。
これについては下記で詳細を説明します。
もうひとつは成長率kが一定ではないこと。
新製品が発売されるとFacebookの成長率は変化します。
これは折れ線モデルの場合と同様に、変化点を持たせてその時点において成長率kが変化するモデルを採用します。
なおその場合は関数の連続性を維持するためにbもkから自動的に計算され、変更されます。
【環境収容力のモデル設計】
非線形成長モデルを用いる場合は環境収容力Cの設定が必須です(なお成長率kはProphetが自動で同定してくれます。)。
もちろんある時点の予測値の許容限界値がはっきりと分かっていればそれを採用すればよいですが、もしそうでない場合には、Prophet原論文によると、一定値を与えたり(C(t)=K), 線形にしてみたり(C(t)=Mt+K)、外部情報を引っ張ってきたり(たとえば世界銀行のデータから人口の予測値)ということをして設定します。
上記の理由から私はProphetを使う際には基本的には折れ線モデルを採用するべきだと考えています。
非線形成長モデルを使う場合は
- 新製品、新サービスが発表された後で成長過程にある
- 環境収容力が明確である
という条件が整ったときにのみ使うべきです。
【Prophetでの使い方】
公式サイトの手順を参考に、実際に非線形成長モデルを用いて分析してみます。
対象データはwikipedia日本語版のR言語にします。
#R > library(wikipediatrend) > page_views <- wp_trend(page = "R言語", lang = "ja", from = "2008-01-01", to = "2015-12-31") > tail(page_views) date count lang page rank month title 1 2015-12-26 113 ja R%E8%A8%80%E8%AA%9E -1 201512 R言語 2 2015-12-27 114 ja R%E8%A8%80%E8%AA%9E -1 201512 R言語 3 2015-12-28 216 ja R%E8%A8%80%E8%AA%9E -1 201512 R言語 4 2015-12-29 177 ja R%E8%A8%80%E8%AA%9E -1 201512 R言語 5 2015-12-30 102 ja R%E8%A8%80%E8%AA%9E -1 201512 R言語 6 2015-12-31 67 ja R%E8%A8%80%E8%AA%9E -1 201512 R言語 > rlang <- data.frame(ds = page_views$date, y = page_views$count)
ここからもダウンロードできるようにしてあります。
rlang.csv
まずはグラフを見てみます。
2008年にぐぐっと成長したあとで、頭打ちになっている様子です。
2012年以降の平均値が275だったのでとりあえずはその数値を環境収容力と置きましょう。
ただし対数を取って分析します。
#R > rlang <- rlang[rlang$y != 0,] > rlang$y <- log(rlang$y) > rlang$cap <- log(275) > head(rlang) ds y cap 31 2008-02-01 4.852030 5.616771 32 2008-02-02 4.488636 5.616771 33 2008-02-03 4.584967 5.616771 34 2008-02-04 4.820282 5.616771 35 2008-02-05 4.852030 5.616771 36 2008-02-06 4.844187 5.616771
環境収容力はcap列として設定します。
それぞれの行が日付に対応しているため、ある日付の環境収容力はその行のcapの値となるわけです。
この方法ならば任意の時刻の環境収容力を自由に設定できますね。
#R > m <- prophet(rlang, growth = "logistic") > future <- make_future_dataframe(m, periods = 365) > future$cap <- log(275)
非線形成長モデルで予測するためにprophetの引数growthに”logistic”を設定します。
この際、rlangにcap列が入っていることがlogisticを設定できる条件です。
また予測したい時系列データをmake_future_dataframe関数を用いて生成しますが、このデータにもcapを設定します。
将来capが変わる場合は未来のcapを変更することも可能です。
#R > forecast <- predict(m, future) > plot(m, forecast)

なんかあんまりうまく行っているように見えませんが、一応処理は完了しました。
y=5.61のあたりに水平に引かれている点線が環境収容力を表しています。
#R > prophet_plot_components(m, forecast)

トレンド要素がy=5.61に収束しつつあることが分かります。