タダケンのEnjoy Tech

楽しみながらラクに成果を上げる仕組みを考える

【Python】誰でも簡単に予測モデルが作れるProphetでTOPIXの予測モデルを作ってみた

f:id:tadaken3:20180324123817p:plain こんにちは!
タダケン(@tadaken3)です。

今回は時系列予測ツールProphetを使って、過去のデータから未来を予言する予測モデルの作成を試してみました。 ビジネスでは日々発生する時系列データ(DAU、売上など)に対する予測を作成する必要があります。

Prophetを使うことで、とても簡単に予測モデルを作ることができます。Prophetはオープンソースで開発されておりPythonとRのライブラリが公開されています。今回はTOPIXのデータを使用して、Python版のProphetの使い方を解説します。

Prophetを使ってあなたも予言者に

PorphetとはFacebookが作成した時系列データの予測ツール です。Prophetには、「Forcasting at Scale.」というコピーが掲げられており、このような特徴があります。

  • 分析のエキスパートでなくても、簡単に時系列データの予測ができる
  • 予測モデルの結果も視覚的に把握できる
  • ドメイン知識をもとにモデル調整も直感的にできる

データを用意するだけで精度の高い予測モデルを簡単に作ることができます。また作ったモデルを視覚的に把握することができるので、モデルのチューニングも行いやすいのがメリットです。

ちなみにProphetは予言者という意味になります。

TOPIXのデータを準備する

TOPIXのcsvファイルを取得する

実際のビジネスの現場ではDAUなどKPIの予測に使うことが多いと思いますが、今回はTOPIXのデータを使用して予測モデルを作っていきます。

TOPIXのデータはWall Street Journalのサイトからダウンロードできます。今回は2000年1月1日から2018年3月23日のデータを使用しました。

I0000.JP Stock Price & News - TOPIX Index - Wall Street Journal

期間を指定して「DOWNLOAD A SPREADSHEET」を押します。

f:id:tadaken3:20180324111619p:plain
Wall Street Journalのサイトからデータをダウンロードする

PandasでProphetに取り込むための前処理を行う

今回はGoogle Colaroratory(以下、Colab)を用いて分析をしていきます。

まずは先程、ダウンロードしたCSVファイルをColabに取り込みます。

#CSVファイルの読み込み
from google.colab import files
uploaded = files.upload()

Colabでローカルファイルを取り扱う方法については、こちらの記事を参考にしてください。

tadaken3.hatenablog.jp

続いて、読み込んだデータをデータフレームで扱えるようにします。

# 読み込んだデータをpandasのdataframe扱えるようにする
import io
import pandas as pd
import numpy as np

df = pd.read_csv(io.StringIO(uploaded['HistoricalPrices.csv'].decode('utf-8')))

# 中身を確認する
df.head()

f:id:tadaken3:20180324111914p:plain
データの確認をする

データフレームをProphetにインプットする形に前処理をします。 ここで一つ注意があります。入力に使用するカラム名とデータの中身を以下の形式にする必要があります。

カラム名 備考
ds datetime 時系列情報(タイムスタンプ)
y 数値 実績値

また数字の変動が大きい場合は対数変換(log)をしておくと精度が上がります。 今回は、TOPIXの終値を使って、モデルを作成します。

カラム名やデータの形式をこのように変換します。 データはグラフで確認もしておきましょう。

# prophetでモデルを作成する際は、datetimeをdsカラムに、yに値を入れる。
# inputは必ずこの形式に。
%matplotlib inline
import matplotlib.pyplot as plt

df['ds'] = pd.to_datetime(df['Date']).dt.date #date型に変換
df['y']  = np.log(df[' Close']) #データの変化が大きいため、対数変換をする。
df['y'].plot()

f:id:tadaken3:20180324025829p:plain
TOPIXのデータ

これで準備が整いました。

データをもとに予測モデルを作成する

prophetのインストールとモデルの作成

まずはpipでprophetをインストールします。

!pip install fbprophet

インストールが終わったら、さっそく予測モデルを作成していきましょう。

Prophetではいろいろなパラメータをつかって予測モデルをチューニングすることができるのですが、今回はデフォルト設定で作成します。

from fbprophet import Prophet

#デフォルト設定でモデルを作成する
model = Prophet()
model.fit(df)

これで予測モデルができました。簡単ですね。

モデルをもとに未来予測をしてみる

では、作成したモデルを使って、未来予測をしてみましょう。 予言者の本領発揮です。

#モデルをもとに予測をする
# periodに期間を入れる。この場合365日分の予測値が出力される
future = model.make_future_dataframe(periods=365)
forecast = model.predict(future)
forecast[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].tail()

結果はデータフレームでこのような形で返ってきます。

f:id:tadaken3:20180324113056p:plain
予測モデルの結果

yhatが予測値になります。対数変換しているので、e(約2.6)をyhatの値で乗算するともとに戻せます。 この場合、2019年3月23日の予測値は約7.48なので、実際にTOPIXの値としては、1786.46になります。

数値で見てもいいのですが、Prophetにはビジュアライズの機能もあります。

#予測モデルをグラフで表示
model.plot(forecast);

f:id:tadaken3:20180324025852p:plain
Prophetの予測モデル

黒い点が実際の値、青い濃い線が予測モデルになります。2013年以降上昇トレンドがつついており、2019年も上昇するトレンドが続きそうですね。

予測モデルの構成要素

トレンドや周期性についての分析結果は、model.plot_components()にて見ることができます。

#トレンドや周期性を表示する
model.plot_components(forecast)

f:id:tadaken3:20180324030010p:plain
構成要素のグラフ
上から、トレンド性、年周期性、週周期性のグラフです。 それぞれのグラフから以下のようなことが読み取れます。

  • [トレンド性] 2012年の年末から上昇トレンド。2013年のはじめからにトレンドが緩やかになっている
  • [年周期] 2月から5月にかけては上昇する周期性がある
  • [週周期] 土日が下がっているように見えるが、これは相場閉まっているため。

直感的でわかりやすいですね。

予測モデルの精度を検証する

検証用データの生成

では続いて、この予測モデルがどれくらいの精度があるのか検証していきます。

精度検証をするには、prophetのdiagnosticsクラスを使います。 diagnosticsは日本語で「診断」という意味になります。

#diagnosticsは日本語で診断
from fbprophet import diagnostics

#精度検証をする。horizonに検証したい期間を入力する
cv = diagnostics.cross_validation(model, horizon='365 days')
cv.tail()

f:id:tadaken3:20180324113757p:plain

詳しい説明は省きますが、cross_validationメソッドを使うと、交差検証法という手法で、訓練データとテストデータに分けて、何度か予測値の算出を行ってくれます。cvの中身をを簡単に説明します。yが実績値、yhatが予測値になります。この2つの差がどれくらいあるのかを計算してモデルの精度を検証します。

MAPE(平均絶対誤差率)を使って予測モデルの精度をはかる

今回はMAPE(平均絶対誤差率)という指標を使います。実績値に対して予測値にどれくらい誤差率があるのかという指標になります。

cvのデータをもとに以下のように計算できます。

def cal_mape(df):
    return((df['yhat'] - df['y']).div(df['y']).abs().sum()*(1/len(df)))
 
cal_mape(cv)

f:id:tadaken3:20180324115349p:plain
MAPEの計算。画像では他の指標も算出はしています。

今回モデルで365日の予測を行った場合のMAPEの値は28%でした。MAPEは小さいほど精度が高いということになります。

上記に加えて、100日、150日、200日、250日ごとにMAPEの値を計算するとこのようになります。

f:id:tadaken3:20180324115117p:plain

150日を超えたあたりから予測の精度が低下していますね。 実際はここからモデルを調整して予測の精度を上げていくことになります。

まとめ

Prophetの基本的な使い方を解説しました。 Prophetは簡単に時系列分析ができ、非常に強力なツールですので、ぜひみなさんも試してみてはいかがでしょうか。

今回、実施祭に使用したColabのノートブックはこちらになります。 実際に試してみたい方はぜひ参考にしてみてください。

drive.google.com

参考資料

facebook.github.io

d.hatena.ne.jp

data.gunosy.io

funyakofunyao.click

読者登録をお願いします

本ブログではプログラミングについての記事を公開しています。よろしければ読者登録していただけると更新の励みになります。ぜひ一緒にプログラミングを学びましょう。

免責事項:当ブログのご利用につきましては、全ては自己責任、自己判断でお願いいたします。何らかのトラブルや損失・損害等発生した場合、当ブログでは一切の責任を負いかねます。投資は自己責任で。