Prophetで生成した株価モデルの精度を確認する【Pythonで時系列予測】

4月 7, 2021

以下の記事では,時系列予測ライブラリ『Prophet』によって株価を予測する方法を紹介しました.

この記事では予測だけしてモデルの精度については触れなかったので,今回の記事ではProphetで生成した予測モデルの精度検証を行います.

今回も,基本は公式ドキュメント:https://facebook.github.io/prophet/docs/quick_start.htmlに沿っています.

予測にはモデル検証が必要

予測モデルを作っただけでは,その未来予測がどれくらい良いものなのかを議論できません.

そのため,予測モデルを作ったらそのモデルの精度を検証するひつようがあります.

Prophetでモデル精度を検証する方法

Prophetでは,データに対してCV(交差検証)を実行する関数が用意されており,モデル精度の検証が比較的簡単に行えるようになっています.

まずは,交差検証とは何かについて簡単に説明します.

交差検証(cross validation)とは

まず,所持しているデータの一部をテスト(モデル精度の検証)データとして取っておき,残りのデータだけで訓練(モデルの調整)を行った後,残しておいたテストデータでモデルを評価します.

所持データから選ぶテストデータをずらすことで,異なる訓練→テストを再度行うことができます.これを繰り返す方法が交差検証です.

交差検証のメリットとしては,所持しているデータがある程度少なくても,訓練→テストを繰り返し行うため精度の高いモデルの検証を行えることです.

Prophetで交差検証

※ProphetはRとPyhonで動かせますが,この記事ではPythonを用います.また,今回もGoogle Colabで実行しているため,ライブラリのインストールなどは必要ありませんでした(もしインポートエラーが出たら随時インストールしてください).

Prophetでは,Cutoffでテストデータの始点を決め,Horizonでテストデータの期間(予測の期間)を決めます.

Pythonでは,Prophetで生成したモデルをmodelとして,以下のように書くことで交差検証を行うことができます(モデルを生成するところまでは,以前の記事をご覧ください).

Python(Prophet)による交差検証

from fbprophet.diagnostics import cross_validation
df_cv = cross_validation(model, initial='730 days', period='180 days', horizon = '365 days')

initialは訓練データの始点です.また,periodはcutoffを置く間隔のことです.

つまり,この場合は1回目の検証を730日目から365日間をテストデータとして扱い,その他のデータで訓練します.2回目の検証はテストデータを180日ずらす,つまり910日目から365日間をテストデータとして扱います.

今回はKO(コカ・コーラ)の2015/1/1~2021/1/1のデータを使います.

上のコードで,以下のようなデータフレームが生成されます(モデルの検証にはそこそこ時間がかかります).

df_cv.head()
	        ds	     yhat	yhat_lower	yhat_upper	        y	    cutoff
0	2017-01-17	35.257939	34.590674	35.915345	35.827503	2017-01-16
1	2017-01-18	35.198549	34.510758	35.852737	35.888344	2017-01-16
2	2017-01-19	35.208567	34.475215	35.820755	35.757969	2017-01-16
3	2017-01-20	35.149224	34.509085	35.867979	35.914421	2017-01-16
4	2017-01-23	35.107440	34.411316	35.727057	36.010033	2017-01-16

cutoffのカラムは予測した期間の始め,dsのカラムは予測した日付,yは実際の値,yhatはテストデータで予測した値です.

このyとyhatを各々比較することで,実際の値とモデルの予測値の差を評価します.この比較に関しても,Prophetでは簡単にできるようになっています.

Python(Prophet)による評価値計算

from fbprophet.diagnostics import performance_metrics
df_p = performance_metrics(df_cv)

これによって,以下のようなMSE, RMSE, MAE, MAPE, COVERAGEという評価値が得られます.

df_p.head()
	horizon	     mse	    rmse	     mae	    mape	   mdape	coverage
0	36 days	2.808751	1.675933	1.362703	0.030136	0.027425	0.295455
1	37 days	2.963502	1.721482	1.386926	0.030546	0.027752	0.301136
2	38 days	3.017357	1.737054	1.396027	0.030719	0.027851	0.312500
3	39 days	3.026252	1.739613	1.393249	0.030631	0.027752	0.319318
4	40 days	3.227508	1.796527	1.427295	0.031237	0.027895	0.323864

MSEは平均二乗誤差,RMSEはMSEの平方根をとったもの,MAEは平均絶対誤差,MAPEは平均絶対パーセント誤差,そしてCOVERAGEはyhat_lowerからyhat_upperの範囲です.

さらに,Prophetではこの評価値を可視化する関数まで用意されています.

MSEとかを見ても分かりにくいので,今回はMAPE(平均絶対パーセント誤差)を可視化してみます.

Python(Prophet)による評価値(MAPE)の可視化

from fbprophet.plot import plot_cross_validation_metric
fig = plot_cross_validation_metric(df_cv, metric='mape')

横軸はHorizon,すなわち予測値の範囲です.青い線がMAPEです.

予測が未来になるほどMAPEが増加していることが分かります.36日後ではMAPEは約3%であるのに対し,1年後の予測値は約13%くらいになります.

「このモデルの予測が実際の株価にどれだけ近いか」は,以下の記事をご覧ください.

Prophetで株価の予測結果はどれくらい当たっているのか見てみた

コードまとめ

データ取得及びモデルの生成を含めたコードのまとめです.データの取得及びモデルの生成は,以前の記事などをご覧ください.

import matplotlib.pyplot as plt
from fbprophet import Prophet
import pandas_datareader.data as web
import datetime

start = datetime.date(2015,1,1)
end = datetime.date(2021,1,1)

data = web.DataReader('KO', 'yahoo', start, end) #データの取得

#Prophetのためにデータを加工
data['ds'] = data.index
data = data.rename({'Adj Close':'y'},axis=1)

#モデルの生成
model = Prophet()
model.fit(data)

#未来予測
future_data = model.make_future_dataframe(periods=250, freq = 'd')
forecast_data = model.predict(future_data)

#株価データと予測のプロット
fig = model.plot(forecast_data)
model.plot_components(forecast_data)

#交差検証
from fbprophet.diagnostics import cross_validation
df_cv = cross_validation(model, initial='730 days', period='180 days', horizon = '365 days')

#評価値計算
from fbprophet.diagnostics import performance_metrics
df_p = performance_metrics(df_cv)

#評価値描画
from fbprophet.plot import plot_cross_validation_metric
fig = plot_cross_validation_metric(df_cv, metric='mape')

株価と生成モデル及び予測

トレンド,週単位の周期,年単位の周期

モデルの評価