日経平均株価の予測(学習の成果)

はじめに

機械学習のアルゴリズムの1つ「線形重回帰」を使用して、日経平均株価の終値を予測するモデルを、Colaboratory上で作成してみました。作成の流れは以下です。
  1)株価データの取得
  2)株価データの編集
  3)学習用とテスト用にデータの分割
  4)学習用モデルの作成と予測
  5)グラフ表示
  6)考察
  7)ご参考(ソースコード)

1)株価データの取得

pandas_datareaderを使用して、日経平均株価のデータを4年分(2018-2021)取得します。取得したデータは、、インデックスに日付(Date)、列に高値(High)、安値(Low)、始値(Open)、終値(Close)、出来高(Volume)の構成にとなっています。

2)株価データの編集

上記1)で取得したデータに、株価のテクニカル情報として良く使われる移動平均価格を説明変数(X)として、また、株価の終値を予測するために翌日の終値を目的変数(y)として、列に追加しました。
 説明変数(X):(新規追加)5日/25日/75日移動平均価格(追加) +
                              (既存) 高値/安値/始値/終値/出来高
 目的変数(y):翌日の終値

3)学習用とテスト用にデータの分割

上記2)で編集したデータを、以下のように分割しました。
 学習用 :3年分(2018/01/01 - 2020/12/31)
 テスト用:1年分(2021/01/01 - 2021/12/31)
分割したデータより、学習で使用する説明変数(X)と目的変数(y)のデータを設定しました。

4)学習モデルの作成と予測

scikit-learnのLinearRegressionを使用して、学習モデル(線形重回帰モデル)の作成を行いました。作成したモデルに学習用の説明変数(X)と目的変数(y)を与えて学習させました。予測には学習させたモデルにテスト用の説明変数(X)を与えて行いました。

5)グラフ表示

予測された株価と実際の株価をMatplotlib.pyplotを使用してグラフ化してみました。赤色が実際の株価で青色が予測された株価となっています。

予測結果

6)考察

上記5)で作成したグラフを参照してみると、良い感じで予測されている事が分かりました。実際の株価の終値と予測された終値の誤差は約352円と、学習した3年間のデータの値幅の約11,000円(最大27,568円-最小16,552円)に対して約3%の誤差なので、個人的には悪くない結果となっています。
追加で説明変数(X)を終値だけ使用した線形単回帰モデルで同様に実施したところ、誤差は約338円となりました。説明変数(X)が多くなればなるほど誤差は少なくなるのかなと思っていましたが、大きくは外れていないので今回のモデルで個人的には及第点を与えたいと思います。

7)ご参考(ソースコード)

import pandas_datareader.data as data
from datetime import datetime
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error as mse

# 取得する株価コードと期間を設定
stock = "^NKX"
start = datetime(2018, 1, 1)
end = datetime(2021, 12, 31) #end  = datetime.today()
MA_5 = 5
MA_25 = 25
MA_75 = 75

def edit_stock_value(stock_value):
 # 5/10/15日の移動平均価格の設定
 stock_value["MA_5"] = stock_value["Close"].rolling(MA_5).mean()
 stock_value["MA_25"] = stock_value["Close"].rolling(MA_25).mean()
 stock_value["MA_75"] = stock_value["Close"].rolling(MA_75).mean()
 # 翌日の終値を設定(目的変数として使用)
 stock_value["Close_Tomorrow"] = stock_value["Close"].shift(-1)
 # 欠損値の行を削除
 stock_value = stock_value.dropna(how="any")
 return stock_value

# 1)株価データの取得
stock_value = data.DataReader(stock, "stooq", start, end)
stock_value = stock_value[::-1]

# 2)株価データの編集
stock_value_edit = edit_stock_value(stock_value)

# 3)学習用とテスト用にデータ分割
train = stock_value_edit["2018-01-01" : "2020-12-31"]
test = stock_value_edit["2021-01-01" :]

X_train = train.drop("Close_Tomorrow", axis=1)
y_train = train["Close_Tomorrow"]

X_test = test.drop("Close_Tomorrow", axis=1)
y_test = test["Close_Tomorrow"]

# 4)学習用モデルの作成と予測
model = LinearRegression()
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
score = np.sqrt(mse(y_test, y_pred))
print("RMSE(線形重回帰):", score)

# 5)グラフ表示
plt.figure(figsize=(12, 8))
plt.xlabel("Date")
plt.ylabel("Stock_Value")
plt.plot(df_result["Close_Tomorrow"], label="Close_Tomorrow", color="r")
plt.plot(df_result["Close_pred"], label="Close_pred", color="b")
plt.show()

# 説明変数を終値だけで実行(線形単回帰)
X_train = train[["Close"]]
y_train = train["Close_Tomorrow"]
X_test = test[["Close"]]
y_test = test["Close_Tomorrow"]
model = LinearRegression()
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
score = np.sqrt(mse(y_test, y_pred))
print("RMSE(線形単回帰):", score)

この記事が気に入ったらサポートをしてみませんか?