Deep Learningを使った株価予想用の入力データをサックと作る

2022年8月6日土曜日

Python備忘録

t f B! P L

2022年10月10日 更新履歴

人口知能を使って株価予測プログラミング

しょーた、ディープラーニングを使って株価予想のプログラムを作ってみよう!

3年前に競艇の予想するプログラム作ったことある。A4用紙1枚程度のコードで予想できたことに驚いた!

頭のいい人達が誰でも使える様にライブラリを整えてくれているからね。

頭の悪いオイラは、なんの疑問も持たずにひたすら使い倒すのみ(^^♪

それじゃー、行ってみよう!Here we go~!

「頭の悪い」って所はスルーかい!

今回の記事のターゲットは、前回の記事の続きとし、株価データの読出しとそのテクニカル分析を使って、人工知能を利用して「明日の株価は上がるか?下がるか?」を予測させるための入力データを作成する部分をまとめます。

  • 株価データを呼び出して、テクニカル分析を実施
  • 人口知能の学習用の入力データを高速演算ライブラリNumpyへ変換
  • 人口知能の学習用の出力データをNumpyで作る

というステップで進めます。

株価データを呼び出して、テクニカル分析を実施

まず、IBMの株価のデータを2000年1月から今日までのデータ、約22年間分のデータを読み出します。Indexが日付になっていると、「前日」とか「2日後」といった演算も手間ひま掛かるので、新たなDataFrameを用意して、日付をColumeへ退避させておきます。


import pandas_datareader.data as data
import pandas as pd
import datetime

st = '2000-01-01' 
ed = datetime.datetime.now()
us_stock = data.DataReader('IBM','yahoo',st,ed)

df = pd.DataFrame(index=[])

df['Date'] = us_stock.index
df['終値'] = us_stock['Adj Close']
df['出来高'] = us_stock['Volume']
df['MA5'] = df['終値'].rolling(window=5).mean()
df['ShortEMA'] = df['終値'].ewm(span=8, adjust=False).mean()
df['LongEMA'] = df['終値'].ewm(span=18, adjust=False).mean()
df['MACD'] = df['ShortEMA'] - df['LongEMA']
df['Signal'] = df['MACD'].ewm(span=6,adjust=False).mean()
    

5日移動平均とMACDのテクニカル分析も完了してます。df(DataFrame)は、以下の通りです。


  Date  終値  出来高 MA5 ShortEMA  LongEMA MACD  Signal
0 1999-12-31  61.040012 3002334.0 NaN 61.040012 61.040012 0.000000  0.000000
1 2000-01-03  65.637451 10823694.0  NaN 62.061665 61.523953 0.537712  0.153632
2 2000-01-04  63.409492 8606279.0 NaN 62.361183 61.722431 0.638751  0.292238
3 2000-01-05  65.637451 13318927.0  NaN 63.089242 62.134538 0.954704  0.481514
4 2000-01-06  64.505783 8338607.0 64.046038 63.404029 62.384143 1.019886  0.635334
... ... ... ... ... ... ... ... ...
5676  2022-07-25  128.539993  4702400.0 128.799998  131.574097  134.685374  -3.111277 -2.098017
5677  2022-07-26  128.080002  3645300.0 128.239998  130.797631  133.990071  -3.192440 -2.410709
5678  2022-07-27  129.119995  4175600.0 128.227998  130.424823  133.477432  -3.052609 -2.594109
5679  2022-07-28  129.220001  3913700.0 128.641998  130.157085  133.029281  -2.872196 -2.673562
5680  2022-07-29  130.789993  5551814.0 129.149997  130.297731  132.793567  -2.495835 -2.622783
5681 rows × 8 columns
    

1999-12-31から2000-01-06までの5日移動平均MA5が「NaN」となっているので、人口知能へ入力する前に、1999-12-31から2000-01-06の全てのデータを削り落とし、Indexを再度つけ直します。


df = df.iloc[4:,]
df = df.reset_index(drop=True)
    

すると、5681行から4行減って、5677行になり、「NaN」はなくなりました。


  Date  終値  出来高 MA5 ShortEMA  LongEMA MACD  Signal
0 2000-01-06  64.505783 8338607.0 64.046038 63.404029 62.384143 1.019886  0.635334
1 2000-01-07  64.222878 12402108.0  64.682611 63.585995 62.577694 1.008301  0.741896
2 2000-01-10  66.769127 8933363.0 64.908946 64.293358 63.018898 1.274460  0.894057
3 2000-01-11  67.334976 8235472.0 65.694043 64.969273 63.473222 1.496051  1.066056
4 2000-01-12  67.617889 7116775.0 66.090131 65.557855 63.909502 1.648352  1.232426
... ... ... ... ... ... ... ... ...
5672  2022-07-25  128.539993  4702400.0 128.799998  131.574097  134.685374  -3.111277 -2.098017
5673  2022-07-26  128.080002  3645300.0 128.239998  130.797631  133.990071  -3.192440 -2.410709
5674  2022-07-27  129.119995  4175600.0 128.227998  130.424823  133.477432  -3.052609 -2.594109
5675  2022-07-28  129.220001  3913700.0 128.641998  130.157085  133.029281  -2.872196 -2.673562
5676  2022-07-29  130.789993  5551814.0 129.149997  130.297731  132.793567  -2.495835 -2.622783
5677 rows × 8 columns
    

人口知能の学習用の入力データを高速演算ライブラリNumpyへ変換

予測の精度を上げるために入力データを正規化する

上のデータは、python上のEXCELと呼ばれる演算処理の得意なDataFrameになります。人工知能を使う場合は、高速な処理が求められることからDataFrameをそのまま入力されることはなく、数値計算ライブラリであるNumpyへの変換が必要となります。

Numpyへ変換する前に、数字のバラつきを 0~1.0 あるいは -1.0~1.0 の中へ整えます。これを正規化と言います。 正規化すると人口知能が数字の特徴を掴む精度が上がるんです。正規化せずとも人工知能へ入力できるので比べて見て下さい。

今回、人口知能への入力は、出来高と5移動平均とMACD,Signalの4種類だけとします。なので4種類だけ正規化します。


def minmax_norm(df):
    return (df - df.min()) / ( df.max() - df.min())

df['normalize_Volume'] = minmax_norm(df['出来高'])
df['normalize_MA5'] = minmax_norm(df['MA5'])
df['normalize_MACD'] = minmax_norm(df['MACD']) 
df['normalize_Signal'] = minmax_norm(df['Signal']) 
    

DataFrameから高速演算が得意なNumpyへ

いよいよDataFrameからNumpyへの変換を行います。


training_in = df[['normalize_Volume',"normalize_MA5","normalize_MACD","normalize_Signal"]].values
    

3年前はmatrixという関数を使っていたんですが、今はvalueを使って変換します。こんな感じで関数とかも時々変更があるのでGoogleなしでは挫折しますよね。


array([[ 0.19345843,  0.44854119,  0.23296129,  0.16159802],
       [ 0.28773299,  0.45299938,  0.23031513,  0.18870219],
       [ 0.20725697,  0.4545845 ,  0.29111092,  0.22740456],
       ...,
       [ 0.0968753 ,  0.8980343 , -0.69727371, -0.65981464],
       [ 0.09079913,  0.90093371, -0.6560641 , -0.68002374],
       [ 0.12880391,  0.90449144, -0.57009615, -0.66710801]])
    

これが人工知能の学習用の入力データになります。

人口知能の学習用の出力データをNumpyで作る

これから作るのは、「株価は上がる!」と予測するための出力データです。

  • 翌日の終値で株を購入
  • 2日後の終値で株を売却
  • この時、1%以上の利益を出た時を「株が上がった」と定義する。

つまり2日後の株価を予想する事になります。

  • [1,0] → 2日後株価が1%以上上がる!
  • [0,1] → 上記以外

training_in と同じサイズで taining_out の空numpyを用意します。


import numpy as np
training_out = np.empty((len(training_in),2))
    

と、入力データと同じサイズの空Numpyデータを用意します。

この空のNumpyに株価が1%を超えて上がった時の目印となる[1,0]。それ以外は[0,1]とします。


for index,row in df.iloc[:-2].iterrows():
    rate_of_up = (df.loc[index+2,'終値'] - df.loc[index+1,'終値']) * 100 / df.loc[index+1,'終値']
    if rate_of_up > 1 :
        training_out[index] = [1,0]
    else :
        training_out[index] = [0,1]
    

df.iloc[:-2]と、2日少なく回しているのは、df.loc[index+2,'終値'] と'終値'が存在しない部分を読みだそうとするとエラーになるからです。

今日はここまでにしよう。

途中、何度もエラーが出たけど、冷静にエラーメッセージを読めば対処できるよね!

今回作ったデータを人工知能に与えるとどんな答えが出るか?次回が楽しみね~♪

今回の入力データは、ある意味適当に選んで作ったけど、結果を元に、入力データへどんな風にフィードバックするか?ここが大切だよね!

しょーた、いい事言うわね~♡

更新履歴

2022.10.10
正規化のサンプル修正
2022.8.6
新規作成

QooQ