Prophetで生成した株価モデルの精度を確認する【Pythonで時系列予測】
以下の記事では,時系列予測ライブラリ『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')
株価と生成モデル及び予測

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

モデルの評価

ディスカッション
コメント一覧
まだ、コメントがありません