【機械学習で競馬予想】非エンジニアがAzureの機械学習機能で競馬の予想した手順を公開
過去の記事をまとめたよ
機械学習の本を買ってから、データを収集、データの前処理、Azureに取り込み、機械学習を走らせて、結果を分析するまでの手順まとめ
機械学習の本を読んだ
子供が産まれる直前に読む時間もあるだろうと、クラウドではじめる機械学習
という本を読んだ。
ざっくり内容を書くと、マイクロソフトのAzure Machine Learning Studioを使いながら
機械学習を学ぶ本だった。
自分でも機械学習で何かを予想できそうだったので、競馬の予想をしてみようと思った。
できるかわからないけど、予想までの過程をまとめる。
クラウドではじめる機械学習 改訂版 --Azure ML Studioでらくらく体験
- 作者: 脇森浩志,杉山雅和,羽生貴史
- 出版社/メーカー: リックテレコム
- 発売日: 2019/05/23
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る
Azure Machine Learning Studioを申し込む
マイクロソフトのページから申し込みを行う。
https://azure.microsoft.com/ja-jp/services/machine-learning-studio/
Free Workspaceを選ぶと、無料プランの申し込みができるので
とりあえずこれを申し込んでみた。
そうすると、無料の機能がつかえるのだけど、本には機能が制限されているから
有料プランのほうがいいと書いてあったけど、とりあえず無料を申し込んだ。
競馬データを集める
競馬に関する過去データはJRAのソフトからCSV形式で集めることができると書いてある。
とりあえず、無料トライアルが申し込めたので申し込んでみた
https://app.jra-van.jp/member/WAAlAdr0001.do
あとは、無料トライアルをしつつ、過去データを収取しよう。
競馬のデータを取得するのに苦労する話
前準備として、データを準備しないといけない。
前回書いたようにJRAのソフトを使って集めてみた。
競馬データを集める
競馬に関する過去データはJRAのソフトからCSV形式で集めることができると書いてある。
とりあえず、無料トライアルが申し込めたので申し込んでみた
久々にDVDの起動を行ってソフトをインストールした。
DVDには5本のソフトが入っていて、どれ使っていいのかよくわからないものの
一番右上にあったTarget というものを入れてみた。
Target
公式サイトはこちら
見事当たりだったみたいで、成績のCSVを出力することができた。
このソフトのデータ量ほんとに半端なくて、過去数十年間の競馬データが全部出力できる。
いろいろエクスポートしてはまったことを書く
1.エクスポートデータに項目名が書いていない
項目名は別で載せているらしい
http://faqnavi13a.csview.jp/faq2/userqa.do?user=jravan&faq=faq01_target&id=285&parent=20
2.とりあえず全項目をエクスポート
項目の意味がマニアックすぎて競馬知っている人でもよくわからないから使えない
3.基本データエクスポート
データが途中入っていない列があって、フル+オッズを選ばないといけないっぽい
とりあえず、10年分のデータをエクスポートして、今日は終了。
インストールに3時間、エクスポートに2時間くらい費やしました。
競馬のデータを取得したけど、全然中身がなかった
メインメニューから開催成績CSV出力を選ぶとデータのエクスポートはできるのだけど、ヘルプに書いてある項目は前走もありもっととれるデータがある様子。
なので、今日はツールを触ってみてどうやって取得するのかまとめておく。
http://faqnavi13a.csview.jp/faq2/userqa.do?user=jravan&faq=faq01_target&id=285&parent=20
前走データも取得するために
ヘルプを見ると戦歴・レース検索画面のレース一覧CSV形式とかいてあるので
レース検索画面をいじってみる。
基本全部のデータをエクスポートしたいのでここでは何も絞り込まず次へ。
選択馬の条件設定
最初は1着のみになっているので、28着までを選ぶ。
取消・除外馬を検索しないにチェックする。
そして、次へ。
出力期間の選択
あとは、期間を選択して検索実行すればレース検索ができる。
前走データを追加する
出力すると、レースのデータが出力されるけどここではまだ前走データは入っていない。
ここから「前走読込」を押すと前走データが追加される。
前走データを追加したものをCSVで出力する
ここまで出来たら、あとはCSVで出力するだけ。
「レース一覧・成績CSV形式(項目固定)」をクリックして出力する
出力したデータを保存する
あとは保存するファイル名を記入して、保存をすればCSV形式でエクスポートできる。
いっぱいデータが集まったので予測に使うデータを選別する
今回は一番新しいレース着順が1着を正解データとして、機械学習をやる予定。
なので、一番新しいレースの結果は予想のデータとしては使えないので削除する。
同じデータが名前を変えて入っている(騎手名と騎手コードとか)のでそこも削除する。
あと、Azureの文字コードがUTF-8で、JRA-DatalabがShift-jisなのでこのタイミングでUTF-8に変換しておく。
距離と馬場は合わせたほうが予想できそうと思ったので、抽出するときに1200m芝専用モデルというように作ることにした。
項目の説明はこちらに
http://faqnavi13a.csview.jp/faq2/userqa.do?user=jravan&faq=faq01_target&id=285&parent=20
作成したイメージ
モデル作りとスコア対象
モデルには1200m芝の2008−2018年までのデータを使って作る。
そのモデルを使って2019年の1200m芝のデータを使ってオフラインテストをやって検証することにする。
削除項目
削除した項目をメモしておく。
競馬やっている感で消したものもあるので未来データだけ消しているわけではない。
迷ったのはオッズで、オッズと勝ち負けは絶対相関しているので、オッズを入れると結局オッズで選んだのと一緒になりそうと思った。
なので、オッズありモデル、オッズなしモデルの2つを使って検証することにした。
項目名 | 値 | メモ |
年 | 19 | 削除 |
月 | 11 | 削除 |
日 | 17 | 削除 |
回次 | 3 | 削除 |
場所 | 福島 | 削除 |
日次 | 6 | 削除 |
レース番号 | 12 | 削除 |
レース名 | 会津特別1000 | 削除 |
クラスコード | 43 | 削除 |
芝・ダ | 芝 | 削除 |
コースコード | 0 | 削除 |
距離 | 1200 | 削除 |
馬場状態 | 良 | 削除 |
馬名 | バーミーブリーズ | 削除 |
性別 | 牝 | |
年齢 | 5 | |
騎手名 | 西田雄一 | |
斤量 | 55 | |
頭数 | 16 | |
馬番 | 14 | |
確定着順 | 1 | 削除 |
入線着順 | 1 | |
異常コード | 0 | 削除 |
着差タイム | 0 | 削除 |
人気順 | 7 | 削除 |
走破タイム | 69 | 削除 |
走破時計 | 1090 | 削除 |
通過順1 | 0 | 削除 |
通過順2 | 0 | 削除 |
通過順3 | 2 | 削除 |
通過順4 | 2 | 削除 |
上がり3Fタイム | 34.9 | 削除 |
馬体重 | 466 | 削除 |
調教師 | 青木孝文 | |
所属地 | 美 | |
賞金 | 1500 | 削除 |
血統登録番号 | 14105413 | 削除 |
騎手コード | 1004 | 削除 |
調教師コード | 1156 | 削除 |
レースID | 319361214 | 削除 |
現馬主名 | 吉田照哉 | |
生産者名 | 社台ファーム | |
父馬名 | キンシャサノキセキ | |
母馬名 | ウィンドハック | 削除 |
母の父馬名 | Platini | |
毛色 | 鹿毛 | |
生年月日 | 140505 | |
単勝オッズ | 19.4 | |
PCI | 47.7 | 削除 |
間隔 | 2 | |
前走年 | 19 | 削除 |
前走月 | 11 | 削除 |
前走日 | 2 | 削除 |
前走回次 | 3 | 削除 |
前走場所 | 福島 | |
前走日次 | 1 | 削除 |
前走レース番号 | 11 | 削除 |
前走レース名 | 河北新H1000 | 削除 |
前走クラスコード | 43 | 削除 |
前走芝・ダ | 芝 | |
前走コースコード | 0 | |
前走距離 | 1200 | |
前走馬場状態 | 良 | |
前走性別 | 牝 | |
前走騎手名 | 西田雄一 | 削除 |
前走斤量 | 52 | |
前走頭数 | 16 | |
前走馬番 | 12 | |
前走確定着順 | 2 | |
前走入線着順 | 2 | 削除 |
前走異常コード | 0 | 削除 |
前走着差タイム | 0.1 | |
前走人気順 | 14 | |
前走走破タイム | 68.4 | 削除 |
前走走破時計 | 1084 | 削除 |
前走通過順1 | 0 | 削除 |
前走通過順2 | 0 | 削除 |
前走通過順3 | 8 | |
前走通過順4 | 7 | |
前走上がり3Fタイム | 34.4 | |
前走馬体重 | 464 | |
前調教師 | 青木孝文 | |
前所属地 | 美 | |
前走賞金 | 600 | 削除 |
前走騎手コード | 1004 | 削除 |
前走競走識別コード | 319311112 | 削除 |
前オッズ | 68.7 | 削除 |
前走PCI | 48.8 | 削除 |
最終的に出来上がったもの
項目を消して残ったのがこちら、一般的に予想で使うものと思っている。
項目名 | 値 |
馬場状態 | 重 |
性別 | 牝 |
年齢 | 3 |
騎手名 | 秋山真一 |
斤量 | 52 |
頭数 | 18 |
馬番 | 1 |
入線着順 | 1 |
人気順 | 4 |
馬体重 | 442 |
調教師 | 音無秀孝 |
所属地 | 栗 |
現馬主名 | 吉田照哉 |
生産者名 | 社台ファーム |
父馬名 | ディープインパクト |
母の父馬名 | Giant's Causeway |
毛色 | 黒鹿 |
生年月日 | 160302 |
間隔 | 15 |
前走場所 | 京都 |
前走クラスコード | 23 |
前走芝・ダ | 芝 |
前走距離 | 1600 |
前走馬場状態 | 良 |
前走騎手名 | 松若風馬 |
前走斤量 | 54 |
前走馬番 | 3 |
前走確定着順 | 0 |
前走着差タイム | 999.9 |
前走人気順 | 0 |
前走通過順3 | 0 |
前走通過順4 | 0 |
前走上がり3Fタイム | 0 |
前走馬体重 | 0 |
前オッズ | 0 |
データの準備ができたので、予測をする
前回までの記事はこちら。
データの取得から前処理まで終わったところ。
データの準備ができたのでAzureMLを使って予測をする
AzureMLの設定
AzureMLのキャプチャを張りたかったのだけど、無料期間が過ぎて解約してしまったので、記事を書いた時にはもうログインができなかった。
本を見ながらやったので、大体このページと同じ設定にすると予測ができる。
今回はほんの通りロジスティック回帰を使って予測をした。
それ以外のアルゴリズムを試す前に試用期間が終わったので試していない。
最後にCSVに変換するのと、ダウンロードするというものをくっつけるとCSVでDLできるようになる。
予想の結果
今回はオッズを説明変数に入れているパターンを載せる。
結果はこんな感じで出力される。1着になりそうな上位30レコードをとってきた。
予測のデータの横に、予測の勝率が出る。
果たしてこの予測で買ったら儲かるのかを検証したいのだけど、まだできていない。
予測に起因した説明変数の上位も表示されたけど、もう解約したため見れない。
圧倒的1位は想定通りオッズでした。
予測勝率 | 実際のオッズ | 予測の逆算オッズ | 実際の着順 |
0.378983020782471 | 2.7 | 2.1 | 0 |
0.380202740430832 | 3.7 | 2.1 | 0 |
0.388832420110703 | 4.2 | 2.1 | 1 |
0.389530181884766 | 2.8 | 2.1 | 0 |
0.390958935022354 | 2 | 2.0 | 1 |
0.39361184835434 | 2.1 | 2.0 | 1 |
0.394054859876633 | 3.8 | 2.0 | 1 |
0.395985215902328 | 1.9 | 2.0 | 1 |
0.397620350122452 | 4.5 | 2.0 | 0 |
0.401534855365753 | 4.1 | 2.0 | 0 |
0.40315979719162 | 2.4 | 2.0 | 1 |
0.403720200061798 | 3 | 2.0 | 1 |
0.408076673746109 | 2.9 | 2.0 | 1 |
0.4115269780159 | 3.4 | 1.9 | 0 |
0.417304247617722 | 2.3 | 1.9 | 1 |
0.42043924331665 | 2.4 | 1.9 | 0 |
0.429091244935989 | 2 | 1.9 | 1 |
0.430251508951187 | 1.9 | 1.9 | 0 |
0.433185815811157 | 4.3 | 1.8 | 0 |
0.442336916923523 | 5.9 | 1.8 | 0 |
0.448809862136841 | 2.6 | 1.8 | 0 |
0.449275314807892 | 4 | 1.8 | 0 |
0.451326549053192 | 4.1 | 1.8 | 1 |
0.466164171695709 | 2.7 | 1.7 | 0 |
0.467372596263886 | 1.8 | 1.7 | 0 |
0.469014525413513 | 2.4 | 1.7 | 0 |
0.515306830406189 | 5 | 1.6 | 1 |
0.51767373085022 | 2.8 | 1.5 | 1 |
0.526918768882751 | 2.8 | 1.5 | 0 |
0.538346827030182 | 3.6 | 1.5 | 1 |
AzureMLの料金
Azureを使うとしきりに無料!無料!無料!無料!無料!無料!無料!無料!無料!
と表示されるので、いったいどこにお金が発生するか、何が無料なのかさっぱりわからない。
最後まで分からなかったけど、結果的には「サブスクリプション」の登録をすると月3800円かかる。
これも同意の所には無料と書かれているのでいくらなのかわからなかったけど、クレジット明細を見ると3800円だった。
無料と書いてあるのが何を指しているのかというと、3800円払うと従量課金のサーバー費用が無料になるということ。
今回競馬予想で計10回くらい処理を走らせたので、大体1000円くらいと表示された。
これは無料だった。
書いてあるのを読むとサブスクリプション代を払うと何か月かは無料になるっぽい。
競馬で勝ち馬を予測したところで儲からないと意味がない
競馬の予想を機械学習でやるにしても、勝つ馬を予測するのはオッズを見れば大体相関があるのでできる。
ただ、儲からないと意味がないので高オッズかつ勝てる馬をピンポイントで探せないと意味がない。
そういうことで、まずはオッズだけを見てお得な倍率はないのかを探ってみる
芝1200mだけに絞った2008年~2018年までの結果を分析
全3249レース、のべ出走頭数は49360頭のオッズを集計。
1倍台のオッズは492頭と、つくこと自体があまりないみたいだ。
1倍台の馬がいたときは半数程度は勝っている。
オッズ | 頭数 | 勝ち数 |
1~2倍 | 492 | 241 |
2~3倍 | 1355 | 434 |
3~5倍 | 3791 | 761 |
5~10倍 | 7628 | 899 |
10~20倍 | 8724 | 522 |
20~50倍 | 10876 | 277 |
50~1000倍 | 16494 | 115 |
全体 | 49360 | 3249 |
全体の回収率は75.2%なので、公表している控除率とほぼ同じ。
50倍以上の大穴の馬は回収率が悪い。
少なくとも芝1200mでは、大穴を狙わないほうがよさそう。
オッズ | 回収率 | 結果 |
1~2倍 | 80.2% | 49.0% |
2~3倍 | 78.1% | 32.0% |
3~5倍 | 77.7% | 20.1% |
5~10倍 | 82.0% | 11.8% |
10~20倍 | 84.7% | 6.0% |
20~50倍 | 77.0% | 2.5% |
50~1000倍 | 64.8% | 0.7% |
全体 | 75.2% | 6.6% |
過去の傾向と現在の傾向を見るため、2019年の結果を分析
全264レース、のべ出走頭数は1201頭のオッズを集計。
1倍台のオッズは45頭、過去の傾向とあまり変わりはないみたい。
1倍台の勝率は下がっている。
オッズ | 出走頭数 | 勝ち数 |
1~2倍 | 45 | 19 |
2~3倍 | 121 | 40 |
3~5倍 | 299 | 55 |
5~10倍 | 612 | 73 |
10~20倍 | 669 | 39 |
20~50倍 | 859 | 30 |
50~1000倍 | 1201 | 8 |
全体 | 3806 | 264 |
単勝の控除率が80%に変わった影響なのか、全体の回収率は上がっている。
5~20倍がおいしいのは過去の傾向と同じだけど、20~50倍がほぼ回収率100%とおいしい状況だった。
ただ、高オッズは数頭の違いで回収率に大きく影響が出るので揺れ程度の認識でよさそう。
オッズ | 回収率 | 的中率 |
1~2倍 | 69.3% | 42.2% |
2~3倍 | 82.3% | 33.1% |
3~5倍 | 71.3% | 18.4% |
5~10倍 | 82.9% | 11.9% |
10~20倍 | 84.0% | 5.8% |
20~50倍 | 99.2% | 3.5% |
50~1000倍 | 60.3% | 0.7% |
全体 | 78.5% | 6.9% |
ということで5~20倍を狙おう
ということで、今日の競馬は5~20倍を買おうと思う。
次回は機械学習した結果をどう使えば儲かりそうなのかを分析してみる。
機械学習で勝つ確率を予測してみた
AzureMLから出力されるのは馬ごとに勝つ確率が出る。
2019年芝1200メートルを走った馬について、のべ3800頭についてそれぞれ勝つ確率は〇〇%って出力される。
そのまま集計しても良かったんだけど、競馬はオッズで考えるのがしっくりくるので、予想オッズを勝率から逆算して出している。
例えば機械学習で勝率50%と出たら、1/0.5*0.8=1.6倍と出している。
オッズとの比較すると雰囲気使えるかなと思っている。
予想オッズ | 出走頭数 | 勝ち数 |
1~2倍 | 4 | 3 |
2~3倍 | 47 | 16 |
3~5倍 | 264 | 62 |
5~10倍 | 632 | 81 |
10~20倍 | 649 | 49 |
20~50倍 | 760 | 31 |
50~1000倍 | 1353 | 22 |
それ以上 | 97 | 0 |
機械学習で予測された勝ちそうな馬をそのまま買う
予想オッズの平均値を書いておくんだったと思いつつ、回収率と的中率を出してみた。
1倍台の予想が少なく4件中3件だったので回収率が高くてもたまたまだと思われる。
2〜3倍も47件しかないのでブレ幅が大きそうだけど、まあ参考程度には使えそうな感じだった。
ただ回収率が100%を超えていないのでこのモデルでは競馬で儲けるのは不可能ということが分かった。
予想オッズ | 回収率 | 的中率 |
1~2倍 | 285.0% | 75.0% |
2~3倍 | 98.9% | 34.0% |
3~5倍 | 72.2% | 23.5% |
5~10倍 | 73.2% | 12.8% |
10~20倍 | 80.7% | 7.6% |
20~50倍 | 77.3% | 4.1% |
50~1000倍 | 86.2% | 1.6% |
全体 | 0.0% | 0.0% |
オッズ>予想オッズだけを買ったとき
オッズと言うのは参加者が思う勝率と同義なので、機械学習で予想したオッズよりも高ければお得ということでお得と予想された馬だけ買ったとしたらどうなるかと分析してみた。
例えば機械学習では50%勝つと出ているのに実際のオッズが10倍だったらお得な状態としている。
そういうお得な状態は全体の3割程度起きていた。
出走頭数 | 勝ち数 | |
お得 | 1111 | 59 |
お得ではない | 2695 | 205 |
お得な状態はホントにお得だったのか
回収率を求めると全然お得ではなくてむしろ逆転していた。
機械学習を使って競馬で儲けるためにはこの実際のオッズとの乖離をいかに見つけるかだと思っているんだけど、難しそうだ。
オッズ | 回収率 | 的中率 |
お得 | 69.7% | 5.3% |
お得ではない | 82.2% | 7.6% |
まとめ
高確率で勝ちそうと予想した部分に関しては若干回収率が高くなって意味がありそうなモデルだけど、中間層は全然当たっていない。
また勝たないと予想した馬は逆に勝つことがあり、ランダムにかけるよりも少しマシな回収率になった。
azureMLはずっと前に解約したのでこれ以上の分析はできないけど、次はgoogleのBigQUERYを使ってデータの可視化から機械学習までやってみたいと思っている。