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


## はじめに


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

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


勉強を始めるにあたり、先ずは以下の本を確認。
※ 株が動く条件は「業績がよい」「PERが低い」「チャートの形が良い」らしい。
各々スクレイピングで持ってきて予測していきたいと思います。
![DDeoY-tVwAAeFnE.jpg](https://qiita-image-store.s3.amazonaws.com/0/52867/49395e2a-8499-e39f-36e0-685fdc303792.jpeg "DDeoY-tVwAAeFnE.jpg")


###[補足]
普段は株以外に競馬予想 [siva](http://siva-ai.com/)を運用しています。
   連対的中率 ： 約 86%
      回収率 ： 約 136%

[twitter](https://twitter.com/tsunaki00)始めました。
フォローお願いします。

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

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

  
## 先ずは株の予測実験

スクレイピングで持ってくる前にダウンロードして実験できる[サイト](http://k-db.com/)から実験を始めてみます。

ダウンロードしてきたデータは日経平均の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も入力される。
この「前の状態」は、それまでの過去の情報を含んでいる。

![screenshot_119.png](https://qiita-image-store.s3.amazonaws.com/0/52867/da110c12-7871-9f8a-5a21-1a59f2c7f77e.png "screenshot_119.png")
RNNの概略図([引用元](http://peterroelants.github.io/))

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

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

```python
# -*- 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()

```

## 結果

なかなか予測できてるのでは・・・・
![Screen Shot 0029-06-30 at 3.26.00 AM.png](https://qiita-image-store.s3.amazonaws.com/0/52867/691bdb61-f9ae-8e37-5b9c-9f7496de237c.png "Screen Shot 0029-06-30 at 3.26.00 AM.png")


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


## さいごに
今回は動かすことを優先しましたが、今後も継続して記事を書いていきます。
[twitter](https://twitter.com/tsunaki00)始めました。
フォローお願いします。

その他、競馬予想 [siva](http://siva-ai.com/)を運用しています。
こちらもフォローお願いします。