競馬AIの回収率100%は、なぜ再現しないのか
- AUC 0.839・1着的中率30%まで来ても、機械的に買えば回収率は0.6〜0.95で止まった
- 一度は「エッジを見つけた」と判断し、撤回した。正体はデータの欠け
- 疑う順番はモデルより先にデータ。同じ期間・対象の参照結果と、出走馬・着順・払戻を照合する
精度が上がることと、増えることは別物だった
まず数字から。過去10年ぶんのJRAデータで学習させたモデルは、6か月ぶんを学習に使わずに残して評価して、AUC 0.839・1着的中率30%・3着内67%まで来ました。数字だけ見れば十分に機能しています。
ところが同じモデルの予測で機械的に買うと、本命の単勝・複勝、3連複ボックス、期待値でしぼる買い方——どれも回収率0.6〜0.95に収まりました。控除率を超えられません。
順位を当てる能力と、オッズに対して割に合う馬を見つける能力は、別々のものです。前者が高いだけでは後者にはなりません。ここを混同したまま「精度が出たので回収率も出るはず」と進むと、あとの検証がすべて甘くなります。
リークは3層ある。3層目はあまり語られていない
予測に未来の情報が混ざることをデータリークと呼びます。競馬AIの解説記事でよく挙がるのは最初の2層です。
1層目は分かりやすい未来情報。着順、走破タイム、上がり、通過順、確定オッズ、確定人気。レースが終わらないと確定しない値を特徴量に入れてしまう形です。
2層目は集計の作り方によるもの。騎手の勝率のような「過去の平均」を作るとき、集計対象にそのレース自身が入っていると、答えの一部を特徴量に埋め込んだことになります。過去だけを見るようにずらす処理が要ります。
評価データが欠けるという3層目
3層目が、私が実際につまずいたところです。特徴量は正しく作れていても、評価に使うデータの方が欠けていると、リークと同じように成績が水増しされます。この層はあまり書かれていません。
| 層 | どこで混ざるか | 本文で挙がった中身 |
|---|---|---|
| 1層目 | 分かりやすい未来情報 | 着順、走破タイム、上がり、通過順、確定オッズ、確定人気 |
| 2層目 | 集計の作り方 | 騎手の勝率などの集計対象にそのレース自身が入っている |
| 3層目 | 評価に使うデータ | 特徴量は正しくてもデータが欠けて成績が水増しされる |
「エッジを見つけた」を撤回した話
オッズを使わないモデルを作ったとき、市場より優れた判断ができているように見える結果が出ました。検定にもかけて、統計的にも支持されたと判断しました。
数え直して分かったこと
おかしいと思って評価データを数え直したところ、レースの66%で出走馬が欠けていました。18頭立てのはずが3頭しか入っていないレースがあり、37%のレースでは勝ち馬すら含まれていませんでした。
何が起きていたか。欠けていたのは主に人気薄です。よく走る馬ほど過去データが揃っているので、集計に残りやすい。結果、評価データは「堅い馬だけの世界」になっていました。その世界では市場1番人気の単勝回収率が1.13になります。回収率が高いことだけで欠損とは断定できませんが、この評価では出走馬の欠落も確認できました。
つまり見つけたのはエッジではなく、データの欠けでした。検定の数字は正しく計算されていましたが、入力が現実と違っていました。結論は撤回しています。
公開前に確認したい3つの点
この経験を踏まえ、公開前には次の3点を確かめる必要があります。
1つめ。市場1番人気の単勝回収率を、同じ期間・レース範囲・計算法の参照データと照合します。控除率だけから正常値の範囲は決まりません。参照値からずれたら、まず抽出条件や欠損を調べます。
2つめ。公式の確定結果と照合し、同着を含む勝ち馬が欠けていないかを確認します。3つめ。出走馬IDの集合・頭数を参照結果と比べ、重複・欠損を調べます。取消・除外・競走中止も区別し、行数と着順の最大値が合うだけで完全とは判定しません。
閾値を200%に置くと見逃す
「ROIが異常に高かったらデータを疑う」という目安だけでは十分ではありません。閾値を200%のように置くと、今回の1.13の水増しは素通りします。同じ条件の参照結果と、馬ごとの記録を照合することが必要です。
- 過去で準備する学習や条件選びは過去のデータで行う
- 予想を確定するその時点で取得できた情報だけを使う
- 未使用の期間で評価確定した予想と、その後の結果を照合
- 改善は次の評価へ結果を見た変更を、元の評価に混ぜない
時間の向きは一方向。あとから分かった情報を、過去の予想時点へ戻さない。
オッズを入れると、モデルは市場の写しになる
オッズや人気を特徴量に入れると精度は明確に上がります。私のモデルでも、重要度の上位4つを市場系の特徴が独占し、合計で83%を占めました。
ただし中身を見ると、モデルの本命は市場の1番人気と91%一致していました。ほぼ同じことを言っているだけです。
さらに、意見が割れた61レースだけを取り出すと、モデルの的中14.8%に対し市場は29.5%でした。食い違ったときは市場のほうが当たっていたわけです。オッズ入りモデルの高い精度は、市場をうまく再現できているという意味であって、市場に勝てるという意味ではありませんでした。
オッズを抜くと、何が見えたか
そこで市場の情報を完全に外したモデルも作りました。精度は当然落ちます。AUCは0.839から0.788へ、1着的中率は30%から24%へ。
代わりに独立性が手に入りました。オッズを±20%動かしても、欠損させても、予測はまったく変わりません。参照していないので当然です。市場との本命一致率も91%から58%に下がりました。別の意見を言うモデルになったということです。
この独立したモデルでは、いくつかの買い方で学習期間・検証期間の両方で回収率が1.0を超えました。ただし該当したのは50〜100件程度で、この件数では誤差の範囲を出ません。有望な兆しではありますが、確かめられたとは言えない段階です。
| 指標 | オッズ入り | オッズを抜く |
|---|---|---|
| AUC | 0.839 | 0.788 |
| 1着的中率 | 30% | 24% |
| 市場との本命一致率 | 91% | 58% |
それでも壁は越えられていない
ここまでやって、私はまだ持続的なプラス収支を確認できていません。控除率という構造が、思っていたより厚いというのが現時点の結論です。
誤解のないように書いておくと、モデルを作ること自体は無駄ではありませんでした。どの条件が3着内と着外を分けているかは実際に見えるようになりましたし、このサイトの重賞メタ読みはその副産物です。ただ、それは「見え方が整理される」ことであって、「増える」ことではありません。
回収率100%超えを掲げた記事を読むときは、検証期間の長さ、買った件数、そして評価データが欠けていないかを見てみてください。私の場合、そこに原因がありました。
- 回収率100%超えの記事で先に見るのは、検証期間の長さと買った件数
- オッズを特徴量に入れたモデルは、本命が市場1番人気と何%一致するかを数える
- 自分で集計するときは、同着・取消・除外・中止を区別し、出走馬IDの重複と欠損を確かめる