こんな悩みにお答えします。
1. Aidemy
・・・AIエンジニアとしてのスキルを身に付けたい。その延長で就職、転職できたら嬉しい方におすすめ。
2.侍エンジニア塾
・・・基礎力と即戦力を身に付けられる、満足度No.1スクール
3. TechAcademy
・・・副業に向けてスキルアップしたい。フリーランスなどを目指している方向け。
4. AIジョブカレッジ
・・・コスパ良く、質の高い講座を受けたい方におすすめ。
本記事の信頼性
現在はデータサイエンティストとして大企業で活動しています。
1. 結論:
Prophetでは通常、学習データを基にトレンドの変化点を自動で推測しモデル化します。しかし実際には、データに表れていない変化点(外部影響)も存在します。
今回は、株価に影響を与える会合(FOMC)の日程を変化点として指定しました。
その結果、すべての実験で精度の改善が見られました(※RMSLE:評価指標のひとつ)。
- S&P500
- RMSLE:0.07832 ⇒ 0.03189
- NASDAQ総合
- RMSLE:0.09538 ⇒ 0.04560
- NYダウ
- RMSLE:0.06629 ⇒ 0.02152
ここから具体的な取り組み内容についてご説明します。
2.
今回は、Prophetのパラメータである「changepoint」を利用します。「changepoint」はその名のとおり、「トレンドの変化点」を表します。
Prophetでは時系列データを3つの項の和として回帰モデルを構築しています。「changepoint」はこの中のトレンド項に影響を与えます。
$$y(t)=g(t)+s(t)+h(t)+\varepsilon_t$$
通常、データから自動的に変化点を探すことになりますが、この変化点は「changepoint」として指定してあげることができるのです。
#例
m = Prophet(changepoints=["2022-05-01"])
今回は株価の動きに影響を与えているFOMCの開催日程を「changepoint」に入力します。
3. FOMC
FOMCとは、Federal Open Market Committee(連邦公開市場委員会)の略で、米国の金融政策を決定する会合のことです。
FOMCは年に8回開催され、現在の景況判断と政策金利(FF金利)の上げ下げなどの方針が発表されます。その結果が市場の予想とは違った場合には、株式市場や為替レートが大きく変動することがあり、世界の金融マーケットにも大きな影響を及ぼします。(引用:SMBC日興証券)
直近3年間のFOMCの日程は以下のとおりです(参考:時事エクイティ)。
2020年 | 2021年 | 2022年 |
1月28日~29日 | 1月26日~27日 | 1月25日~26日 |
3月17日~18日 | 3月16日~17日 | 3月15日~16日 |
4月28日~29日 | 4月27日~28日 | 5月3日~4日 |
6月9日~10日 | 6月15日~16日 | 6月14日~15日 |
7月28日~29日 | 7月27日~28日 | 7月26日~27日 |
9月15日~16日 | 9月21日~22日 | 9月20日~21日 |
11月4日~5日 | 11月2日~3日 | 11月1日~2日 |
12月15日~16日 | 12月14日~15日 | 12月13日~14日 |
特にここ最近は政策金利の引き上げについて、いつどの程度の利上げが行われるのか、いつまで続くのか、などが焦点に当てられ、FOMC後に株価が大きく変動する傾向にあります。
今回は、上記のとおり直近3年間のFOMCの日程を用いた株価予測を行っていきます。また、変化点としてはFOMCの翌日を指定します。
4. FOMCの日程を考慮した株価予測
ここから、Prophetを用いて実際に株価予測を行います。Prophetを用いた株価予測方法の詳細は以下の記事をご覧ください。
a. 実験設定
a-1. 対象期間
期間 | 2016/1/1~2022/4/30(取得期間) 2016/1/1~2022/3/31(学習) 2022/4/1~2022/5/31(予測) 2022/4/1~2022/4/30(テスト) |
2022年3月までのデータを基にモデルの学習を行い、4~5月の株価を予測します。予測結果が正しいかの確認を4月分の実データと比較していきます。
a-1.
FOMCの日程を考慮するため、米国市場の主要指標を対象とします。
対象 | コード |
S&P500 | ^GSPC |
NASDAQ総合 | |
NYダウ | ^DJI |
a-2.
予測対象は以下の2値とします。
- 株価
- 株価の対数
対数を取ることで外れ値の影響を抑制することができるため、特定時期における株価の急変に左右されない予測を行うことができます。
a-3. モデル
Prophetのパラメータ「changepoint」を利用するため、モデルはProphetのみとします。
a-4. 比較手法
比較手法は以下のとおりです。
項番 | 手法 |
① | 株価 |
② | 株価の対数 |
③ | 株価の対数(FOMCの日程を考慮) |
前回のProphetの予測結果から、①株価よりも②株価の対数の方が精度が高かったことから、株価の対数のみFOMCの日程を考慮します。
a-5. 評価指標
評価には、以下2つの指標を用います。
項番 | 評価指標 |
1 | RMSLE (Root Mean Squared Logarithmic Error) |
2 | Prophetの予測範囲の中に実測値が含まれているデータ数 |
RMSLEの評価式は以下のとおりです。
$$RMSLE=\sqrt{\frac{1}{n}\sum_{i=1}^{n}{(\log(y_i+1)-\log(\hat{y}_i+1))^2}}$$
b. 予測結果
予測結果を、評価指標と可視化の2つの方法で比較します。
b-1. 評価結果
各手法における評価結果は以下のとおりです。
対象 | 手法 | RMSLE | 予測範囲内のデータ数 (予測データ数:21) |
S&P500 | ①株価 | 0.09040 | 2(9.5%) |
②株価の対数 | 0.07832 | 6(28.6%) | |
③株価の対数 (FOMCの日程を考慮) | 0.03189 | 19(90.5%) | |
NASDAQ総合 | ①株価 | 0.1349 | 1(4.8%) |
②株価の対数 | 0.09538 | 6(28.6%) | |
③株価の対数 (FOMCの日程を考慮) | 0.04560 | 17(81.0%) | |
NYダウ | ①株価 | 0.07051 | 0(0.0%) |
②株価の対数 | 0.06629 | 4(19.0%) | |
③株価の対数 (FOMCの日程を考慮) | 0.02152 | 21(100%) |
FOMCの日程を考慮することで、全ての対象で精度改善が確認されました。
特に顕著だったのはNYダウで、①株価では実際の株価が予測範囲に1つも入っていなかったにも関わらず、③株価の対数(FOMCの日程を考慮)では全ての実測値が予測範囲に入っています。
この結果より、ある程度の銘柄数の株価によって成り立っている指標であれば、FOMC後に株価が変動することが多く、変化点として上手く機能することが確認できます。
個別銘柄に対して同じように上手く予測できるかと言われると、FOMCが影響していない場合も多いでしょうからね。
b-2. 可視化結果
ここでは、特に改善度合いの大きかったNYダウについて可視化結果を確認します。
以下、青:予測結果、赤:実測値、黒点:学習データ です(したがって、実際の予測値は直近20日分程度となります)。
■NYダウ ①株価
■NYダウ ②株価の対数
■NYダウ ③株価の対数(FOMCの日程を考慮)
上3図を確認すると、①と②は上昇予測にも関わらず、③のみ唯一下降予測できていることが分かります。
また、②については学習データを追従していることから過学習の懸念があります。パラメータ等を調整することで精度改善が期待できるかもしれません。
上記以外の可視化結果は以下のリンクを参照ください。
対象 | 手法 |
S&P500 | ①株価 |
②株価の対数 | |
③株価の対数(FOMCの日程を考慮) | |
NASDAQ総合 | ①株価 |
②株価の対数 | |
③株価の対数(FOMCの日程を考慮) | |
NYダウ | ①株価 |
②株価の対数 | |
③株価の対数(FOMCの日程を考慮) |
c. 考察
予測結果と評価を踏まえた考察です。
c-1. FOMCの日程を考慮することで主要3指標の予測精度向上に繋がった理由
FOMCは米国市場全体に影響を及ぼすことが多く、複数企業の株価を元に作成される指標に対しては特に上手く働いたためと考えられます。
一方で、特定のセクターや個別銘柄に対しての予測を考えると、関係のないFOMCも多いことが予想され、十分な精度改善には繋がらないでしょう。
c-2. 期間によって変わる(一時的な調整局面の影響を受ける)
今回の実験では、特定の一期間を用いました。しかし、本来は
c-3. パラメータチューニング
可視化結果を見ると、②株価の対数の予測では学習データに対して過学習を起こしている可能性があります。
Prophetのパラメータはデフォルトを使用しているため、チューニングを実施することで精度改善に繋がると思われます。
5. サンプルコード
今回用いたプログラムのサンプルコードを記載いたします。
import pandas as pd
import pandas_datareader.data as web
import matplotlib.pyplot as plt
import numpy as np
from fbprophet import Prophet
from sklearn.metrics import mean_squared_log_error
################################################################
st = '2016/01/01'
ed = '2022/05/01'
st_train = '2016/01/01'
ed_train = '2022/03/31'
st_test = ed_train
ed_test = '2022/04/30'
period = 61 #予測日数
y_type =1 #0:オリジナルの株価、1:対数株価
changepoint_flag = 0 #0:changepointを考慮しない、1:FOMCの翌日
fomc_list = ['2020-01-30','2020-03-19','2020-04-30','2020-06-11',
'2020-07-30','2020-09-17','2020-11-06','2020-12-17',
'2021-01-28','2021-03-18', '2021-04-29','2021-06-17',
'2021-07-29','2021-09-23','2021-11-04','2021-12-16',
'2022-01-27','2022-03-17']
################################################################
main_target = '^IXIC' #'^DJI' #'^GSPC'
lst1= ['^IXIC']
stooq = web.DataReader(lst1, 'yahoo',start=st,end=ed)
df = stooq[st_train:ed_train]
#①株価 or ②③株価の対数
if y_type == 1:
df = df.dropna(how='any')
df['Adj Close'] = np.log(df['Adj Close'])
df = df.reset_index()
df[['ds','y']] = df[['Date' ,'Adj Close']]
df = df[['ds','y']]
else:
df = df.reset_index()
df[['ds','y']] = df[['Date' ,'Adj Close']]
df = df[['ds','y']]
df_actual = stooq[st_test:ed_test]
if y_type == 1:
df_actual = df_actual.dropna(how='any')
df_actual['Adj Close'] = np.log(df_actual['Adj Close'])
df_actual = df_actual.reset_index()
df_actual[['ds','y']] = df_actual[['Date' ,'Adj Close']]
df_actual = df_actual[['ds','y']]
if y_type == 1:
stooq = stooq.dropna(how='any')
stooq['Adj Close'] = np.log(stooq['Adj Close'])
stooq = stooq.reset_index()
stooq[['ds','y']] = stooq[['Date' ,'Adj Close']]
stooq = stooq[['ds','y']]
#FOMC日程考慮
if changepoint_flag==0:
m = Prophet(weekly_seasonality=True)
elif changepoint_flag==1:
m = Prophet(weekly_seasonality=True,changepoints=fomc_list)
#モデル学習+予測
m.fit(df)
future = m.make_future_dataframe(periods=period)
forecast = m.predict(future)
plt.rcParams["font.size"] = "25"
fig, ax = plt.subplots(figsize=(20,10))
pd.plotting.register_matplotlib_converters()
m.plot(forecast,ax=ax);
ax.plot(stooq["ds"],stooq["y"],color="r")
plt.rcParams["font.size"] = "13.3"
ax.set_title(str(main_target))
m.plot_components(forecast);
stooq.columns = stooq.columns.droplevel(1)
ans = pd.merge(forecast, stooq, on="ds", how='inner')
ans.set_index("ds",inplace=True)
y_pred = ans[st_test:ed_test]["yhat"]
y_true = ans[st_test:ed_test]["y"]
if y_type == 1:
y_pred = np.exp(y_pred)
y_true = np.exp(y_true)
#評価指標1:RMSLE
RMSLE=np.sqrt(mean_squared_log_error (y_true, y_pred))
print("RMSLE:",RMSLE)
y_pred_lower = ans[st_test:ed_test]["yhat_lower"]
y_pred_upper = ans[st_test:ed_test]["yhat_upper"]
ans_judge = ans[st_test:ed_test].copy()
if y_type == 1:
y_pred_lower = np.exp(y_pred_lower)
y_pred_upper = np.exp(y_pred_upper)
#評価指標2
cnt = 0
for i in ans_judge.index:
if y_pred_lower[str(i)] <= y_true[str(i)] <= y_pred_upper[str(i)]:
cnt += 1
print("予測数:",len(ans_judge.index),"範囲内:",cnt)
6. まとめ
今回は、
- Prophetを用いた株価予測方法
- Prophetにデータの変化点を指定する方法
Prophetのパラメータ「changepoint」にFOMCの日程を入力することで、米国主要3指標の株価を精度高く予測することができました。
一方で、複数期間や複数銘柄での実験を行えていないため、今後も検証が必要です。
まずは、機械学習モデルの改善アプローチとして、参考いただければと思います。
・【株式投資】Pythonでスクリーニングする方法
・【Python】【株式投資】TA-Libによるテクニカル指標算出方法(移動平均、ボリンジャーバンド、MACD、RSI)
・【初心者向け】20分でできる!Pythonで銘柄スクリーニング結果をスマホへ通知する方法
・【Python】銘柄スクリーニング結果を定期的に通知する方法(無料)【30分でできる!】
本ブログでは、株式やプログラミングに関する記事を投稿しています。
プログラミング(Python)を学びたい方におすすめの書籍やプログラミングスクール、おすすめの学習方法などをご紹介しておりますのでぜひご覧ください。
は、プログラミングスクールという方法がおすすめです。
私の一押しは『TechAcademy』です。
質問することですぐに分からないところをクリアにできますし、進捗をサポートしてくれるため確実に成長することができます。
無料相談を実施しているため、まずは話を聞いてあなたのスタイルに合っているかどうか確認してみるのが良いと思います。
コメント