はじめに
特にFujitsu Advent Calendar 2016にちなんだ内容でなく、自分の趣味(継続中の開発の続き)を書きます。
※ 当記事は会社を代表するものではなく、個人の意見です。
(本業は新規事業立ち上げなどで開発職ではありません)
継続中の開発
[開発しているSIVAについて]
[facebook]
https://www.facebook.com/AIkeiba/
[Twitter]
https://twitter.com/Siva_keiba
随時実況していきますので、いいね!フォローお願いします。
今回のやること
前回の続き。
ディープラーニング(深層学習)による予測についてのサンプルコードを書きます。
始めるにあたり必要なスキルはこちらを参考してください。
今回のライブラリ
TensorFlow:https://www.tensorflow.org/
前回のデータを使います。
インストール方法は以下の記事などを参考にしてもらえばと思います。
予測モデル作成と実験(前と同じです)
以下のプログラムを準備してモデルの作成
###用意したデータは以下のCSV(JRA-VANより)
| ラベル名 | 説明 |
| :-----------|:--------------|:--------------|
|開催日|yyyy-mm-dd|
|競馬場|
|レース番号|
|レース名|
|コース|ダート|
|周回|ダートか芝の場合、右回りなら「右」、左回りなら「左」|
|距離|[m]|
|馬場状態|良(りょう)|
|賞金|[万円]|
|頭数|
|着順|
|枠番|
|馬番|
|馬名|
|性別|
|年齢|
|騎手|
|タイム|[s]|
|着差|前着の馬との差のこと,クビ,|大差|
|通過順|
|上り3F|ラスト600mのタイム[s]|
|斥量|[kg]|
|馬体重|[kg]|
|増減|前レースからの馬体重変化[kg]|
|人気|oddsの降順の番号|
|オッズ|
|ブリンカー|ブリンカー(目隠し)ありの場合、「B」|
|調教師|
|調教コメント|
|調教評価|
※ブリンカー、調教師、調教コメント以外をパラメータにしてます。
###予測プログラム(trainNN.py)
データと合わせてGitにあげときました。
# -*- coding: utf-8 -*-
import csv
import random
import numpy as np
import pandas as pd
import tensorflow as tf
from sklearn.cross_validation import train_test_split
from sklearn.feature_extraction import DictVectorizer
from sklearn import preprocessing
class TrainNN:
def __init__(self) :
# Parameters
self.learning_rate = 0.01 # 学習率 高いとcostの収束が早まる
self.training_epochs = 50 # 学習全体をこのエポック数で区切り、区切りごとにcostを表示する
self.batch_choice = 500
self.batch_size = 0 # 学習1回ごと( sess.run()ごと )に訓練データをいくつ利用するか
self.display_step = 1 # 1なら毎エポックごとにcostを表示
self.train_size = 500 # 全データの中でいくつ訓練データに回すか
self.step_size = 500 # 何ステップ学習するか
# Network Parameters
self.n_hidden_1 = 64 # 隠れ層1のユニットの数
self.n_hidden_2 = 64 # 隠れ層2のユニットの数
self.n_input = 27 # 与える変数の数
self.n_classes = 0 # 分類するクラスの数
def load_csv(self):
file_name = "data/jra_race_resultNN.csv"
df = pd.read_csv(file_name)
## 文字列の数値化
labelEncoder = preprocessing.LabelEncoder()
df['area_name'] = labelEncoder.fit_transform(df['area_name'])
df['race_name'] = labelEncoder.fit_transform(df['race_name'])
df['track'] = labelEncoder.fit_transform(df['track'])
df['run_direction'] = labelEncoder.fit_transform(df['run_direction'])
df['track_condition'] = labelEncoder.fit_transform(df['track_condition'])
df['horse_name'] = labelEncoder.fit_transform(df['horse_name'])
df['horse_sex'] = labelEncoder.fit_transform(df['horse_sex'])
df['jockey_name'] = labelEncoder.fit_transform(df['jockey_name'])
df['margin'] = labelEncoder.fit_transform(df['margin'])
df['is_blinkers'] = labelEncoder.fit_transform(df['is_blinkers'])
df['trainer_name'] = labelEncoder.fit_transform(df['trainer_name'])
df['comments_by_trainer'] = labelEncoder.fit_transform(df['comments_by_trainer'])
df['evaluation_by_trainer'] = labelEncoder.fit_transform(df['evaluation_by_trainer'])
df['dhorse_weight'] = labelEncoder.fit_transform(df['dhorse_weight'])
x_np = np.array(df[['area_name', 'race_number', 'race_name', 'track', 'run_direction',
'distance', 'track_condition', 'purse', 'heads_count',
'post_position', 'horse_number', 'horse_name', 'horse_sex', 'horse_age',
'jockey_name', 'time', 'margin', 'time3F',
'load_weight', 'horse_weight', 'dhorse_weight', 'odds_order',
'odds', 'is_blinkers', 'trainer_name', 'comments_by_trainer',
'evaluation_by_trainer'
]].fillna(0))
# 結果
d = df[['finish_order']].to_dict('record')
self.vectorizer = DictVectorizer(sparse=False)
y_np = self.vectorizer.fit_transform(d)
self.n_classes = len(self.vectorizer.get_feature_names())
# データを訓練データとテストデータに分ける
[self.x_train, self.x_test] = np.vsplit(x_np, [self.train_size])
[self.y_train, self.y_test] = np.vsplit(y_np, [self.train_size])
self.batch_size = self.train_size
# Create model
def multilayer_perceptron(self, x, weights, biases):
# Hidden layer with RELU activation
layer_1 = tf.add(tf.matmul(x, weights['h1']), biases['b1'])
layer_1 = tf.nn.relu(layer_1)
# Hidden layer with RELU activation
layer_2 = tf.add(tf.matmul(layer_1, weights['h2']), biases['b2'])
layer_2 = tf.nn.relu(layer_2)
# Output layer with linear activation
out_layer = tf.matmul(layer_2, weights['out']) + biases['out']
return out_layer
def train(self) :
# tf Graph input
x = tf.placeholder("float", [None, self.n_input])
y = tf.placeholder("float", [None, self.n_classes])
# Store layers weight & bias
weights = {
'h1': tf.Variable(tf.random_normal([self.n_input, self.n_hidden_1]), name="h1"),
'h2': tf.Variable(tf.random_normal([self.n_hidden_1, self.n_hidden_2]), name="h2"),
'out': tf.Variable(tf.random_normal([self.n_hidden_2, self.n_classes]), name="wout")
}
# バイアスの設定
biases = {
'b1': tf.Variable(tf.random_normal([self.n_hidden_1]), name="b1"),
'b2': tf.Variable(tf.random_normal([self.n_hidden_2]), name="b2"),
'out': tf.Variable(tf.random_normal([self.n_classes]), name="bout")
}
# Construct model
pred = self.multilayer_perceptron(x, weights, biases)
# Define loss and optimizer
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(pred, y))
correct_prediction = tf.equal(tf.argmax(pred, 1), tf.argmax(y, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
# Logistic Regression AdamOptimizer GradientDescentOptimizer
optimizer = tf.train.AdamOptimizer(learning_rate=self.learning_rate).minimize(cost)
# Initializing the variables
init = tf.initialize_all_variables()
saver = tf.train.Saver()
# Launch the graph
with tf.Session() as sess:
tf.scalar_summary("cost", cost)
tf.scalar_summary("accuracy", accuracy)
merged = tf.merge_all_summaries()
writer = tf.train.SummaryWriter("logs/tensorflow_log", sess.graph_def)
sess.run(init)
# Training cycle
for epoch in range(self.training_epochs):
avg_cost = 0.
# Loop over step_size
for i in range(self.step_size):
# 訓練データから batch_size で指定した数をランダムに取得
ind = np.random.choice(self.batch_size, self.batch_choice)
x_train_batch = self.x_train[ind]
y_train_batch = self.y_train[ind]
# Run optimization op (backprop) and loss op (to get loss value)
_, c = sess.run([optimizer, cost], feed_dict={x: x_train_batch, y: y_train_batch})
avg_cost += c / self.step_size
# Display logs per epoch step
if epoch % self.display_step == 0:
print "Epoch:", '%04d' % (epoch+1), "cost=", "{:.9f}".format(avg_cost)
# Compute average loss
summary_str, acc = sess.run([merged, accuracy], feed_dict={x: x_train_batch, y: y_train_batch})
writer.add_summary(summary_str, epoch)
print "Accuracy:", acc
## modelの保存
# name_model_file = 'model_epoch_' + str(epoch+1) + '.ckpt'
# save_path = saver.save(sess, 'model/tensorflow/' + name_model_file)
# Test model
correct_prediction = tf.equal(tf.argmax(pred, 1), tf.argmax(y, 1))
# Calculate accuracy
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
print "Accuracy:", accuracy.eval(session=sess, feed_dict={x: self.x_test, y: self.y_test})
if __name__ == "__main__":
trainNN = TrainNN()
trainNN.load_csv()
trainNN.train()
※ pythonおよびデTensorFlowについては勉強中ですのでプログラムに誤りがあるかもです。
結果
$ python trainNN.py
Epoch: 0001 cost= 28999.539070313
Accuracy: 0.183333
Epoch: 0002 cost= 10636.817809570
Accuracy: 0.146667
Epoch: 0003 cost= 8187.893877930
Accuracy: 0.216667
Epoch: 0004 cost= 6673.761091797
Accuracy: 0.183333
Epoch: 0005 cost= 5364.944535645
Accuracy: 0.196667
Epoch: 0006 cost= 4300.876705078
Accuracy: 0.176667
Epoch: 0007 cost= 3560.373814697
Accuracy: 0.27
Epoch: 0008 cost= 2843.689293701
Accuracy: 0.203333
Epoch: 0009 cost= 1605.616168819
Accuracy: 0.1
Epoch: 0010 cost= 21.059406254
Accuracy: 0.0666667
Epoch: 0011 cost= 9.320877672
Accuracy: 0.0566667
Epoch: 0012 cost= 5.621849694
Accuracy: 0.0866667
Epoch: 0013 cost= 4.749191205
Accuracy: 0.07
Epoch: 0014 cost= 4.069611630
Accuracy: 0.0733333
Epoch: 0015 cost= 3.946254434
Accuracy: 0.0566667
Epoch: 0016 cost= 3.253856863
Accuracy: 0.0433333
Epoch: 0017 cost= 3.309734127
Accuracy: 0.07
Epoch: 0018 cost= 2.978426178
Accuracy: 0.0566667
Epoch: 0019 cost= 2.970437231
Accuracy: 0.0533333
Epoch: 0020 cost= 2.999267270
Accuracy: 0.0566667
Epoch: 0021 cost= 3.828851234
Accuracy: 0.0766667
Epoch: 0022 cost= 2.859027134
Accuracy: 0.0666667
Epoch: 0023 cost= 2.799751988
Accuracy: 0.08
Epoch: 0024 cost= 2.799972694
Accuracy: 0.06
Epoch: 0025 cost= 2.799448245
Accuracy: 0.0633333
Epoch: 0026 cost= 2.799542419
Accuracy: 0.06
Epoch: 0027 cost= 2.798464981
Accuracy: 0.0933333
Epoch: 0028 cost= 2.799431955
Accuracy: 0.07
Epoch: 0029 cost= 2.798901843
Accuracy: 0.05
Epoch: 0030 cost= 2.797275106
Accuracy: 0.0366667
Epoch: 0031 cost= 2.799933175
Accuracy: 0.0566667
Epoch: 0032 cost= 2.799303545
Accuracy: 0.07
Epoch: 0033 cost= 2.799922926
Accuracy: 0.0533333
Epoch: 0034 cost= 2.799450584
Accuracy: 0.0833333
Epoch: 0035 cost= 2.800814153
Accuracy: 0.08
Epoch: 0036 cost= 2.799030569
Accuracy: 0.0733333
Epoch: 0037 cost= 2.799764482
Accuracy: 0.0566667
Epoch: 0038 cost= 2.799920460
Accuracy: 0.0833333
Epoch: 0039 cost= 2.799320694
Accuracy: 0.09
Epoch: 0040 cost= 2.800959777
Accuracy: 0.0766667
Epoch: 0041 cost= 2.799612596
Accuracy: 0.09
Epoch: 0042 cost= 2.800021134
Accuracy: 0.0666667
Epoch: 0043 cost= 2.799918224
Accuracy: 0.0666667
Epoch: 0044 cost= 2.799846961
Accuracy: 0.06
Epoch: 0045 cost= 2.799782973
Accuracy: 0.06
Epoch: 0046 cost= 2.798343555
Accuracy: 0.0633333
Epoch: 0047 cost= 2.800401002
Accuracy: 0.0633333
Epoch: 0048 cost= 2.799323093
Accuracy: 0.06
Epoch: 0049 cost= 2.799231728
Accuracy: 0.0733333
Epoch: 0050 cost= 2.800211056
Accuracy: 0.0633333
Accuracy: 0.0697074
$ tensorboard --logdir=logs/
tensorboard
0.6%。。。全くあたりませんね(笑)
※ もちろんですがSIVAで開発しているアルゴリズムは全く違います。
もう少し勉強してまた書きます!
さいごに(ご参考)
SIVAについては的中率は約40%で回収率は安定して100%前後です。
[開発しているSIVAについて]
[facebook]
https://www.facebook.com/AIkeiba/
[Twitter]
https://twitter.com/Siva_keiba
随時実況していきますので、いいね!フォローお願いします。