プロクラシスト

今日の寄り道 明日の近道

【Day-13】『Prophet入門』簡単に高精度を実現するFacebook謹製の時系列予測ライブラリ


スポンサーリンク

f:id:imslotter:20171213111429p:plain

データ分析ガチ勉強アドベントカレンダー 13日目。

仮想通貨がはやり始めて、チャートを見るようになった人も多いのではないでしょうか?

チャートから予測をしたい

という思いを持ちつつも、結構ハードルの高いのが時系列予測。 それをできるだけ簡単にできるツールがProphet

自分の持っているドメイン知識を導入しながら、簡単に時系列データ予測を行うことができます。

prophetとは

資料

  • Completely automatic forecasting techniques can be brittle and they are often too inflexible to incorporate useful assumptions or heuristics.
  • Analysts who can produce high quality forecasts are quite rare because forecasting is a specialized data science skill requiring substantial experience.
  • 完全な予測は柔軟さに欠ける
  • 時系列予測は特別なスキルがいる

から、良い予測が全然スケールしない。 なので、簡潔な記述必要な柔軟性を残し作ったのがProphet

設計思想

公式の設計思想がこちら

  • 簡潔な記述 : 正しい形で入力をすると、デフォルトで良い予測ができるようになっている
  • 柔軟性 : ユーザーの持つドメイン知識をいれることで、精度向上を測れる

必要のないものは裏でやっちゃって、必要な部分だけ自由度を残すという感じですね。

Prophetでできないこと

これだけ言えば超絶便利だと思われるが、もちろんできないこともある。

(認識間違っていたら教えてください。)

  • いろいろなアルゴリズムを試して比べるようなものではない*2
  • 予測のためのツール。時系列クラスタリングなどはできない。
  • 他変数を用いた予測(issueにあげられているので、そのうち対応されるかも。されてほしい)

根底のアルゴリズム

additive regression modelを利用している。具体的には下記のアルゴリズムを組み合わせている。

  • トレンドをlinearかlogistic曲線で近似する。また、Prophetではトレンドの変化点も自動で検知するようになっている
  • Fourier級数によって、年周期を抽出している
  • ダミー変数をもちいて週周期を抽出している
  • 重要な休日やイベントのリストをわれわれユーザー側で与えられる(ドメイン知識)

インストール

切り分けのため、別々にインストールするといいかも。*3

# numpyとmatplotlibを最新版にしておくといい
pip install -U numpy matplotlib
# mcmc等サンプリング用ライブラリ
pip install pystan
# fbprophet
pip install fbprophetc

Prophet tutorial

型の変換

  • pythonAPIでは、sklearnのモデルを踏襲しているため、fitpredictで学習と予測を行うことができる。
  • inputは必ず下記の型で行う
変数 用途
ds datetime 時系列情報(タイムスタンプ)
y 数値 そのときの値
%matplotlib inline
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
from datetime import datetime
from fbprophet import Prophet
df = pd.read_csv("AirportPassengers.csv",delimiter=";").dropna()
def str2time(string):
    #datetimeに変換
    return datetime.strptime(string, '%Y-%m')
# 読み込んだデータをdsとyに変える
df["ds"] = df.Month.apply(str2time)
df = df.drop(["Month"],axis=1)
df["y"] = np.log(df.Passengers) #logをとる
df.head()

出力。dsyの形で持っている

   Passengers         ds         y
0       112.0 1949-01-01  4.718499
1       118.0 1949-02-01  4.770685
2       132.0 1949-03-01  4.882802
3       129.0 1949-04-01  4.859812
4       121.0 1949-05-01  4.795791

将来の予測

下記の手順で、めちゃくちゃ簡単に予測までできる。面倒なパラメータ調整なんていらない。めちゃくちゃ簡単。

  • m = Prophet()で初期化(ドメイン知識はここで入れる!)
  • m.fit(df)で学習
  • make_future_dataframeで、dsのデータフレームを追加
    • freq : 予測する間隔(freq="M"ならMonthly。詳しくは公式 Sub-daily data )
    • periods : 何個dataframeを作るか
  • m.predct(future)で予測 : 出力はdataframe型
  • m.plot()でかなりオシャレなプロット

今回は、下記要領で予測する

  • 1949年1月から1960年12年までのデータを入力にする
  • 1961年1月から5年間を予測する
m = Prophet()
# prophetに入れるには、dsとyのペアが必要
m.fit(df)
future = m.make_future_dataframe(periods=60,freq="M")
forecast = m.predict(future)
forecast[["ds","trend","yhat"]].tail()
m.plot(forecast);
plt.legend()

出力がコレ

かなりきれいな予測が出来ていそう。また、予測の誤差見積もりまでplotされている。色使いがFacebookっぽくてこれまたオシャレ感がある。

Components

アルゴリズムで紹介したように、トレンドや周期性についての分析結果は、m.plot_components()にて見ることができる。

m.plot_components(forecast)

特別なイベントなど

ドメイン知識を入力し、精度向上を図ることができる。↓が参考になる。

facebook.github.io

help

その他使い方はhelp(Prophet)と打つ。

まとめ

一次元のデータを予測するなら、本当に簡単に分析が行えるので、オススメ。 株価でも突っ込んで分析をしてみようかな。

株価といえば、明日はテクニカル分析で使われる指標について調べて実装してみます。オレオレ分析ツールを作りたいと思っているので。ではでは、また明日!

*1:ドメイン知識の入れ方や、時系列予測に対する評価方法も書かれていて、良かった。

*2:設計思想上その必要はない気がする

*3:単にpip install fbprophetのみでもOKではありそう。

PROCRASIST