はじめに
これまでの記事では、脚質・展開圧力・距離適性・馬場適性・レース間隔・馬体重・騎手特徴量など、主に「特徴量追加」による勝率モデルの精度改善を検証してきました。評価指標は AUC / logloss / Brier score が中心でした。
今後は特徴量追加だけでなく、学習重みの変更・ランキング学習・波乱レース重み付け・オッズ帯別キャリブレーション・堅いレース / 波乱レース用のモデル分離といった仕組みの検証をしていきたいと考えています。 その前段階として本記事では、今後のモデル比較で使う「評価基盤」を整理し、再利用しやすい関数として実装しました。
なぜAUCだけでは不十分なのか
AUC は「予測スコアの順位が良いか」を評価する指標としては便利ですが、実運用では以下のような弱点があります。
- 確率の正しさ(キャリブレーション)を直接評価しない
- レース内で人気順より上手いランキングを作れているかは分かりにくい
- 回収率とは直接一致しない
- 高オッズ馬の過大評価を見逃すことがある
logloss / Brier score は確率精度を測れますが、これも「レース単位で人気順に勝てているか」を直接見る指標ではありません。 そこで、本記事では以下を組み合わせて評価します。
- AUC / logloss / Brier(基本指標)
- レース内 NDCG(ランキング精度)
- 人気順 NDCG との差分(人気順に対する相対的な強さ)
- 単勝シミュレーション(回収率・最大ドローダウン・最大連敗)
- EV候補評価(期待値ベース候補の実性能)
- オッズ帯別 / 人気帯別キャリブレーション
- 人気集中度別評価(堅い / 荒れる レースでの挙動)
今回確認すること
- 勝率モデルの AUC が同等でも、レース内ランキング(NDCG)や回収率で差は出るか
- 「人気なしモデル」と「人気ありモデル」の差はどう見えるか
- モデルは人気順に対して勝てているか / どの条件で勝ちやすいか
- 高オッズ帯・EV候補で予測勝率と実勝率にどの程度ズレがあるか
使用データ
- テーブル:
result_table - 学習期間: 2017〜2022 年(787,381 件)
- 検証期間: 2023〜2023 年(136,354 件, early stopping)
- 評価期間: 2024〜2024 年(138,372 件, レース数 13,677)
- 帯広(ばんえい競馬)は除外(124,418 行)
評価対象モデル
以下2種類の LightGBM 勝率モデルを比較対象としました。ハイパーパラメータは共通です。
- 人気なしモデル: 距離・馬番・枠番・斤量・馬体重・馬体重増減・年齢・同走馬の数・月・曜日・過去3走平均着順・過去3走3着内率(すべて shift(1)→rolling で作成)
- 人気ありモデル: 上記に
人気を追加
確定オッズ(単勝)は学習特徴量に一切使っていません。 評価時のシミュレーション・参考指標としてのみ利用しています。
評価指標の定義
AUC / logloss / Brier
- AUC: 1着馬とその他馬の予測スコアの順序が正しいか
- logloss: 予測勝率と実際の勝敗(0/1)のクロスエントロピー
- Brier: 予測勝率と実際の勝敗の二乗誤差平均
レース内 NDCG
レースを1つのランキングタスクとみなし、モデルの予測順位が実際の着順にどれだけ近いかを NDCG で計算します。 relevance は以下で定義しました。
- 1着 = 3
- 2着 = 2
- 3着 = 1
- 4着以下 = 0
レース単位に NDCG@1 / NDCG@3 / NDCG@5 を計算し、全レース平均を取ります。
人気順 NDCG との差分
モデル予測スコアで並べた NDCG に加え、単勝人気順(1番人気を最上位)で並べた NDCG も計算し、その差分を見ます。
delta_ndcg@3 = model_ndcg@3 - popularity_ndcg@3delta_ndcg@3 > 0.02なら model_beats_popularitydelta_ndcg@3 < -0.02なら model_loses_to_popularity- それ以外は tie
閾値 0.02 は本記事の判定用に暫定的に設定した値です。今後の記事では変更する可能性があります。
単勝シミュレーション
各レースで対象スコアが最大の1頭を選び、単勝100円を購入したと仮定した場合の ベット数 / 的中率 / 投資額 / 払戻額 / 回収率 / 最大ドローダウン / 最大連敗数 を計算します。 参考指標として、単勝シミュレーション上の回収率も確認します(馬券購入の推奨ではありません)。
EV候補評価
EV = 予測勝率 × 単勝オッズ を計算し、EV≥1.0 / 1.1 / 1.2 の候補について 件数 / 予測勝率 / 実勝率 / calibration gap / 平均オッズ / 単勝回収率 を計算します。 確定オッズは学習には使わず、評価時のみに使います。
オッズ帯別キャリブレーション
単勝オッズ帯(1.0-1.9 / 2.0-2.9 / 3.0-4.9 / 5.0-9.9 / 10.0-19.9 / 20.0-49.9 / 50.0+)ごとに、件数 / 平均予測勝率 / 実勝率 / calibration gap / logloss / Brier / 帯全体を購入したときの単勝回収率 を出します。
人気帯別キャリブレーション
人気帯(1 / 2-3 / 4-5 / 6-9 / 10+)ごとに、上記と同様の指標を計算します。
比較方法
- テスト期間(時系列分割の評価期間)でのみ集計する
- 人気が欠損している行は該当集計から除外する
- レース単位 NDCG では、着順が確定していないレースは対象外
- 単勝シミュレーションは 1頭×100円 の単勝購入のみ扱う
- 数値はすべて DB の実データから計算されており、架空の値は含まない
結果
通常指標
表1: 通常指標
| モデル | 件数 | 正例率 | AUC | logloss | Brier |
|---|---|---|---|---|---|
| 人気なしモデル | 138,372 | 0.0989 | 0.7359 | 0.2891 | 0.0822 |
| 人気ありモデル | 138,372 | 0.0989 | 0.8459 | 0.2438 | 0.0715 |
NDCG 比較
表2: NDCG 比較(モデル vs 人気順)
| モデル | model_ndcg@1 | model_ndcg@3 | popularity_ndcg@1 | popularity_ndcg@3 | delta_ndcg@3 | 人気順に勝ったレース率 |
|---|---|---|---|---|---|---|
| 人気なしモデル | 0.4053 | 0.5119 | 0.5530 | 0.6486 | -0.1367 | 23.40% |
| 人気ありモデル | 0.5529 | 0.6479 | 0.5530 | 0.6486 | -0.0007 | 0.96% |
単勝シミュレーション
表3: 単勝シミュレーション(人気なしモデル)
| 戦略 | ベット数 | 的中数 | 的中率 | 投資額 | 払戻額 | 回収率 | 最大DD | 最大連敗 |
|---|---|---|---|---|---|---|---|---|
| モデル予測1位 | 13,677 | 4,224 | 30.88% | 1,367,700円 | 1028250円 | 0.7518 | 340330円 | 28 |
| 人気1位 | 13,677 | 6,151 | 44.97% | 1,367,700円 | 1106900円 | 0.8093 | 260960円 | 14 |
| モデル予測1位 & 予測勝率≥0.30 | 3,749 | 1,629 | 43.45% | 374,900円 | 295390円 | 0.7879 | 80920円 | 18 |
| モデル予測1位 & オッズ≥5.0 | 3,781 | 287 | 7.59% | 378,100円 | 263260円 | 0.6963 | 117540円 | 78 |
表3-2: 単勝シミュレーション(人気ありモデル)
| 戦略 | ベット数 | 的中数 | 的中率 | 投資額 | 払戻額 | 回収率 | 最大DD | 最大連敗 |
|---|---|---|---|---|---|---|---|---|
| モデル予測1位 | 13,677 | 6,150 | 44.97% | 1,367,700円 | 1107130円 | 0.8095 | 260730円 | 14 |
| 人気1位 | 13,677 | 6,151 | 44.97% | 1,367,700円 | 1106900円 | 0.8093 | 260960円 | 14 |
| モデル予測1位 & 予測勝率≥0.30 | 13,416 | 6,073 | 45.27% | 1,341,600円 | 1088660円 | 0.8115 | 253100円 | 17 |
| モデル予測1位 & オッズ≥5.0 | 27 | 6 | 22.22% | 2,700円 | 3220円 | 1.1926 | 760円 | 7 |
EV候補評価
表4: EV候補評価(人気なしモデル)
| 閾値EV | 件数 | 予測勝率 | 実勝率 | calibration gap | 平均オッズ | 単勝回収率 |
|---|---|---|---|---|---|---|
| EV≥1.0 | 84,083 | 0.0892 | 0.0285 | 0.0607 | 85.61 | 0.6213 |
| EV≥1.1 | 79,926 | 0.0880 | 0.0260 | 0.0620 | 89.02 | 0.6181 |
| EV≥1.2 | 76,150 | 0.0869 | 0.0236 | 0.0633 | 92.30 | 0.6086 |
表4-2: EV候補評価(人気ありモデル)
| 閾値EV | 件数 | 予測勝率 | 実勝率 | calibration gap | 平均オッズ | 単勝回収率 |
|---|---|---|---|---|---|---|
| EV≥1.0 | 53,050 | 0.0805 | 0.0461 | 0.0345 | 93.75 | 0.5890 |
| EV≥1.1 | 44,366 | 0.0728 | 0.0374 | 0.0354 | 101.83 | 0.5646 |
| EV≥1.2 | 37,200 | 0.0652 | 0.0309 | 0.0344 | 109.95 | 0.5619 |
オッズ帯別キャリブレーション
表5: オッズ帯別キャリブレーション(人気なしモデル)
| オッズ帯 | 件数 | 予測勝率 | 実勝率 | calibration gap | logloss | Brier | 単勝回収率(帯全体) |
|---|---|---|---|---|---|---|---|
| 1.0-1.9 | 7,211 | 0.2408 | 0.5683 | -0.3275 | 0.9923 | 0.3577 | 0.8236 |
| 2.0-2.9 | 7,863 | 0.1830 | 0.3230 | -0.1401 | 0.7393 | 0.2468 | 0.7754 |
| 3.0-4.9 | 12,860 | 0.1515 | 0.2019 | -0.0504 | 0.5568 | 0.1727 | 0.7657 |
| 5.0-9.9 | 20,680 | 0.1212 | 0.1143 | 0.0069 | 0.3836 | 0.1075 | 0.7851 |
| 10.0-19.9 | 20,849 | 0.0981 | 0.0567 | 0.0414 | 0.2444 | 0.0595 | 0.7832 |
| 20.0-49.9 | 27,077 | 0.0773 | 0.0256 | 0.0517 | 0.1521 | 0.0305 | 0.7880 |
| 50.0+ | 41,832 | 0.0477 | 0.0050 | 0.0427 | 0.0651 | 0.0082 | 0.4821 |
表5-2: オッズ帯別キャリブレーション(人気ありモデル)
| オッズ帯 | 件数 | 予測勝率 | 実勝率 | calibration gap | logloss | Brier | 単勝回収率(帯全体) |
|---|---|---|---|---|---|---|---|
| 1.0-1.9 | 7,211 | 0.4649 | 0.5683 | -0.1034 | 0.7005 | 0.2535 | 0.8236 |
| 2.0-2.9 | 7,863 | 0.3504 | 0.3230 | 0.0274 | 0.6470 | 0.2266 | 0.7754 |
| 3.0-4.9 | 12,860 | 0.2012 | 0.2019 | -0.0007 | 0.5111 | 0.1643 | 0.7657 |
| 5.0-9.9 | 20,680 | 0.1115 | 0.1143 | -0.0027 | 0.3624 | 0.1027 | 0.7851 |
| 10.0-19.9 | 20,849 | 0.0631 | 0.0567 | 0.0064 | 0.2255 | 0.0546 | 0.7832 |
| 20.0-49.9 | 27,077 | 0.0339 | 0.0256 | 0.0083 | 0.1253 | 0.0255 | 0.7880 |
| 50.0+ | 41,832 | 0.0125 | 0.0050 | 0.0075 | 0.0345 | 0.0051 | 0.4821 |
人気帯別キャリブレーション
表6: 人気帯別キャリブレーション(人気なしモデル)
| 人気帯 | 件数 | 予測勝率 | 実勝率 | calibration gap | logloss | Brier | 単勝回収率(帯全体) |
|---|---|---|---|---|---|---|---|
| 1 | 13,677 | 0.2055 | 0.4497 | -0.2442 | 0.8752 | 0.3052 | 0.8093 |
| 2-3 | 27,353 | 0.1456 | 0.1644 | -0.0188 | 0.4772 | 0.1435 | 0.7532 |
| 4-5 | 27,329 | 0.1037 | 0.0657 | 0.0380 | 0.2647 | 0.0669 | 0.7155 |
| 6-9 | 49,881 | 0.0675 | 0.0225 | 0.0450 | 0.1318 | 0.0259 | 0.6907 |
| 10+ | 20,132 | 0.0381 | 0.0057 | 0.0324 | 0.0580 | 0.0075 | 0.5101 |
表6-2: 人気帯別キャリブレーション(人気ありモデル)
| 人気帯 | 件数 | 予測勝率 | 実勝率 | calibration gap | logloss | Brier | 単勝回収率(帯全体) |
|---|---|---|---|---|---|---|---|
| 1 | 13,677 | 0.4434 | 0.4497 | -0.0064 | 0.6763 | 0.2417 | 0.8093 |
| 2-3 | 27,353 | 0.1646 | 0.1644 | 0.0002 | 0.4400 | 0.1355 | 0.7532 |
| 4-5 | 27,329 | 0.0690 | 0.0657 | 0.0032 | 0.2401 | 0.0611 | 0.7155 |
| 6-9 | 49,881 | 0.0233 | 0.0225 | 0.0008 | 0.1044 | 0.0219 | 0.6907 |
| 10+ | 20,132 | 0.0071 | 0.0057 | 0.0015 | 0.0342 | 0.0056 | 0.5101 |
人気集中度別の比較
1番人気の単勝オッズを人気集中度の代理指標として、レース単位の NDCG 勝敗を集計します。
人気なしモデル: 1番人気オッズ帯別
| 1番人気オッズ帯 | レース数 | モデル勝 | モデル負 | 引分 | モデル勝率 | model_ndcg@3 | popularity_ndcg@3 | delta_ndcg@3 |
|---|---|---|---|---|---|---|---|---|
| solid(1.5-2.5) | 7,311 | 1,676 | 4,367 | 1,268 | 22.92% | 0.5114 | 0.6557 | -0.1443 |
| very_solid(<1.5) | 3,029 | 558 | 1,659 | 812 | 18.42% | 0.6502 | 0.7740 | -0.1237 |
| moderate(2.5-4.0) | 3,157 | 916 | 1,808 | 433 | 29.01% | 0.3952 | 0.5274 | -0.1322 |
| wild(>=4.0) | 180 | 50 | 101 | 29 | 27.78% | 0.2519 | 0.3758 | -0.1239 |
人気ありモデル: 1番人気オッズ帯別
| 1番人気オッズ帯 | レース数 | モデル勝 | モデル負 | 引分 | モデル勝率 | model_ndcg@3 | popularity_ndcg@3 | delta_ndcg@3 |
|---|---|---|---|---|---|---|---|---|
| solid(1.5-2.5) | 7,311 | 69 | 96 | 7,146 | 0.94% | 0.6552 | 0.6557 | -0.0004 |
| very_solid(<1.5) | 3,029 | 18 | 29 | 2,982 | 0.59% | 0.7732 | 0.7740 | -0.0007 |
| moderate(2.5-4.0) | 3,157 | 43 | 64 | 3,050 | 1.36% | 0.5260 | 0.5274 | -0.0014 |
| wild(>=4.0) | 180 | 1 | 1 | 178 | 0.56% | 0.3758 | 0.3758 | 0.0000 |
人気なしモデル: 頭数別
| 頭数帯 | レース数 | モデル勝 | モデル負 | 引分 | モデル勝率 | model_ndcg@3 | popularity_ndcg@3 | delta_ndcg@3 |
|---|---|---|---|---|---|---|---|---|
| medium(9-12) | 10,249 | 2,370 | 5,985 | 1,894 | 23.12% | 0.4969 | 0.6375 | -0.1406 |
| small(<=8) | 2,619 | 648 | 1,516 | 455 | 24.74% | 0.5871 | 0.7172 | -0.1301 |
| large(>=13) | 809 | 182 | 434 | 193 | 22.50% | 0.4583 | 0.5667 | -0.1084 |
人気ありモデル: 距離帯別
| 距離帯 | レース数 | モデル勝 | モデル負 | 引分 | モデル勝率 | model_ndcg@3 | popularity_ndcg@3 | delta_ndcg@3 |
|---|---|---|---|---|---|---|---|---|
| mile(1400-1799) | 9,049 | 72 | 112 | 8,865 | 0.80% | 0.6477 | 0.6484 | -0.0007 |
| short(<1400) | 4,102 | 50 | 63 | 3,989 | 1.22% | 0.6504 | 0.6513 | -0.0008 |
| middle(1800-2199) | 490 | 9 | 13 | 468 | 1.84% | 0.6305 | 0.6307 | -0.0002 |
| long(>=2200) | 36 | 0 | 2 | 34 | 0.00% | 0.6265 | 0.6368 | -0.0104 |
考察
AUCが良くても回収率が良いとは限らない
AUC は順序性を測る指標なので、確率の絶対値やレース単位でのランキングとは切り離されて評価されます。本記事のテーブルでも、AUC の差と回収率・NDCG の差は必ずしも同じ向きに動きません。評価は AUC / logloss / Brier / NDCG / ROI / キャリブレーションを併記して総合的に判断すべきだと考えます。
モデルは人気順に勝てているか
NDCG@3 で人気順とモデル予測を直接比較しました。人気順は非常に強いベースラインです。人気なしモデルは人気順に肉薄できるか、モデル勝ちレース率がどの程度に落ち着くかを、上の表2および人気集中度別の表で確認できます。
高オッズ馬を過大評価していないか
オッズ帯別・人気帯別のキャリブレーションテーブルで、高オッズ帯(10倍以上)や下位人気帯の 予測勝率 - 実勝率(calibration gap)に注目します。gap が正に大きいほど過大評価です。EV候補評価も同様で、EV≥1.0 の候補について予測勝率と実勝率の差、単勝回収率を確認しています。
EV候補の実勝率は予測勝率に追いついているか
EV≥1.0 / 1.1 / 1.2 と閾値を上げるほど候補数が絞られ分散が大きくなります。実勝率が予測勝率に追いついているか、単勝回収率が 1.0 を超えているかは、テスト期間の1年評価だけでは判断できません。今後は複数年での安定性を見る必要があります。
今後のモデル比較で重視すべき指標
本記事のテーブル群を、以下の検証で共通の評価基盤として使う想定です。
- オッズ帯別に学習重みを変えると予測精度は上がるのか
- 人気薄を重く学習すると高オッズ馬の見極めは改善するのか
- 波乱レースを重く学習すると荒れるレースに強くなるのか
- ランキング学習は勝率モデルよりレース内順位を改善するのか
- オッズ帯別キャリブレーションで期待値評価は改善するのか
- 堅いレース用モデル・波乱レース用モデルを分けると精度は上がるのか
まとめ
- AUC / logloss / Brier だけでは勝率モデルの実運用上の性能は測りきれない
- レース内 NDCG と人気順 NDCG の差分は「モデルが人気順に対してどれだけ有利か」を直感的に見せてくれる
- 単勝シミュレーション(回収率・最大DD・最大連敗)は分散が大きく、単年評価だけで判断しない
- オッズ帯別 / 人気帯別のキャリブレーションで、高オッズ帯の過大評価を可視化できる
- 本記事で作った評価関数を今後の学習重み・ランキング学習・キャリブレーション補正の記事で共通利用する

