TensorFlow(LSTM)で株価予想 〜 株予想その1 〜


はじめに

新しく株投資の勉強を始めるのでそのメモを残していきます。

目標、機械学習やディープラーニングを使って株価予想します。

勉強を始めるにあたり、先ずは以下の本を確認。
※ 株が動く条件は「業績がよい」「PERが低い」「チャートの形が良い」らしい。
各々スクレイピングで持ってきて予測していきたいと思います。

[補足]

普段は株以外に競馬予想 sivaを運用しています。
連対的中率 : 約 86%
回収率 : 約 136%

twitter始めました。
フォローお願いします。

なぜ株か?

以下の見解から株を選んでみました。

 ◆ 競馬などのギャンブル
  0 or 100のリターンも大きいがリスクが大きい。
 ◆ FX 
  儲かる人の反面に損する人がいるので、性分に合わない。
 ◆ bitcoin
  価値が確立されてないので、暴落の恐れも考えられる。
 ◆ 株
  株に関してはみんなが儲かる仕組みである。

  

先ずは株の予測実験

スクレイピングで持ってくる前にダウンロードして実験できるサイトから実験を始めてみます。

ダウンロードしてきたデータは日経平均の2007年〜2017年の情報。
日付, 始値, 高値, 安値, 終値のデータが入っています。

今回使用するデータは終値を利用します。

アプローチを考える

株については過去の実績(※1)を統計的に分析するより、時系列を用いたRNN(Recurrent Neural Network)(※2)で予測するほうが向いていると考えられるので、RNNの拡張であるLSTM(Long short-term memory)を使ってみることにします。

※1 過去データの実績をチャートで学習する方法も次回以降で試してみる。
※2 RNNはディープラーニングの一種。普通のニューラルネットと違い、現在の入力値に加えて自身の前の状態を入力する。RNNの入出力は、以下図のようになります。入力として、時間的に連続なデータx(= x_1, x_2, x_3, …, x_n)を考えたとき、x_tの入力と一緒に直前の状態s_t-1も入力される。
この「前の状態」は、それまでの過去の情報を含んでいる。


RNNの概略図(引用元)

とにかくプログラムで実験

先ずはやってみることを優先して日経平均で、サクッとプログラムを作ってみました。

# -*- coding: utf-8 -*-
import numpy
import pandas
import matplotlib.pyplot as plt

from sklearn import preprocessing
from keras.models import Sequential
from keras.layers.core import Dense, Activation
from keras.layers.recurrent import LSTM

class Prediction :

  def __init__(self):
    self.length_of_sequences = 10
    self.in_out_neurons = 1
    self.hidden_neurons = 300


  def load_data(self, data, n_prev=10):
    X, Y = [], []
    for i in range(len(data) - n_prev):
      X.append(data.iloc[i:(i+n_prev)].as_matrix())
      Y.append(data.iloc[i+n_prev].as_matrix())
    retX = numpy.array(X)
    retY = numpy.array(Y)
    return retX, retY


  def create_model(self) :
    model = Sequential()
    model.add(LSTM(self.hidden_neurons, \
              batch_input_shape=(None, self.length_of_sequences, self.in_out_neurons), \
              return_sequences=False))
    model.add(Dense(self.in_out_neurons))
    model.add(Activation("linear"))
    model.compile(loss="mape", optimizer="adam")
    return model


  def train(self, X_train, y_train) :
    model = self.create_model()
    # 学習
    model.fit(X_train, y_train, batch_size=10, nb_epoch=100)
    return model


if __name__ == "__main__":

  prediction = Prediction()

  # データ準備
  data = None
  for year in range(2007, 2017):
    data_ = pandas.read_csv('csv/indices_I101_1d_' + str(year) +  '.csv')
    data = data_ if (data is None) else pandas.concat([data, data_])
  data.columns = ['date', 'open', 'high', 'low', 'close']
  data['date'] = pandas.to_datetime(data['date'], format='%Y-%m-%d')
  # 終値のデータを標準化
  data['close'] = preprocessing.scale(data['close'])
  data = data.sort_values(by='date')
  data = data.reset_index(drop=True)
  data = data.loc[:, ['date', 'close']]

  # 2割をテストデータへ
  split_pos = int(len(data) * 0.8)
  x_train, y_train = prediction.load_data(data[['close']].iloc[0:split_pos], prediction.length_of_sequences)
  x_test,  y_test  = prediction.load_data(data[['close']].iloc[split_pos:], prediction.length_of_sequences)

  model = prediction.train(x_train, y_train)

  predicted = model.predict(x_test)
  result = pandas.DataFrame(predicted)
  result.columns = ['predict']
  result['actual'] = y_test
  result.plot()
  plt.show()

結果

なかなか予測できてるのでは・・・・

UP・DOWNにすれば良い予測もできそう。

さいごに

今回は動かすことを優先しましたが、今後も継続して記事を書いていきます。
twitter始めました。
フォローお願いします。

その他、競馬予想 sivaを運用しています。
こちらもフォローお願いします。