はじめに
競馬AIをいじっていたらデータの罠とも言える面白い事例に遭遇しました。
土台にしたのはこちらです。
最初は全部自分で作ろうと思っていたのですが挫折してこの書籍を購入しました。
購入者限定のGitHubリポジトリからそのままクローン出来るしコミュニティで改善のための議論も活発に行われています。おすすめです。
価格は2000円。
二値分類からランク学習へ
このAI、アルゴリズムはLightGBMで各馬が3着以内に入るか否かを予測する二値分類問題になっています。
そのままでもいい感じだったのですが「ランク学習を導入したら精度が上がるのでは」という提案を目にし自分でやってみることにしました。
ランク学習は検索エンジンなどで使われる機械学習の手法で、検索結果を適切な順に並べたりとかできます。
詳しい説明は以下の記事が参考になるのでどうぞ。
モデルを磨く
幸いなことにLightGBMにはデフォルトでlambdarankというランク学習の手法が搭載されています。
初めてのことに手こずるもなんとか移行できました。
ハイパーパラメータや目的変数をいじること3日。
ようやく納得の行くモデルが出来上がります。
テストデータは約14500レース、賭け方は単勝です。
横軸はレースにおいてAIが算出する各馬のスコアを表しています。
そのスコアをしきい値として変化させたときの回収率が縦軸です。
例えばスコア2.0以上の馬に全て賭けた場合の回収率は1.25(125%)くらいだなということが読み取れます。
馬券の数も線上に表示されていて、しきい値がスコア2.0なら2011枚です。
複勝と三連単ボックスも載せておきます。
【複勝】
【三連単ボックス】
まあ妥当な結果ですね。
問題が起きたのは馬単です。
2000%
【馬単ボックス】
目を疑いました。
回収率が最高で2000%に達しています。
しきい値2.0の時点で既に500%です。
とんでもないものを作ってしまったと思いました。
でもちょっと待ってください。
こんな初学者が出来合いのモデルを多少いじったくらいで20倍の回収率を叩き出せるわけがありません。
これは何かあるぞと思い確認してみました。
調べる
まずはヒストグラムを描きましょう。
しきい値を2.0に設定してオッズの分布を調べます。
横軸がオッズ、縦軸が馬券の数です。
もうこの時点でやばいですね。
何も見えないのにオッズの目盛りが6000まで設定されています。
これではわからないので文字にしましょう。
【馬単ボックス】
オッズ: 0 ~ 500 枚数: 536
オッズ: 500 ~ 1000 枚数: 1
[515.4]
オッズ: 1000 ~ 1500 枚数: 1
[1144.3]
オッズ: 1500 ~ 5500 枚数: 0
0.0
オッズ: 5500 ~ 6000 枚数: 1
[5984.9]
オッズの範囲ごとに馬券の枚数を出力しました。
[]でくくられているのがその範囲に存在する馬券のオッズです。
……1枚とんでもないのがありますね。
5984.9、およそ6000倍の馬券です。
グラフの右側ががくんと下がっていたのはそういうことだったのですね。
せっかくなのでどのレースか調べました。
2018年5月20日の3歳未勝利戦です。
出典:
3歳未勝利 結果・払戻 | 2018年5月20日 新潟3R レース情報(JRA) - netkeiba.com
15番人気と8番人気の馬が1着2着でフィニッシュしています。
大荒れもいいところですがこいつを当てたわけです。
馬単のオッズは……。
202番の4>1、ノーブルエイムとメモリーコバルトです。
当然ながらぴったり5984.9ですね。
なんと人気は下から9番目!
数字で見れば馬単で4位タイの払い戻し率になっています。
万馬券どころの騒ぎではありません、六十万馬券です。
もう1個、1144.3倍を当てたレースも確認してみましょう。
出典:
2歳新馬 結果・払戻 | 2021年7月25日 新潟6R レース情報(JRA) - netkeiba.com
10番人気と12番人気が1位2位でフィニッシュ。
こちらは真ん中くらいの154番人気でした。
しかし情報の少ない新馬戦を当てるとはいいのか悪いのか……。
ともかく上振れの原因がわかりました。
問題はここからです。
この十万馬券2枚なしでどこまで回収率を伸ばせるでしょうか。
しきい値を先ほどと同じ2.0に設定して計算します。
オッズ: 0 ~ 500 回収率: 0.6291966426858513
オッズ: 0 ~ 1000 回収率: 0.9348267622461172
オッズ: 0 ~ 5500 回収率: 1.6164677804295942
オッズ: 0 ~ 6000 回収率: 5.181227651966626
1144.3の馬券は0~5500、5984.9は0~6000に入ってますね。
なんということでしょう、十万馬券がなくては元を取れません。
515.4倍の馬券を手にしてようやく回収率93%です。
しきい値を2.5に上げてみましょう。
オッズ: 0 ~ 500 枚数: 147
オッズ: 500 ~ 5500 枚数: 0
0.0
オッズ: 5500 ~ 6000 枚数: 1
[5984.9]
悲しいことに515.4と1144.3の馬券は消えました。
スコア2.0~2.5の馬が含まれていたようです。
回収率はどうでしょうか。
オッズ: 0 ~ 500 回収率: 1.0870748299319726
オッズ: 0 ~ 5500 回収率: 1.0870748299319726
オッズ: 0 ~ 6000 回収率: 21.298986486486484
オッズが0~500の合計147枚だけでも元を取れるようになりました。
スコアを底上げしただけのことはあります。
しかし六十万馬券が強すぎる。
こいつが入るだけで回収率が2000%を超えます。
何年こつこつ賭ければここに辿り着くんでしょうか。
テストデータはおよそ4年分ですが4年で手に入るとは限りません。
でもまあレースを絞ればたぶん8~9%は儲けられるのでよしとしましょう。
もちろんそこに届かない可能性はあります……。
単勝の場合
比較的安定しているように見えた単勝も確認です。
【単勝しきい値2.5】
オッズ: 0 ~ 50 枚数: 592
オッズ: 50 ~ 100 枚数: 2
[74.1, 51.6]
オッズ: 100 ~ 150 枚数: 1
[127.8]
オッズ: 150 ~ 200 枚数: 2
[183.3, 178.4]
オッズ: 0 ~ 50 回収率: 0.8342818428184282
オッズ: 0 ~ 100 回収率: 1.0018918918918918
オッズ: 0 ~ 150 回収率: 1.1714285714285715
オッズ: 0 ~ 200 回収率: 1.6522147651006713
127.8倍の馬券を買えれば117%まで伸びるようです。
183.3倍と178.4倍もあれば165%。
しきい値を3.0に上げてみましょう。
【しきい値3.0】
オッズ: 0 ~ 50 枚数: 300
オッズ: 50 ~ 100 枚数: 2
[74.1, 51.6]
オッズ: 100 ~ 150 枚数: 0
0.0
オッズ: 150 ~ 200 枚数: 1
[178.4]
オッズ: 0 ~ 50 回収率: 0.8320000000000001
オッズ: 0 ~ 150 回収率: 1.2427152317880794
オッズ: 0 ~ 200 回収率: 1.8273927392739275
万馬券2枚は儚く消えました。
ただオッズ0~50のはずれ馬券が減って回収率は全体的に上がっています。
下手な万馬券を狙うよりレースを絞るほうがよさそうです。
終わりに
というわけでとんでもない外れ値には気を付けようという話でした。
しかし競馬AIは面白いですね。
やはり金という欲望に直結した題材だと学びやすいです。
みなさんも挑戦してみてはいかがでしょうか。
【おすすめ】