0
0

機械学習で株価分析 11.目的変数の作成

Last updated at Posted at 2023-12-19

はじめに

本記事では、目的変数を作成する方法を紹介します。紹介内容はあくまで一例で、本気で株価予測を行う際は自身で様々な目的変数を試行錯誤する必要があります。なお、本記事は過去の記事 10.説明変数の作成 の続きですので、未読の方はまずこちらをご参照ください。

なお、本記事は機械学習による株価予測において非常に注意を要する内容を含んでいます。自身で機械学習手法を構築した際に、予測精度が高すぎる等の現象が生じた場合、本記事を今一度確認いただければ幸いです。

概要

設計した説明変数に対し、以下のプログラムを実行することで目的変数を作成できます。今回は簡単のために、「ある日の終値に対し翌日の終値が一定以上上昇するか否か」を示すフラグを目的変数としました。

プログラムは以下の手順で実行されます。

  1. 目的値の二値化のために株価高騰判定関数を作成
  2. 目的変数作成のために翌日の株価の変動率データを追加
  3. 目的変数として翌日の株価の変動率を二値化
  4. 説明変数から未来指標を削除

特に手順3と手順4が重要な意味を持ちますので、以下で詳しく説明します。

手順3では、目的変数として翌日の株価の変動率を二値化しています。これは 04.機械学習の基礎 でも述べたとおり、目的変数は簡潔なほうが予測の精度が上がるためです。例えば、単純に翌日の株価の変動率そのものを予測した場合、その適合率は変動率を二値化した場合と比較して大きく劣ってしまいます。

手順4では、説明変数から未来指標を削除しています。これを忘れると、未来を予測するために未来のデータを使用することとなり、当然予測精度は無意味に向上してしまいます。説明変数に未来指標が含まれていないかの確認は、単純ながら非常に重要な作業です。

確認のために、実際の翌日の騰落率と、関数で算出された株価の高騰フラグをそれぞれ表示するようにしています。見比べて間違いがないことを確認してみてください。

# 株価高騰判定関数
rate_rise =  0.01
def func_flg_rise(data):
  if data["Return 1d_After"] > rate_rise :
    return  1
  else:
    return  0

# 目的変数作成のために翌日の株価の変動率データを追加
df_merge["Return 1d_After"] = df_merge.shift(-1)["Return"]

# 目的変数として翌日の株価の変動率を二値化
df_merge["flg_rise"] = df_merge.apply(func_flg_rise, axis=1)

# 説明変数から未来指標を削除
df_merge = df_merge.drop(["Return 1d_After"], axis=1)

# 結果の確認
display(df_merge["flg_rise"], df_merge.shift(-1)["Return"])

ソースコード全文

以下にソースコード全文を示します。

!pip install yfinance

# 必要なライブラリをインポート
import yfinance as yf
yf.pdr_override()
import numpy  as np
import pandas as pd
from   pandas_datareader       import data
import datetime
from   IPython.display         import display

# 株価データの取得 ----------------------------------------------------------

# データの取得開始日・取得終了日を設定
day_start = datetime.date(2021,1,1)
day_end   = datetime.date.today() + datetime.timedelta(days=1)

# 銘柄名を変数に格納
stock_name  = ["4689.T"]

# 株価データを読み込み
df_stock = data.DataReader(stock_name, day_start, day_end, interval="1d")

# 取得する経済指標を設定
fred_name = ["^N225"]

# 経済指標データ取得
df_fred = data.DataReader(fred_name, day_start, day_end, interval="1d")

# 経済指標データの列名を編集
for i in range(len(fred_name)):
  df_fred = df_fred.add_prefix(fred_name[i] + " ")

# 株価データに経済指標データを統合
df_merge = pd.concat([df_stock, df_fred], axis=1)

# データのブランクを穴埋め
df_merge = df_merge.fillna(method='ffill')
df_merge = df_merge.fillna(0)


# 機械学習の試行 ----------------------------------------------------------

# 説明変数に株価に関する情報を追加
df_merge['Body']        = df_merge['Open']  - df_merge['Close']
df_merge['Body Ratio']  = df_merge['Body']  / df_merge['Close']
df_merge['Range']       = df_merge['High']  - df_merge['Low']
df_merge['Range Ratio'] = df_merge['Range'] / df_merge['Close']
df_merge['Gap']         = df_merge['Open']  - df_merge.shift(1)['Close']
df_merge['Gap Ratio']   = df_merge['Gap']   / df_merge.shift(1)['Close']
df_merge["Return"]      = df_merge.pct_change()["Adj Close"]

# 説明変数に各種移動平均と移動平均乖離率を追加
for dd in [5,10,15,20,25,30]:
  df_merge["Close " + str(dd) + "days Average"]  = df_merge["Close"].rolling(dd).mean()
  df_merge["Close " + str(dd) + "days Diverge"]  = (df_merge["Close"] - df_merge["Close " + str(dd) + "days Average"]) / df_merge["Close " + str(dd) + "days Average"]
  df_merge["Volume " + str(dd) + "days Average"] = df_merge["Volume"].rolling(dd).mean()
  df_merge["Volume " + str(dd) + "days Diverge"] = (df_merge["Volume"] - df_merge["Volume " + str(dd) + "days Average"]) / df_merge["Volume " + str(dd) + "days Average"]

# 株価高騰判定関数
rate_rise =  0.01
def func_flg_rise(data):
  if data["Return 1d_After"] > rate_rise :
    return  1
  else:
    return  0

# 目的変数作成のために翌日の株価の変動率データを追加
df_merge["Return 1d_After"] = df_merge.shift(-1)["Return"]

# 目的変数として翌日の株価の変動率を二値化
df_merge["flg_rise"] = df_merge.apply(func_flg_rise, axis=1)

# 説明変数から未来指標を削除
df_merge = df_merge.drop(["Return 1d_After"], axis=1)

# 結果の確認
display(df_merge["flg_rise"], df_merge.shift(-1)["Return"])

プログラムを実行し、設計したフラグと翌日の騰落率が表示されれば成功です。

目次へのリンク

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0