LoginSignup
35
44

More than 3 years have passed since last update.

機械学習で競馬分析をしてみた話

Last updated at Posted at 2018-12-23

機械学習で競馬分析

ドワンゴの主催している電脳賞を始めとしてAIに競馬予想をさせてみようという試みが機械学習の盛り上がりをともに再燃してきており、ちょっと古いですが競馬予想ソフトで30億稼いで1億脱税して捕まった人もいました。まぁこれは大成功な例ですが、電脳賞にも回収率に応じて賞金がでますし、
JRA-DATALABでも人気ソフトには報奨金が出ます。
予想ツールを作って当たれば儲かる、作ったツールを人に使ってもらってもお金がはいる・・・。
やろう!!
ということで今回は12月23日中山競馬場で開催されるG1有馬記念の着順予想をしてみようと思います。

データ取得

やろうといってもデータがなければ始まらないのでJRA-VANデータラボ(https://jra-van.jp/dlb/)
からデータを取得してきます。月額2052円で最古データは1986年から30年近いデータを取得することができます。
とはいえこれが厄介でAPIはVBしか対応していないらしい・・・。
なので今回はJRA-VANデータラボで提供されているデータベースソフトのひとつpckeibaを使用してSQLiteにてデータを取得します。
が、約30年分のデータ重い、遅い・・・。
pckeiba_datainsert.jpg
ここまで2週間近く取得に費やして今20120599なので2012年の5月開催のデータまで取得できてるということ・・・。
うーん、12月23日15:25発送というタイムリミットがあるので、苦肉の策ではありますが、ここは現在活躍している馬の親世代2000年~2012年のデータを使用します。

使用環境

Google Colaboratory
google_corabolatry_image.jpg
ブラウザ上でjyupiternotebookが使用できpython、Numpy、Tensolflowも特にインストールせず使用でき、GPUも利用可能、なおかつ無料で利用できるGoogle Colaboratoryを使用します。

で本題

一般的には、多層パーセプトロンで抽出したあとSVMにかけてゴニョゴニョするっていうのが競馬分析で多い手法のようです。
とはいえ、今回は競馬分析に合っている手法とは言えませんが線形回帰で分析をしようと思います。

horse_race.py
# show upload dialog
from google.colab import files
uploaded = files.upload()

# read data
import pandas as pd
import io
data = pd.read_csv(io.StringIO(uploaded['race_data2.csv'].decode('utf-8')), header=0)

pd.set_option("display.max_columns", 100)
pd.set_option("display.max_rows", 10000)

dp_data = data.drop(["KAKUTEI_CHAKUJUN"], axis=1)

X = dp_data.values
Y = data["KAKUTEI_CHAKUJUN"].values

# learn
from sklearn import linear_model

clf = linear_model.Lasso()
clf.fit(X, Y)

print(pd.DataFrame({"column": dp_data.columns, "coef": clf.coef_}))
print(clf.intercept_)

# test
uploaded2 = files.upload()
test_data = pd.read_csv(io.StringIO(uploaded2['test_data.csv'].decode('utf-8')), header=0)

x_test = test_data.values

# predict
predict = clf.predict(x_test)
print(predict)

とここまで何となくお分かりかもしれませんが、ほぼteco-yagiさんが12/17のTECOTEC Advent Calendar 2018でやられていることとほぼ同じです。

JRA-VANデータラボで取得してきたデータをGoogle colaboratoryで使用するためfiles_uploadでアップロードしてread_csvで読み込むようになってます。

race_data2.csv
RACE_CODE,KEIBAJO_CODE,KAISAI_NICHIJI,RACE_BANGO,WAKUBAN,UMABAN,KETTO_TOROKU_BANGO,UMAKIGO_CODE,SEIBETSU_CODE,HINSHU_CODE,MOSHOKU_CODE,BAREI,TOZAI_SHOZOKU_CODE,CHOKYOSHI_CODE,BANUSHI_CODE,FUTAN_JURYO,KISHU_CODE,KAKUTEI_CHAKUJUN
2011122506050810 ,6,8,10,8,13,2008103235,0,3,1,3,3,2,1002,180800,55,666,9
2011122506050810 ,6,8,10,6,9,2008102636,0,1,1,1,3,2,1071,226800,55,1032,1
2011122506050810 ,6,8,10,5,8,2007103404,0,1,1,4,4,2,343,226800,57,711,12
2011122506050810 ,6,8,10,5,7,2007103265,0,1,1,3,4,2,1071,486800,57,1014,3
・
・
・

JRA-VANデータラボからの抽出データの一部です。
有料データとなるので一部のみ記載しています。
大体のカラム名がそのままの意味ですが念のため以下に記します

カラム名 詳細
RACE_CODE 開催年月日8桁(yyyyMMdd 形式) + 競馬場コード2桁 + 開催回次2桁 + 開催日次2桁 + レース番号2桁
KEIBAJO_CODE 競馬場ごとに一意に振られた番号
KAISAI_NICHIJI 開催日時
RACE_BANGO レース番号
WAKUBAN 枠番
UMABAN 馬番
KETTO_TOROKU_BANGO 血統登録番号
UMAKIGO_CODE 馬記号コード(馬ごとに一意に振られた番号)
SEIBETSU_CODE 性別コード(性別ごとに一意に振られた番号)
HINSHU_CODE 品種コード(品種ごとに一意に振られた番号)
MOSHOKU_CODE 毛色コード(毛色ごとに一意に振られた番号)
BAREI 馬齢
TOZAI_SHOZOKU_CODE 東西所属コード(東か西かを表すコード)
CHOKYOSHI_CODE 調教師コード(調教師ごとに一意に振られた番号)
BANUSHI_CODE 馬主コード(馬主ごとに一意に振られた番号)
FUTAN_JURYO 負担重量
KISHU_CODE 騎手コード(騎手ごとに一意に振られた番号)
KAKUTEI_CHAKUJUN 確定後の順位

必要なデータのみを取得してCSVを作成しているので全てのデータを利用して
確定後順位を予想してみようと思います。
速報系データとして現在時点の出走馬情報が取得できるので速報系データからtest_data.csvを作成します。test_data.csvは以下の通り。

test_data.csv
RACE_CODE,KEIBAJO_CODE,KAISAI_NICHIJI,RACE_BANGO,WAKUBAN,UMABAN,KETTO_TOROKU_BANGO,UMAKIGO_CODE,SEIBETSU_CODE,HINSHU_CODE,MOSHOKU_CODE,BAREI,TOZAI_SHOZOKU_CODE,CHOKYOSHI_CODE,BANUSHI_CODE,FUTAN_JURYO,KISHU_CODE
2018122306050810,6,8,11,1,1,2011101125 ,0,1,1,3,7,1,1114,892800,0,0
・
・
・
・

こちらも一応一部のみ記載していますが、出走16頭分のデータが入っています。

出力してみる

[14.4199213 13.67719624 13.41511762 14.07644514 14.28232161 14.05559027
14.98255294 13.8792095 14.46912673 14.35686541 14.69296645 14.23888201
15.62113876 14.67513616 15.26724555 15.69717164]
馬番順に並んでいます。
まぁ出力結果が1~16になってない時点で色々調整が必要ですが、数値が1に近い方が
1着の可能性が高くなるのでこの場合、出走表通り3-2-8の順になる可能性が高いということになります。
3.モズカッチャン、2.クリンチャー、8.ブラストワンピース
一番人気のレイデオロやキセキ、注目馬のオジュウチョウサンは入っていないものの
モズカッチャン、クリンチャーはあってもおかしくないのではっていう結果でちょっと驚いてます。
ブラストワンピースは過去2回G1で賭けてはずしたので期待薄・・・。
2018年の有馬記念は3-2-8で各単勝、複勝、3連複、3連単で賭けてみましょう。
(ここまでは2018年12月22日~23日深夜に書いています)

結果

御存知の方は御存知だと思いますが8-12-15。
ブラスワンピース、レイデオロ、シュバルグラン

というわけで
IMG_2498.JPG

単勝、複勝当たり!!
期待薄なんて言ってすいませんでしたーーーー!!
まぁただし、予想順位が上位であったモズカッチャン、クリンチャーは8着、15着と沈んでいるので精度が高いものとは言えないでしょう。
もうちょっと理論を精査して多層パーセプトロン等での実装が将来的にはできるようにしたいなぁ。
今回の収支?今回の収支は結果を信じ切れずレイデオロ軸でもろもろ買ったけどシュバルグラン入ってなくて撃沈したので総収支ではマイナスでした!!!

35
44
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
35
44