1 はじめに
競馬などの公営ギャンブルは全くしたことがなかったが、今年初めて友人に競馬AIを作ってみないかと誘われ、興味がでたので作成してみることにした。データのスクレイピングはすでに友人が既にしてくれていたため、それを利用して競馬自体のドメイン知識がほとんどないが、AIの作成と競馬の世界へと足を踏み入れることになった。
2 データのスクレイピングとモデルの構成
友人がネット競馬のWebサイトからひたすら5年分ぐらいのスクレイピングをしてくれたデータをありがたく使わせていただく。ネット競馬の出馬表と結果・払い戻しのサイトからデータをスクレイピングしていた。
さて、基本的なAIの構成としては、次のサイトを参考に3位以内を予測するlightGBMによる2値分類モデルの方向で検討した。予測確率をスコアとして、高い順に並び替えて順位を予測するモデルである。
「機械学習で競馬予想」をガチで作る〜「予測してみた」で終わらせないAI開発〜
ただ、これだけではやはり面白くないので、次のサイトを参考にベイズ統計モデルによる馬や騎手の強さを能力値として推定し、それを新たな特徴量として用いることにした。
もともとは、松浦さんの「StanとRでベイズ統計モデリング」の中で、将棋の棋士の強さ(レーティング)を推定するというところから、競争馬と騎手の「強さ」の統計モデルを作成されている。ここの能力値を推定する部分はR言語で作成し、事前分布に馬と騎手の力の割合を7:3とする仮定を入れて推定モデルを作成した。また、競争馬と騎手の能力値はグレード毎に持つと仮定し、G1グレードであれば、G1とG2の成績から推定、G2であればG2とG3の成績から推定など2グレードの成績から能力値の推定を行った。
3 データの訓練とバリデーションの方法、特徴量の選択
特徴量をどのように組み合わせるか?あまりドメイン知識がないこともあり「逐次前方選択(Forward Selection)」の手法を用いて、AUCの評価指標等を用い、特徴量選択を行った。訓練データは2年間のデータ、検証データは訓練データの最後から未来の1ヶ月とし、バックテスト法で時系列的に過去にさかのぼりながら、検証を行った。馬と騎手の能力値推定は、結果のリークをしないようにバックテストでさかのぼる度に、その時点で作成したものを用いた。
また、後からではあったが、賞金取得額のデータも追加でスクレイピングして、新たに特徴量とした。最終的に特徴量の組み合わせの違いで、5つのモデルができた。(全モデルに馬と騎手の能力値と人気度の特徴量があり、それに加え、他の特徴量(馬体重、調教師、天気、馬場の状態など)の組み合わせの違いとlightGBMの決定木モデルによる勾配ブースティング2値分類モデルである。実装はPythonで行った。
モデルの種類:A,B,C,D,E
(CとDは、賞金額データの特徴量を含む。特徴量の構成はCとDは同じであるが、馬の能力値をレース毎に標準化しているのがD、していないのがCの違い。Eが一番用いた特徴量は少ない。特徴量の数は、E<A<B<C=D)
4 自作AIの予測の実際
では、今年のレース事例から実際の自作AIによる予測を見てみる。
予測対象は重賞レースのみを対象とした。以下は、予測モデルCによる出力結果である。
horse_abilityの欠損率: 12.50%
horse_ability平均1.07
レース名:['武蔵野S']
レース開催場所:東京
出走馬数[16]
予想:16-1-4-3-14
予測確率[0.46636183 0.43998519 0.40528183 0.36180389 0.35414768]
馬の人気度:[2 4 1 7 5]
馬の名前:['ルクソールカフェ' 'ビダーヤ' 'コスタノヴァ' 'ロードフォンス' 'ペプチドナイル']
馬の能力値:[0.83174128 0.70327703 1.00687187 2.01971662 1.63642119]
馬の能力値(SC):[-0.37657287 -0.58625379 -0.09072259 1.56245498 0.9368355 ]
本来は、モデルとしては、3以内の確率を意味しているが、ここでは予測スコアとして予測確率を高い順に並べることで予測している。
下には、推定された競走馬の「強さ」である馬の能力値を示した。能力値は高い方が有利ではあるが、予測自体は能力値だけでなされている訳ではない。(SC)は、馬の能力値をレース内での標準化した数値である。より能力値の差をつけることを目的としている。
また、レースに出場する馬の能力値がすべて出揃っている訳ではなく、欠損が生じている。上記レースでは12・5%が欠損となっている。これはG3レースの対戦成績がない馬が出走しているために生じる。
本レースの結果は、16-4-1-15-3となった。
やはり、人気度の特徴量の貢献度が一番高く、次に馬、騎手の能力値の特徴量の貢献度が高くなっている。
5 今年のレースによる予測性能の評価
上記予測は、たまたま良く当たった事例であるため、この結果で評価するのはよくないので、自作AIの評価の検証を今年の今年の6月1日から12月20日までに開催された重賞レースを対象とし、テストデータとして評価した。
ただし、馬の能力値の欠損率が34%以上であった場合を除く46レースを対象とした。
なお、人気度だけのモデルを対照とした(すなわち人気1位を1位と予測)。
6/1~12/20
| Model | 単勝 | 回収率 |
|---|---|---|
| Popularity | 9/46 | 0.62 |
| A | 9/46 | 0.80 |
| B | 8/46 | 0.81 |
| C | 9/46 | 0.75 |
| D | 10/46 | 0.82 |
| E | 6/46 | 0.45 |
Eを除く他モデルはすべて対照より回収率は上回ったが、1を超えなかった。
本来、このモデルは3位以内を学習しているため、上位傾向を予測していると思われたので、予測5位以内をボックス買いとする10通りの3連複における回収率の検証を試みた。10通りあるので、1回当たりのコストが10倍になる。
人気度による予測の場合は人気5位以内をボックス買いする設定となる。
| Model | 3連複 | 回収率 |
|---|---|---|
| Popularity | 12/46 | 1.03 |
| A | 10/46 | 1.86 |
| B | 8/46 | 1.46 |
| C | 13/46 | 2.13 |
| D | 14/46 | 1.87 |
| E | 11/46 | 2.01 |
対照より的中率が優れていたのはC,Dであり、また回収率は全モデルで対照より優れていた。3連複はオッズの幅が広いため、たまたま当たったときの高オッズの影響を強く受けると思われる。
6 まとめ
人気度を特徴量に入れていることもあり、人気度による影響が大きく、ModelCとDが人気度による予測より、やや優れているように思えた。3連複による予想は、回収率が1を超えていたため、実際に儲かる可能性もある。ただし、たまたまの高オッズによる振れの可能性もあるため、もっと長期間にわたる検証が必要である。
こうして、今まで競馬は全く興味がなかったのですが、予測モデルを作るのが楽しくなったこともあり、競馬も見てると楽しいもんですね。
最後に、このブログを見てくれている競馬好きの先輩方にとって、どう評価されるかわかりませんが、今年の最後のビッグイベントである「有馬記念」に出走予定の馬の能力値推定の結果を掲載します。
| 馬の名前 | 能力値(現グレード) | 能力値(アンダーグレード) |
|---|---|---|
| アドマイヤテラ | 2.07 | 2.48 |
| アラタ | 0.26 | 0.86 |
| エキサイトバイオ | 1.21 | NA |
| エルトンバローズ | 2.55 | 3.06 |
| コスモキュランダ | 1.65 | 1.79 |
| サンライズアース | 0.87 | 1.04 |
| サンライズジパング | 1.43 | 2.02 |
| ジャスティンパレス | 2.41 | 2.89 |
| シュヴァリエローズ | 1.43 | 1.71 |
| シンエンペラー | 2.79 | 3.55 |
| スティンガーグラス | 0.04 | 0.55 |
| タスティエーラ | 1.83 | 2.22 |
| ダノンデサイル | 2.97 | 3.55 |
| ディマイザキッド | 1.66 | 1.99 |
| ビザンチンドリーム | 0.76 | 1.96 |
| ヘデントール | 1.68 | 2.01 |
| ミステリーウェイ | 1.27 | 1.39 |
| ミュージアムマイル | 2.41 | 2.89 |
| メイショウタバル | 0.51 | 1.67 |
| ライラック | 0.26 | 1.07 |
| レガレイラ | 2.29 | 2.74 |
さすがに有馬記念だけあって、2を超える能力値の高い馬が勢ぞろいですね。能力値の一番高いと推定された馬はダノンデサイルでした!

