TensorFlow(多層パーセプトロン:MLP)で株価予想 〜 株予想その２ 〜


## はじめに
株投資の勉強を始めるのでそのメモを残していきます。

前回の[TensorFlow(LSTM)で株価予想 〜 株予想その１ 〜](http://qiita.com/tsunaki/items/a5f3f975a31dc45fc9c9)の続き

※前回の予測した株価
![Screen Shot 0029-06-30 at 3.26.00 AM.png](https://qiita-image-store.s3.amazonaws.com/0/52867/3724bf6a-d0b4-127e-8021-57e9c2dc7de5.png "Screen Shot 0029-06-30 at 3.26.00 AM.png")

今回は多層パーセプトロン(MLP)を用いて株価が上がるか下がるかを分類し株価予測をしてみます。

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

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

## 簡単な仕様
[前回](http://qiita.com/tsunaki/items/a5f3f975a31dc45fc9c9)の予測方法として、前10日分の終値から、LSTMで翌日の株価を予測していました。

今回は前100日分の終値を入れ、翌日の株価が上がるか下がるかの2値分類をします。


## 先ずは株の予測実験
データは[前回](http://qiita.com/tsunaki/items/a5f3f975a31dc45fc9c9)と一緒で[こちら](http://k-db.com/)のデータを使います。


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



## アプローチ

過去100日分の終値情報から翌日の株が上がるか下がるかの２値分類なので、活性化関数にロジスティック関数（シグモイド）、損失関数にエントロピー誤差で実施します。

####多層パーセプトロンについて

多層パーセプトロン (Multi-Layer Perceptron : MLP) は、複数の層にニューロンを配置させたフィードフォワード型ニューラルネットワーク。


![image.jpg](https://qiita-image-store.s3.amazonaws.com/0/52867/8b4c3e97-30dc-228f-c9e9-a88f956a39df.jpeg "image.jpg")


## プログラムによる実験
前回同様に先ずはやってみることを優先して日経平均で、サクッとプログラムを作ってみます。
分類の正解率を出します。

```stock_mlp.py
# -*- coding: utf-8 -*-
import sys
import os
import numpy
import pandas
from sklearn import preprocessing

from keras.models import Sequential
from keras.layers import Convolution2D, MaxPooling2D
from keras.layers import Activation, Dropout, Flatten, Dense
from keras.utils import np_utils


#
# モデルを生成
#
class StockCNN : 
  def __init__(self):
    self.length_of_sequences = 100

  def load_data(self, date, data, n_prev=100):
    label = []
    X, Y = [], []
    for i in range(len(data) - n_prev):
      label.append(date.iloc[i+n_prev].as_matrix())
      X.append(data['close'].iloc[i:(i+n_prev)].as_matrix())
      array = data.iloc[i:(i+n_prev)].as_matrix()
      if (float(array[-1]) > float(data.iloc[i+n_prev].as_matrix())) :
        Y.append([0])
      else :
        Y.append([1])

    ret_label = numpy.array(label)
    retX = numpy.array(X)
    retY = numpy.array(Y)
    return ret_label, retX, retY

  def create_model(self) :
    model = Sequential()
    model.add(Dense(64, input_dim=self.length_of_sequences, activation='sigmoid'))
    model.add(Dense(128, activation='sigmoid'))
    model.add(Dense(64, activation='sigmoid'))
    model.add(Dense(1, activation='sigmoid'))


    model.compile(loss='binary_crossentropy',
                  optimizer='rmsprop',
                  metrics=['accuracy'])

    return model

if __name__ == "__main__":

  stock = StockCNN()
  data = None
  for year in range(2007, 2018):
    data_ = pandas.read_csv('csv/indices_I101_1d_' + str(year) +  '.csv', encoding="shift-jis")
    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']]

  # データ準備
  split_pos = int(len(data) * 0.9)
  x_label, x_train, y_train  = stock.load_data(data[['date']].iloc[0:split_pos],\
                                          data[['close']].iloc[0:split_pos], stock.length_of_sequences)
  x_tlabel, x_test,  y_test  = stock.load_data(data[['date']].iloc[split_pos:], \
                                          data[['close']].iloc[split_pos:], stock.length_of_sequences)

  model = stock.create_model()

  
  model.fit(x_train, y_train, nb_epoch=1000, batch_size=10)



  good = 0
  index = 0
  for values in x_test : 
    y = y_test[index][0]
    predict = model.predict(numpy.array([values]))[0][0]
    print(x_tlabel[index][0])
    print(y)
    print(predict)
    if predict < 0.5 :
      if y == 0 :
        good += 1
    else : 
      if y == 1 :
        good += 1
    index += 1
  print ("accuracy = {0:.2f}".format(float(good) / len(x_test)))
  
```

## 結果
今回はUP/DOWNの２分類なので複数回試して結果を検証します。

| 回目 | accuracy|
|:----:|:------------:|
|１回目|57%|
|２回目|59%|
|３回目|53%|


うーん。。。。
適当よりは可能性が高いが、予測ができてるとは言えないかな。。。
ってことでもっと頑張ります。

## さいごに

先ずはとにかく試すことを優先して最適なやり方を検討します。
次回は統計算出、CNN、強化学習に挑戦してみます。

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

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