はじめに
これまでの競馬AI開発メモでは、脚質・展開圧力・距離適性・馬場適性・レース間隔・馬体重・騎手変更の特徴量を個別に検証してきました。 個別検証ではそれぞれ一定の改善が見られましたが、「全部まとめたら本当に精度は上がるのか?」という疑問が残ります。
今回は、共通特徴量テーブル features_v1 を使い、すべての特徴量をまとめたモデルの予測精度を、AUC だけでなく NDCG・単勝シミュレーション・キャリブレーションなど多角的に検証します。
これまで作ってきた特徴量
| グループ | 内容 |
|---|---|
| 脚質 (running_style) | 過去走の通過順から前方指数・脚質割合などを算出 |
| 展開圧力 (pace_pressure) | 同レース内の先行馬頭数・圧力スコアなど |
| 距離適性 (distance_aptitude) | 同距離・同距離帯での過去成績 |
| 馬場適性 (going_aptitude) | 同馬場状態・道悪での過去成績 |
| レース間隔 (race_interval) | 前走からの日数・間隔区分別成績 |
| 馬体重 (body_weight) | 当日体重・変動・過去平均との比較 |
| 騎手変更 (jockey_change) | 騎手乗り替わり・騎手成績・馬×騎手成績 |
features_v1 とは何か
features_v1 は上記の特徴量をすべて統合した共通テーブルです。 レース前に使える過去走ベースの特徴量のみが含まれ、今走の着順・タイム・上り等の結果情報は含みません。 shift(1) + rolling / expanding で作成されており、リーク(未来情報の混入)を防いでいます。
馬体重関連の特徴量は馬体重発表後に使えるものとして扱います。
今回確認すること
- 個別検証で効いた特徴量は、全部まとめても効くのか
- 人気を入れると、手作り特徴量の効果は小さくなるのか
- 人気なしモデルでは features_v1 の効果が大きいか
- 人気ありモデルでは features_v1 の効果が残るか
- NDCG で見ても改善しているか
- 単勝シミュレーションで見ても改善しているか
- 高オッズ帯の過大評価が悪化していないか
- どの特徴量グループが一番効いているか
使用データ
| 項目 | 値 |
|---|---|
| データソース | features_v1 + result_table |
| 学習期間 (train) | 2017〜2022 |
| 検証期間 (valid) | 2023〜2023 |
| 評価期間 (test) | 2024〜2024 |
| 学習行数 | 787,381 |
| 検証行数 | 136,354 |
| 評価行数 | 138,372 |
| 評価レース数 | 13,677 |
| 目的変数 | 1着 (1着=1, それ以外=0) |
| 除外 | 帯広(ばんえい競馬) |
| 分割方法 | 時系列分割(ランダム分割は不使用) |
比較するモデル
LightGBM の二値分類モデル (objective=binary, early stopping on valid) を使用。 すべてのモデルでハイパーパラメータを揃えています。
表1: 比較モデル一覧
| モデル名 | 使用特徴量グループ | 人気 | 特徴量数 |
|---|---|---|---|
| A: 基本特徴量のみ | 基本 | なし | 9 |
| B: 基本+人気 | 基本, 人気 | あり | 10 |
| C: 基本+脚質 | 基本, 脚質 | なし | 21 |
| D: 基本+展開圧力 | 基本, 展開圧力 | なし | 19 |
| E: 基本+距離適性 | 基本, 距離適性 | なし | 21 |
| F: 基本+馬場適性 | 基本, 馬場適性 | なし | 20 |
| G: 基本+レース間隔 | 基本, レース間隔 | なし | 23 |
| H: 基本+馬体重 | 基本, 馬体重 | なし | 29 |
| I: 基本+騎手変更 | 基本, 騎手変更 | なし | 21 |
| J: 全部入り(人気なし) | 基本, 脚質, 展開圧力, 距離適性, 馬場適性, レース間隔, 馬体重, 馬体重欠損, 騎手変更 | なし | 100 |
| K: 全部入り(人気あり) | 基本, 脚質, 展開圧力, 距離適性, 馬場適性, レース間隔, 馬体重, 馬体重欠損, 騎手変更, 人気 | あり | 101 |
評価指標
AUC / logloss / Brier
二値分類の標準的な指標です。AUC は高いほど良く、logloss / Brier は低いほど良い結果です。
NDCG
レース内のランキング精度を測る指標です。1着=3, 2着=2, 3着=1, 4着以下=0 の relevance で計算しています。 人気順 NDCG との差分 (delta) がプラスなら、モデルが市場人気より良いランキングを出せていることを意味します。
単勝シミュレーション
各レースでモデル予測1位を1頭選び、単勝100円を購入したと仮定するシミュレーションです。参考指標として回収率・最大ドローダウン・最大連敗を算出しています。
EV候補評価
EV = 予測勝率 × 単勝オッズ の期待値が閾値以上の馬を候補として評価します。
オッズ帯別キャリブレーション
単勝オッズ帯ごとの予測勝率と実勝率の差 (calibration gap) を確認します。
人気帯別キャリブレーション
人気帯ごとの予測勝率と実勝率の差を確認します。
条件別評価
race_labels_v1 を使い、波乱レース・堅いレースなどの条件別にモデル精度を評価します(入力特徴量には使用していません)。
特徴量重要度
LightGBM の feature importance (gain / split) を確認します。
結果
表2: 通常指標 (test)
| モデル | 件数 | 正例率 | AUC | logloss | Brier |
|---|---|---|---|---|---|
| A: 基本特徴量のみ | 138,372 | 9.89% | 0.6180 | 0.3150 | 0.0878 |
| B: 基本+人気 | 138,372 | 9.89% | 0.8450 | 0.2445 | 0.0717 |
| C: 基本+脚質 | 138,372 | 9.89% | 0.7452 | 0.2861 | 0.0816 |
| D: 基本+展開圧力 | 138,372 | 9.89% | 0.7347 | 0.2896 | 0.0824 |
| E: 基本+距離適性 | 138,372 | 9.89% | 0.7316 | 0.2898 | 0.0822 |
| F: 基本+馬場適性 | 138,372 | 9.89% | 0.7208 | 0.2930 | 0.0829 |
| G: 基本+レース間隔 | 138,372 | 9.89% | 0.7073 | 0.2976 | 0.0842 |
| H: 基本+馬体重 | 138,372 | 9.89% | 0.6822 | 0.3028 | 0.0851 |
| I: 基本+騎手変更 | 138,372 | 9.89% | 0.7350 | 0.2889 | 0.0820 |
| J: 全部入り(人気なし) | 138,372 | 9.89% | 0.7893 | 0.2703 | 0.0780 |
| K: 全部入り(人気あり) | 138,372 | 9.89% | 0.8478 | 0.2427 | 0.0711 |
表3: NDCG比較 (test)
| モデル | NDCG@1 | NDCG@3 | NDCG@5 | pop NDCG@3 | delta@3 | モデル勝率 |
|---|---|---|---|---|---|---|
| A: 基本特徴量のみ | 0.2437 | 0.3507 | 0.4531 | 0.6486 | -0.2979 | 18.19% |
| B: 基本+人気 | 0.5530 | 0.6485 | 0.7306 | 0.6486 | -0.0001 | 0.16% |
| C: 基本+脚質 | 0.4156 | 0.5244 | 0.6194 | 0.6486 | -0.1242 | 23.48% |
| D: 基本+展開圧力 | 0.3657 | 0.4802 | 0.5791 | 0.6486 | -0.1684 | 22.64% |
| E: 基本+距離適性 | 0.4004 | 0.5091 | 0.6034 | 0.6486 | -0.1395 | 23.63% |
| F: 基本+馬場適性 | 0.3856 | 0.4912 | 0.5874 | 0.6486 | -0.1573 | 22.67% |
| G: 基本+レース間隔 | 0.3513 | 0.4654 | 0.5655 | 0.6486 | -0.1832 | 21.68% |
| H: 基本+馬体重 | 0.3223 | 0.4299 | 0.5298 | 0.6486 | -0.2186 | 21.25% |
| I: 基本+騎手変更 | 0.4059 | 0.5113 | 0.6037 | 0.6486 | -0.1372 | 23.49% |
| J: 全部入り(人気なし) | 0.4468 | 0.5577 | 0.6514 | 0.6486 | -0.0909 | 23.75% |
| K: 全部入り(人気あり) | 0.5530 | 0.6478 | 0.7302 | 0.6486 | -0.0008 | 2.61% |
表4: 単勝シミュレーション (test)
| モデル | 戦略 | ベット数 | 的中数 | 的中率 | 投資額 | 払戻額 | 回収率 | 最大DD | 最大連敗 |
|---|---|---|---|---|---|---|---|---|---|
| A: 基本特徴量のみ | model_top1 | 13,677 | 2,327 | 17.01% | 1,367,700 | 1062940 | 77.72% | 306500 | 45 |
| A: 基本特徴量のみ | popularity_top1 | 13,677 | 6,151 | 44.97% | 1,367,700 | 1106900 | 80.93% | 260960 | 14 |
| A: 基本特徴量のみ | model_top1_prob_ge_0.30 | 142 | 43 | 30.28% | 14,200 | 11780 | 82.96% | 3170 | 11 |
| A: 基本特徴量のみ | model_top1_odds_ge_5.0 | 8,855 | 505 | 5.70% | 885,500 | 663440 | 74.92% | 231140 | 111 |
| A: 基本特徴量のみ | model_top1_odds_ge_10.0 | 6,428 | 193 | 3.00% | 642,800 | 450620 | 70.10% | 202000 | 217 |
| B: 基本+人気 | model_top1 | 13,677 | 6,151 | 44.97% | 1,367,700 | 1106900 | 80.93% | 260960 | 14 |
| B: 基本+人気 | popularity_top1 | 13,677 | 6,151 | 44.97% | 1,367,700 | 1106900 | 80.93% | 260960 | 14 |
| B: 基本+人気 | model_top1_prob_ge_0.30 | 13,613 | 6,138 | 45.09% | 1,361,300 | 1104040 | 81.10% | 257420 | 13 |
| B: 基本+人気 | model_top1_odds_ge_5.0 | 24 | 5 | 20.83% | 2,400 | 2680 | 111.67% | 1100 | 11 |
| B: 基本+人気 | model_top1_odds_ge_10.0 | 1 | 0 | 0.00% | 100 | 0 | 0.00% | 0 | 1 |
| J: 全部入り(人気なし) | model_top1 | 13,677 | 4,770 | 34.88% | 1,367,700 | 1035580 | 75.72% | 332620 | 20 |
| J: 全部入り(人気なし) | popularity_top1 | 13,677 | 6,151 | 44.97% | 1,367,700 | 1106900 | 80.93% | 260960 | 14 |
| J: 全部入り(人気なし) | model_top1_prob_ge_0.30 | 6,760 | 2,965 | 43.86% | 676,000 | 535980 | 79.29% | 140440 | 17 |
| J: 全部入り(人気なし) | model_top1_odds_ge_5.0 | 2,446 | 211 | 8.63% | 244,600 | 163970 | 67.04% | 81690 | 68 |
| J: 全部入り(人気なし) | model_top1_odds_ge_10.0 | 724 | 31 | 4.28% | 72,400 | 48330 | 66.75% | 26000 | 95 |
| K: 全部入り(人気あり) | model_top1 | 13,677 | 6,152 | 44.98% | 1,367,700 | 1107930 | 81.01% | 259930 | 14 |
| K: 全部入り(人気あり) | popularity_top1 | 13,677 | 6,151 | 44.97% | 1,367,700 | 1106900 | 80.93% | 260960 | 14 |
| K: 全部入り(人気あり) | model_top1_prob_ge_0.30 | 13,015 | 5,966 | 45.84% | 1,301,500 | 1061580 | 81.57% | 240080 | 16 |
| K: 全部入り(人気あり) | model_top1_odds_ge_5.0 | 28 | 6 | 21.43% | 2,800 | 3240 | 115.71% | 1100 | 11 |
| K: 全部入り(人気あり) | model_top1_odds_ge_10.0 | 1 | 0 | 0.00% | 100 | 0 | 0.00% | 0 | 1 |
表5: EV候補評価 (test)
| モデル | EV閾値 | 件数 | 予測勝率 | 実勝率 | cal.gap | 平均オッズ | 回収率 |
|---|---|---|---|---|---|---|---|
| J: 全部入り(人気なし) | >=1.0 | 75,533 | 8.66% | 3.40% | 0.0526 | 84.1 | 63.84% |
| J: 全部入り(人気なし) | >=1.1 | 69,997 | 8.49% | 3.07% | 0.0542 | 87.6 | 63.21% |
| J: 全部入り(人気なし) | >=1.2 | 65,056 | 8.34% | 2.77% | 0.0556 | 90.9 | 62.70% |
| K: 全部入り(人気あり) | >=1.0 | 53,392 | 7.87% | 4.56% | 0.0331 | 94.1 | 62.86% |
| K: 全部入り(人気あり) | >=1.1 | 44,588 | 7.09% | 3.75% | 0.0335 | 102.5 | 62.15% |
| K: 全部入り(人気あり) | >=1.2 | 37,368 | 6.36% | 3.08% | 0.0328 | 110.8 | 59.88% |
表6: オッズ帯別キャリブレーション (test, J: 全部入り人気なし)
| オッズ帯 | 件数 | 予測勝率 | 実勝率 | cal.gap | logloss | Brier | 回収率 |
|---|---|---|---|---|---|---|---|
| 1.0-1.9 | 7,211 | 33.29% | 56.83% | -0.2354 | 0.8468 | 0.3085 | 82.36% |
| 2.0-2.9 | 7,863 | 23.07% | 32.30% | -0.0924 | 0.7057 | 0.2409 | 77.54% |
| 3.0-4.9 | 12,860 | 17.54% | 20.19% | -0.0264 | 0.5426 | 0.1711 | 76.57% |
| 5.0-9.9 | 20,680 | 12.53% | 11.43% | 0.0110 | 0.3851 | 0.1081 | 78.51% |
| 10.0-19.9 | 20,849 | 8.87% | 5.67% | 0.0320 | 0.2391 | 0.0581 | 78.32% |
| 20.0-49.9 | 27,077 | 6.09% | 2.56% | 0.0353 | 0.1408 | 0.0284 | 78.80% |
| 50.0+ | 41,832 | 2.90% | 0.50% | 0.0240 | 0.0479 | 0.0063 | 48.21% |
表7: 人気帯別キャリブレーション (test, J: 全部入り人気なし)
| 人気帯 | 件数 | 予測勝率 | 実勝率 | cal.gap | logloss | Brier | 回収率 |
|---|---|---|---|---|---|---|---|
| 1 | 13,677 | 27.40% | 44.97% | -0.1758 | 0.7796 | 0.2753 | 80.93% |
| 2-3 | 27,353 | 16.26% | 16.44% | -0.0019 | 0.4703 | 0.1434 | 75.32% |
| 4-5 | 27,329 | 9.57% | 6.57% | 0.0300 | 0.2582 | 0.0654 | 71.55% |
| 6-9 | 49,881 | 5.04% | 2.25% | 0.0279 | 0.1189 | 0.0240 | 69.07% |
| 10+ | 20,132 | 2.24% | 0.57% | 0.0167 | 0.0439 | 0.0063 | 51.01% |
表8: 条件別評価 (test)
| モデル | 条件 | レース数 | AUC | NDCG@3 | delta@3 | sim ROI | EV>=1.0 gap | 高オッズ帯gap |
|---|---|---|---|---|---|---|---|---|
| J: 全部入り(人気なし) | 全レース | 13,677 | 0.7893 | 0.5577 | -0.0909 | 75.72% | 0.0526 | 0.0293 |
| J: 全部入り(人気なし) | 1番人気が勝ったレース | 6,151 | 0.9173 | 0.7184 | -0.1557 | 101.96% | 0.0817 | 0.0533 |
| J: 全部入り(人気なし) | 1番人気が負けたレース | 7,526 | 0.6813 | 0.4264 | -0.0378 | 54.27% | 0.0271 | 0.0088 |
| J: 全部入り(人気なし) | 6番人気以下が勝ったレース | 1,237 | 0.4321 | 0.2037 | 0.0146 | 23.71% | -0.0352 | -0.0870 |
| J: 全部入り(人気なし) | 8番人気以下が勝ったレース | 418 | 0.3424 | 0.1576 | -0.0177 | 3.61% | -0.0501 | -0.0853 |
| J: 全部入り(人気なし) | 単勝10倍以上が勝ったレース | 2,084 | 0.4936 | 0.2521 | 0.0204 | 23.26% | -0.0248 | -0.0874 |
| J: 全部入り(人気なし) | 単勝20倍以上が勝ったレース | 902 | 0.3967 | 0.1970 | -0.0096 | 9.79% | -0.0442 | -0.0872 |
| J: 全部入り(人気なし) | 人気順NDCG@3が低いレース | 3,447 | 0.5910 | 0.2827 | 0.0399 | 39.09% | 0.0093 | -0.0214 |
| K: 全部入り(人気あり) | 全レース | 13,677 | 0.8478 | 0.6478 | -0.0008 | 81.01% | 0.0331 | 0.0077 |
| K: 全部入り(人気あり) | 1番人気が勝ったレース | 6,151 | 0.9996 | 0.8735 | -0.0006 | 179.80% | 0.0308 | 0.0331 |
| K: 全部入り(人気あり) | 1番人気が負けたレース | 7,526 | 0.7199 | 0.4633 | -0.0010 | 0.26% | 0.0355 | -0.0139 |
| K: 全部入り(人気あり) | 6番人気以下が勝ったレース | 1,237 | 0.3732 | 0.1871 | -0.0019 | 0.12% | 0.0216 | -0.1096 |
| K: 全部入り(人気あり) | 8番人気以下が勝ったレース | 418 | 0.2494 | 0.1715 | -0.0039 | 0.36% | 0.0269 | -0.1068 |
| K: 全部入り(人気あり) | 単勝10倍以上が勝ったレース | 2,084 | 0.4837 | 0.2337 | 0.0020 | 0.17% | -0.0166 | -0.1089 |
| K: 全部入り(人気あり) | 単勝20倍以上が勝ったレース | 902 | 0.3621 | 0.2048 | -0.0018 | 0.17% | -0.0332 | -0.1079 |
| K: 全部入り(人気あり) | 人気順NDCG@3が低いレース | 3,447 | 0.6109 | 0.2473 | 0.0044 | 0.12% | 0.0333 | -0.0447 |
表9: 特徴量重要度 (J: 全部入り人気なし)
上位30特徴量 (gain)
| 順位 | 特徴量 | gain | split |
|---|---|---|---|
| 1 | front_index_rank_in_race | 104340.2 | 136 |
| 2 | front_index_gap_to_top | 103294.1 | 378 |
| 3 | past3_avg_rank | 98062.8 | 410 |
| 4 | past3_top3_rate | 47237.7 | 62 |
| 5 | horse_jockey_top3_rate_raw | 35678.3 | 407 |
| 6 | jockey_top3_rate_raw | 33111.9 | 505 |
| 7 | past5_avg_rank | 30734.0 | 246 |
| 8 | jockey_win_rate_raw | 28850.6 | 364 |
| 9 | same_distance_bin_avg_rank | 27038.9 | 355 |
| 10 | race_avg_front_index | 26632.2 | 675 |
| 11 | pace_pressure_score | 26419.8 | 513 |
| 12 | body_weight_percentile_in_race | 23847.4 | 481 |
| 13 | same_distance_avg_rank | 20458.9 | 428 |
| 14 | front_index_percentile_in_race | 18955.2 | 215 |
| 15 | jockey_win_rate_smoothed_a5 | 18279.8 | 281 |
| 16 | recent_avg_interval_5 | 17224.2 | 519 |
| 17 | horse_jockey_win_rate_raw | 16202.6 | 312 |
| 18 | past5_top3_rate | 15159.2 | 76 |
| 19 | 同走馬の数 | 14638.3 | 449 |
| 20 | days_since_last_run | 11219.6 | 524 |
| 21 | race_max_front_index | 10205.1 | 380 |
| 22 | distance_diff_from_past_avg | 10081.5 | 461 |
| 23 | same_distance_bin_win_rate | 9289.6 | 241 |
| 24 | recent_avg_interval_3 | 8565.2 | 399 |
| 25 | same_distance_bin_top3_rate | 7345.1 | 227 |
| 26 | wet_going_runs | 7228.1 | 284 |
| 27 | style_stability | 7143.8 | 391 |
| 28 | same_going_avg_rank | 6991.5 | 335 |
| 29 | 距離 | 6493.6 | 282 |
| 30 | wet_going_avg_rank | 6322.6 | 325 |
特徴量グループ別重要度 (gain)
| グループ | 特徴量数 | gain合計 | gain平均 |
|---|---|---|---|
| 展開圧力 | 10 | 299248.3 | 29924.8 |
| 脚質 | 12 | 219150.5 | 18262.5 |
| 騎手変更 | 12 | 141177.7 | 11764.8 |
| 距離適性 | 12 | 91413.8 | 7617.8 |
| 馬体重 | 17 | 71841.1 | 4225.9 |
| レース間隔 | 14 | 51062.4 | 3647.3 |
| 基本 | 9 | 42451.4 | 4716.8 |
| 馬場適性 | 11 | 36335.0 | 3303.2 |
| 馬体重欠損 | 3 | 135.3 | 45.1 |
表10: Ablation 結果 (全部入り人気なしから1グループずつ除外)
| 除外グループ | 特徴量数 | AUC | logloss | Brier | NDCG@3 |
|---|---|---|---|---|---|
| (なし=全部入り) | 100 | 0.7893 | 0.2703 | 0.0780 | 0.5577 |
| 馬体重 | 83 | 0.7874 | 0.2710 | 0.0782 | 0.5564 |
| 馬体重欠損 | 97 | 0.7891 | 0.2703 | 0.0780 | 0.5587 |
| 距離適性 | 88 | 0.7872 | 0.2712 | 0.0783 | 0.5541 |
| 馬場適性 | 89 | 0.7891 | 0.2703 | 0.0780 | 0.5578 |
| 騎手変更 | 88 | 0.7813 | 0.2734 | 0.0787 | 0.5459 |
| 展開圧力 | 90 | 0.7726 | 0.2767 | 0.0796 | 0.5559 |
| レース間隔 | 86 | 0.7877 | 0.2709 | 0.0782 | 0.5555 |
| 脚質 | 88 | 0.7849 | 0.2718 | 0.0783 | 0.5517 |
考察
全部入り特徴量で精度は上がったか
baseline (A) の AUC は 0.6180 に対し、全部入り人気なし (J) は 0.7893 (+0.1713) でした。
人気なしモデルでの効果
人気を使わないモデルでは、features_v1 の特徴量をまとめることで明確な改善が見られました。
人気ありモデルでの効果
人気あり baseline (B) の AUC は 0.8450 に対し、全部入り人気あり (K) は 0.8478 (+0.0027) でした。 人気を入れても手作り特徴量の追加効果が残っています。
NDCG やシミュレーションでも改善したか
NDCG@3 は baseline (A) 0.3507 → 全部入り (J) 0.5577 (+0.2071) でした。
高オッズ帯の過大評価は悪化していないか
オッズ帯 20.0-49.9: calibration gap = 0.0353 オッズ帯 50.0+: calibration gap = 0.0240
高オッズ帯の calibration gap は比較的小さく、大きな過大評価は見られません。
どの特徴量グループが効いたか
gain 合計が大きい上位3グループは 展開圧力, 脚質, 騎手変更 でした。
逆にノイズになった特徴量はあるか
ablation の結果、除外して明確に AUC が上がるグループはありませんでした。
features_v1 を今後使う価値はあるか
features_v1 を使うことで、個別特徴量を毎回自前で作る手間が省けます。 今回の検証では全部入りモデルで baseline を上回る精度が得られており、今後の実験のベースとして使う価値があると考えられます。
まとめ
これまで個別に検証してきた特徴量を features_v1 としてまとめ、全部入りモデルの予測精度を多角的に評価しました。 人気なしモデルでは AUC が baseline 比 +0.1713 の改善を確認できました。 人気ありモデルでも AUC が baseline 比 +0.0027 の改善が見られました。 AUC だけでなく NDCG・キャリブレーション・特徴量重要度なども確認し、総合的な評価を行いました。
