PythonとLSTM(RNN)を使って株価予測を実装する方法

スポンサーリンク

今日はプログラミング言語Pythonを使って、様々なカテゴリの株価を予測する方法を学びます。

株価予測とは、取引所で取引されている企業の株式やその他の金融商品の将来の価値を見極めようとする行為です。

株価の将来価格の予測が成功すれば、大きな利益を得ることができる。

今回のアプリケーションでは、LSTMネットワークを用いて、過去60日間の株価から終値の予測を行いました。

このアプリケーションでは、LSTM(Long Short Term Memory)と呼ばれる機械学習技術を使用しました。

LSTMは、ディープラーニングの分野で使われている人工再帰神経回路網(RNN)のアーキテクチャです。

一般的なフィードフォワードニューラルネットワークとは異なり、LSTMはフィードバック接続を持っています。

画像などの単一データだけでなく、音声や動画などの連続したデータ全体を処理することができる。

LSTMはシーケンス予測の問題に広く用いられ、非常に有効であった

スポンサーリンク

Pythonによる株価予測の実装

1. モジュールのインポート

まず、プロジェクトに必要なすべてのモジュールをインポートします。

1
2
3
4
5
6
7
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from keras.models import Sequential
from keras.layers import Dense, LSTM
import math
from sklearn.preprocessing import MinMaxScaler

このプロジェクトでは、numpy、pandas、matplotlibのような基本的なモジュールを使用する予定です。

これに加えて、モデルを適切に作成し構築するために、kerasのいくつかのサブモジュールを使用する予定です。

また、基本的な計算を行うためのmathモジュールや、データをより良くシンプルに扱うためのsklearnのプリプロセッシングモジュールも必要になるでしょう。

2. データの読み込みと準備

このプロジェクトでは、5年分の株価データを含む、以下の7つのカラムを持つ all_stocks_5yrs csv ファイルを使用する予定です。

    1. 日付 – 日付の書式は以下の通りです。”yy-mm-dd”
    1. 始値 – 当該銘柄の始値
  1. 高値 – その日についた最高値
  2. 安値 – その日の最安値
  3. 終値 – 市場が終了した時点の株価
  4. 出来高 – 取引された株式数
  5. 銘柄名 – ティッカー名
1
2
data=pd.read_csv("all_stocks_5yr..csv")
data.head()

head` 関数は、データセットの最初の5行を表示します。

1
2
all_stock_tick_names = data['Name'].unique()
print(all_stock_tick_names)

3. データを理解する

3.1 ユニークな銘柄名の取得

データセット全体から、まず unique 関数を用いてユニークな銘柄名をすべて抽出します。

データセットには444種類の銘柄名があります。

1
2
3
4
5
6
7
8
9
10
11
# 1. Getting a stock name
stock_name = input("Enter a Stock Price Name: ")
 
# 2. Extrating all the data having the name same as the stock name entered
all_data = data['Name'] == stock_name
 
# 3. Putting all the rows of specific stock in a variable
final_data = data[all_data]
 
# 4. Printing first 5 rows of the stock data of a specific stock name
final_data.head()
1
2
3
4
5
6
7
8
9
10
#  Plotting date vs the close market stock price
final_data.plot('date','close',color="red")
 
# Extract only top 60 rows to make the plot a little clearer
new_data = final_data.head(60)
 
#  Plotting date vs the close  market stock price
new_data.plot('date','close',color="green")
 
plt.show()

3.2 特定の銘柄のデータを抽出する

ユーザから銘柄名を入力し、その特定の銘柄の全データを収集することで、銘柄データの仕組みを理解することに努めます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 1. Filter out the closing market price data
close_data = final_data.filter(['close'])
 
# 2. Convert the data into array for easy evaluation
dataset = close_data.values
 
# 3. Scale/Normalize the data to make all values between 0 and 1
scaler = MinMaxScaler(feature_range=(0, 1))
scaled_data = scaler.fit_transform(dataset)
 
# 4. Creating training data size : 70% of the data
training_data_len = math.ceil(len(dataset) *.7)
train_data = scaled_data[0:training_data_len  , : ]
 
# 5. Separating the data into x and y data
x_train_data=[]
y_train_data =[]
for i in range(60,len(train_data)):
    x_train_data=list(x_train_data)
    y_train_data=list(y_train_data)
    x_train_data.append(train_data[i-60:i,0])
    y_train_data.append(train_data[i,0])
 
    # 6. Converting the training x and y values to numpy arrays
    x_train_data1, y_train_data1 = np.array(x_train_data), np.array(y_train_data)
 
    # 7. Reshaping training s and y data to make the calculations easier
    x_train_data2 = np.reshape(x_train_data1, (x_train_data1.shape[0],x_train_data1.shape[1],1))
1
2
3
4
5
model = Sequential()
model.add(LSTM(units=50, return_sequences=True,input_shape=(x_train_data2.shape[1],1)))
model.add(LSTM(units=50, return_sequences=False))
model.add(Dense(units=25))
model.add(Dense(units=1))

3.3 株式データの可視化

データを視覚化するために、まず FITB 株のすべてのデータポイントについて、日付と終値の市場価格をプロットします。

より簡単に可視化するために、同じプロットを最初の 60 データポイントについてだけ行います。

1
2
model.compile(optimizer='adam', loss='mean_squared_error')
model.fit(x_train_data2, y_train_data1, batch_size=1, epochs=1)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 1. Creating a dataset for testing
test_data = scaled_data[training_data_len - 60: , : ]
x_test = []
y_test =  dataset[training_data_len : , : ]
for i in range(60,len(test_data)):
    x_test.append(test_data[i-60:i,0])
 
# 2.  Convert the values into arrays for easier computation
x_test = np.array(x_test)
x_test = np.reshape(x_test, (x_test.shape[0],x_test.shape[1],1))
 
# 3. Making predictions on the testing data
predictions = model.predict(x_test)
predictions = scaler.inverse_transform(predictions)
1
2
rmse=np.sqrt(np.mean(((predictions- y_test)**2)))
print(rmse)

4. 新しいデータフレームの作成と学習データの作成

ここでは、学習しやすいように「終値」のみを考慮し、Pythonを使って終値を予測することにします。

学習データの作成は以下のステップで行います。

参考までにコメントをつけておきます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
train = data[:training_data_len]
valid = data[training_data_len:]
 
valid['Predictions'] = predictions
 
plt.title('Model')
plt.xlabel('Date')
plt.ylabel('Close')
 
plt.plot(train['close'])
plt.plot(valid[['close', 'Predictions']])
 
plt.legend(['Train', 'Val', 'Predictions'], loc='lower right')
 
plt.show()

ここでは、61日目の終値を予測するために、60日分の終値を含むデータセット(60データポイント)を作成し、学習用データとします。

xxx_trainデータセットには、1列目が0から59まで、2列目が1から60まで、合計60個の値が格納されます。

y_trainデータセットには、1列目のインデックス60に61個目の値が、2列目にはインデックス61に62個目の値が格納される。

独立訓練データセットと従属訓練データセットをそれぞれ x_train_data と y_train_data として NumPy 配列に変換し、LSTM モデルの訓練に使用できるようにします。

また、LSTMモデルは3次元のデータを想定しているので、reshape()関数を用いてデータを3次元の形に整形します。

5. LSTMモデルの構築

LSTMモデルは、50ニューロンからなる2つのLSTM層と、25ニューロンと1ニューロンからなる2つのDense層で構成される。

First_five_rows_stock_data
First_five_rows_stock_data

6. モデルのコンパイル

LSTMモデルは、平均二乗誤差(MSE)損失関数とadamオプティマイザーを用いてコンパイルされる。

All Stock Names Stock Data
All Stock Names Stock Data

train の別名である fit() 関数を用いて、データセットの学習を行う。

batch_sizeは1つのバッチに含まれる学習例の総数、epochsはデータセット全体がニューラルネットワークを通過して前進・後退する際の反復回数です。

Stock Data FITB Stock Name
Stock Data FITB Stock Name

7. テストデータでモデルをテストする

以下のコードでは、終値のカラムから training_data_len 以上の行を全て取得します。

そして、x_testデータセットをNumPyの配列に変換し、LSTMモデルの学習に使用できるようにします。

LSTMモデルは3次元のデータを想定しているので、reshape()関数を使ってデータセットを3次元の形に変形させる。

predict()関数を用いて、テストデータを用いてモデルから予測値を取得します。

また、scaler.inverse_transform()関数はスケーリングを元に戻す関数です。

Date Vs Close Price FITB
Date Vs Close Price FITB

8. 誤差の計算

RMSEとは、平均二乗誤差のことで、モデルの精度を計るのに役立ちます。

Date Vs Close Price FITB First 60
Date Vs Close Price FITB First 60

値が低いほど、モデルの性能が高いことを意味します。

0の値は、モデルの予測値がテストデータセットの実際の値と完全に一致することを示します。

私たちが受け取ったrmse値は0.6505512245089267で、これは十分な値です。

9. 予測する

最後のステップは、データをプロットして可視化することです。

データを可視化するためには、グラフをどのように見せたいかに応じて、タイトル、ラベル、プロットといった基本的な関数を使用します。

Compiled LSTM Stock Price Predict
Compiled LSTM Stock Price Predict
Predictions Made Plot LSTM Stocks
Predictions Made Plot LSTM Stocks

10. 実績値と予測値の比較

Final Predictions Vs Actual Values LSTM Stocks
Final Predictions Vs Actual Values LSTM Stocks

まとめ

今日はLSTMモデルを使って株価を予測する方法を学びました! そして、実際の株価(close)と予測された株価(predicted)の値はかなり一致していますね。

読んでくれてありがとうございました

タイトルとURLをコピーしました