はじめに
地方競馬AIの特徴量エンジニアリング検証シリーズとして、今回は「騎手乗り替わり」と、騎手・馬×騎手・騎手×調教師などの過去成績特徴量に対する スパース対策 の効果を比較します。
過去成績特徴量は履歴が少ない組み合わせで値が不安定になりやすく、1回だけ騎乗して1着なら勝率100%、1回だけ凡走なら勝率0%になってしまうため、そのまま特徴量にすると過学習しやすくなります。
今回確認すること
- 騎手乗り替わり特徴量はLightGBMの1着予測AUCを改善するか
- スパース対策(count / 履歴フラグ / smoothed rate / 階層フォールバック / min_count / recency)はそれぞれ効くか
- 人気なし/人気ありの2条件で効果に差があるか
- 条件別(乗り替わりあり/馬×騎手履歴あり/履歴なし など)で改善度合いは変わるか
なぜ騎手特徴量はスパースになりやすいのか
騎手や騎手を含む組み合わせ(馬×騎手・騎手×調教師・騎手×競馬場・騎手×距離帯)は、同じ組み合わせで積み上げられる履歴数が非常に少なくなりがちです。
- 馬×騎手: 一頭が同じ騎手を何度も乗せるとは限らない
- 騎手×調教師: 調教師と組む騎手は多く、1〜2回しか組まないケースが大量にある
- 騎手×競馬場: 遠征騎手が単発で騎乗するケースが多い
- 騎手×距離帯: 短距離しか騎乗しない騎手、長距離しか騎乗しない馬 など偏りが大きい
履歴が1〜2走しかない状態で単純な勝率・3着内率を計算すると、0%・100% の両極端な値だらけになり、モデルが過学習しやすくなります。 そのため今回は、複数のスパース対策を比較しました。
使用データ
- テーブル:
result_table - 学習期間: 2017-01-01 ~ 2022-12-31 — 787,381件
- 検証期間: 2023-01-01 ~ 2023-12-31 — 136,354件
- 評価期間: 2024-01-01 ~ 2024-12-31 — 138,372件
- 合計: 1,062,107件
- 帯広除外: 124418件
正例率(1着)
- 学習: 0.1000
- 検証: 0.0999
- 評価: 0.0989
分割方法
時系列順にデータを分割しています(ランダム分割は使用していません)。
学習: 2017-01-01 ~ 2022-12-31
検証: 2023-01-01 ~ 2023-12-31 (early stopping)
評価: 2024-01-01 ~ 2024-12-31 (最終評価)
騎手乗り替わりの分布
テスト期間を含む全体(学習+検証+評価)における騎手乗り替わり分布です。
| 状態 | 件数 | 割合 |
|---|---|---|
| 前走から騎手が替わった | 422,650 | 39.8% |
| 前走と同じ騎手(継続) | 592,141 | 55.8% |
| 前走なし(初出走等) | 47,316 | 4.5% |
組み合わせ履歴数の分布
馬×騎手
| 履歴 | 件数 | 割合 |
|---|---|---|
| 0走 | 277,123 | 26.1% |
| 1走 | 157,613 | 14.8% |
| 2走 | 110,775 | 10.4% |
| 3-4走 | 148,468 | 14.0% |
| 5-9走 | 184,178 | 17.3% |
| 10走以上 | 183,950 | 17.3% |
騎手×調教師
| 履歴 | 件数 | 割合 |
|---|---|---|
| 0走 | 27,463 | 2.6% |
| 1走 | 18,589 | 1.8% |
| 2走 | 15,849 | 1.5% |
| 3-4走 | 27,547 | 2.6% |
| 5-9走 | 56,345 | 5.3% |
| 10走以上 | 916,314 | 86.3% |
騎手×競馬場
| 履歴 | 件数 | 割合 |
|---|---|---|
| 0走 | 3,302 | 0.3% |
| 1走 | 2,755 | 0.3% |
| 2走 | 2,254 | 0.2% |
| 3-4走 | 3,766 | 0.4% |
| 5-9走 | 7,255 | 0.7% |
| 10走以上 | 1,042,775 | 98.2% |
騎手×距離帯
| 履歴 | 件数 | 割合 |
|---|---|---|
| 0走 | 1,780 | 0.2% |
| 1走 | 1,646 | 0.2% |
| 2走 | 1,554 | 0.1% |
| 3-4走 | 2,900 | 0.3% |
| 5-9走 | 6,531 | 0.6% |
| 10走以上 | 1,047,696 | 98.6% |
騎手単体
| 履歴 | 件数 | 割合 |
|---|---|---|
| 0走 | 537 | 0.1% |
| 1走 | 525 | 0.0% |
| 2走 | 516 | 0.0% |
| 3-4走 | 1,020 | 0.1% |
| 5-9走 | 2,482 | 0.2% |
| 10走以上 | 1,057,027 | 99.5% |
上記の通り、馬×騎手 や 騎手×調教師 では 0〜2走の履歴しかない組み合わせが多数を占めます。raw rate をそのまま使うと、「1戦1勝で100%」「1戦0勝で0%」といった極端な値が大量発生し、過学習を招きやすい状態です。
作成した騎手特徴量
A. baseline
騎手・乗り替わり系の特徴量を含まないベースライン。 距離・馬番・枠番・斤量・馬体重・馬体重増減・年齢・同走馬の数・月・曜日・過去3走平均着順・過去3走3着内率を使用しています。
B. 騎手乗り替わり基本特徴量
| 特徴量名 | 内容 |
|---|---|
is_jockey_changed | 前走から騎手が替わったか(0/1、前走なしはNaN) |
is_same_jockey_as_last_run | 前走と同じ騎手か(0/1) |
jockey_continuation_count | 同一騎手の連続騎乗回数(過去のみ) |
recent_jockey_change_count_3 | 直近3走の乗り替わり回数 |
recent_jockey_change_count_5 | 直近5走の乗り替わり回数 |
C. 騎手単体の過去成績(raw rate)
| 特徴量名 | 内容 |
|---|---|
jockey_runs | 過去出走数(今走含めない) |
jockey_win_rate_raw | 過去1着率(raw) |
jockey_top3_rate_raw | 過去3着内率(raw) |
jockey_avg_rank | 過去平均着順 |
jockey_recent_win_rate_30d / _90d | 直近30日 / 90日の1着率 |
jockey_recent_top3_rate_30d / _90d | 直近30日 / 90日の3着内率 |
D. 馬×騎手の過去成績
| 特徴量名 | 内容 |
|---|---|
horse_jockey_runs | その馬×騎手コンビの過去出走数 |
horse_jockey_win_rate_raw | コンビの過去1着率(raw) |
horse_jockey_top3_rate_raw | コンビの過去3着内率(raw) |
horse_jockey_avg_rank | コンビの過去平均着順 |
horse_jockey_has_history | 過去にこのコンビで出走した経験 |
horse_jockey_less_than_3_runs | 履歴が3走未満のフラグ |
E. 騎手×調教師の過去成績
| 特徴量名 | 内容 |
|---|---|
jockey_trainer_runs | 騎手×調教師の過去出走数 |
jockey_trainer_win_rate_raw / _top3_rate_raw | raw rate |
jockey_trainer_has_history | 履歴ありフラグ |
jockey_trainer_less_than_5_runs | 履歴5走未満フラグ |
F. 騎手×競馬場・距離の過去成績
| 特徴量名 | 内容 |
|---|---|
jockey_place_runs | 騎手×競馬場の過去出走数 |
jockey_place_win_rate_raw / _top3_rate_raw | raw rate |
jockey_place_less_than_10_runs | 履歴10走未満フラグ |
jockey_distance_bin_runs | 騎手×距離帯の過去出走数 |
jockey_distance_bin_win_rate_raw / _top3_rate_raw | raw rate |
距離帯の定義
| 距離帯 | 範囲 |
|---|---|
| sprint | 〜1200m |
| mile | 1201〜1700m |
| middle | 1701〜2100m |
| long | 2101m〜 |
スパース対策
1. raw rate
win_rate_raw = wins / runs の単純な過去率。件数が少ないと極端な値になりやすい。
2. count特徴量
raw rate と一緒に *_runs を投入し、モデルに「この率が何件から作られたか」を伝える。
3. 履歴不足フラグ
has_history, less_than_3_runs, less_than_5_runs, less_than_10_runs などのフラグで、モデルが履歴不足サンプルを識別できるようにする。
4. smoothed rate(ベイズ縮約)
smoothed = (success + alpha * prior) / (runs + alpha)。 prior は学習期間の全体率(1着 prior=0.1、3着内 prior=0.2998)を使用。 alpha=3, 5, 10 の3種類を比較。
5. 階層フォールバック
horse_jockey_top3_rate_fallback: 馬×騎手履歴が十分(≥3走)ならその smoothed rate、そうでなければ騎手単体(≥10走)の smoothed rate、それでも足りなければ全体 prior にフォールバックjockey_trainer_top3_rate_fallback: 騎手×調教師 → 騎手 → 全体jockey_place_top3_rate_fallback: 騎手×競馬場 → 騎手 → 全体
6. min_count 閾値
各特徴量ごとに閾値を設定し、runs < 閾値 の場合は raw rate を使わずに smoothed_a5 に置き換える。
- 馬×騎手: 閾値=3
- 騎手×調教師: 閾値=5
- 騎手×競馬場: 閾値=10
- 騎手単体: 閾値=10
7. recency weighted rate
騎手の直近30日 / 90日以内の 1着率・3着内率を time-based rolling で算出(今走は closed=’left’ で除外)。 騎手の調子や近況を反映する。
比較方法
各特徴量セット(A〜ALL)に対して、LightGBMで 1着予測(および 3着内予測)モデルを時系列分割で学習し、テスト期間のAUC・logloss・Brier score を比較しました。
- 2条件: 人気なし / 人気あり
- NaN は学習データの中央値で補完
- カテゴリ変数は学習セットのみで label encoding、未知値は 0(missing)に mapping
結果
人気なしモデル:1着予測
ベースライン AUC(テスト期間): 0.7342
| 特徴量セット | AUC | logloss | Brier | AUC差 | logloss差 |
|---|---|---|---|---|---|
| A: baseline | 0.7342 | 0.2895 | 0.0823 | – | – |
| B: 乗り替わり基本 | 0.7379 | 0.2883 | 0.0820 | +0.0037 | -0.0012 |
| C: raw rate | 0.7600 | 0.2813 | 0.0805 | +0.0258 | -0.0082 |
| D: raw + count | 0.7608 | 0.2811 | 0.0805 | +0.0266 | -0.0084 |
| E: raw + count + flag | 0.7606 | 0.2811 | 0.0804 | +0.0264 | -0.0084 |
| F: smoothed α=3 | 0.7604 | 0.2813 | 0.0805 | +0.0262 | -0.0082 |
| G: smoothed α=5 | 0.7601 | 0.2813 | 0.0805 | +0.0259 | -0.0082 |
| H: smoothed α=10 | 0.7609 | 0.2810 | 0.0805 | +0.0267 | -0.0085 |
| I: min_count fallback | 0.7608 | 0.2811 | 0.0804 | +0.0266 | -0.0084 |
| J: 階層フォールバック | 0.7595 | 0.2817 | 0.0806 | +0.0253 | -0.0078 |
| K: recency weighted | 0.7530 | 0.2839 | 0.0811 | +0.0188 | -0.0056 |
| ALL | 0.7614 | 0.2808 | 0.0804 | +0.0272 | -0.0087 |
人気なしでは ALL が最もAUCを改善しました(+0.0272)。
人気ありモデル:1着予測
ベースライン AUC(テスト期間): 0.8459
| 特徴量セット | AUC | logloss | Brier | AUC差 | logloss差 |
|---|---|---|---|---|---|
| A: baseline | 0.8459 | 0.2438 | 0.0714 | – | – |
| B: 乗り替わり基本 | 0.8458 | 0.2438 | 0.0714 | -0.0001 | +0.0000 |
| C: raw rate | 0.8465 | 0.2434 | 0.0713 | +0.0006 | -0.0004 |
| D: raw + count | 0.8462 | 0.2436 | 0.0713 | +0.0003 | -0.0002 |
| E: raw + count + flag | 0.8460 | 0.2437 | 0.0714 | +0.0001 | -0.0001 |
| F: smoothed α=3 | 0.8460 | 0.2437 | 0.0713 | +0.0001 | -0.0001 |
| G: smoothed α=5 | 0.8463 | 0.2436 | 0.0713 | +0.0004 | -0.0002 |
| H: smoothed α=10 | 0.8458 | 0.2438 | 0.0714 | -0.0001 | +0.0000 |
| I: min_count fallback | 0.8460 | 0.2437 | 0.0714 | +0.0001 | -0.0001 |
| J: 階層フォールバック | 0.8463 | 0.2436 | 0.0713 | +0.0004 | -0.0002 |
| K: recency weighted | 0.8454 | 0.2441 | 0.0714 | -0.0005 | +0.0003 |
| ALL | 0.8461 | 0.2437 | 0.0713 | +0.0002 | -0.0001 |
人気ありでは C: raw rate がわずかにAUCを改善しました(+0.0006)。
補助検証:3着内予測(人気なし)
ベースライン AUC(テスト期間): 0.7195
| 特徴量セット | AUC | logloss | Brier | AUC差 | logloss差 |
|---|---|---|---|---|---|
| A: baseline | 0.7195 | 0.5423 | 0.1820 | – | – |
| B: 乗り替わり基本 | 0.7223 | 0.5404 | 0.1812 | +0.0028 | -0.0019 |
| C: raw rate | 0.7413 | 0.5277 | 0.1764 | +0.0218 | -0.0146 |
| D: raw + count | 0.7415 | 0.5275 | 0.1764 | +0.0220 | -0.0148 |
| E: raw + count + flag | 0.7416 | 0.5275 | 0.1763 | +0.0221 | -0.0148 |
| F: smoothed α=3 | 0.7408 | 0.5281 | 0.1765 | +0.0213 | -0.0142 |
| G: smoothed α=5 | 0.7405 | 0.5283 | 0.1766 | +0.0210 | -0.0140 |
| H: smoothed α=10 | 0.7407 | 0.5282 | 0.1766 | +0.0212 | -0.0141 |
| I: min_count fallback | 0.7404 | 0.5284 | 0.1767 | +0.0209 | -0.0139 |
| J: 階層フォールバック | 0.7394 | 0.5290 | 0.1770 | +0.0199 | -0.0133 |
| K: recency weighted | 0.7349 | 0.5324 | 0.1781 | +0.0154 | -0.0099 |
| ALL | 0.7421 | 0.5272 | 0.1762 | +0.0226 | -0.0151 |
スパース対策別の比較(人気なし・1着)
同じ raw rate ベースに対して、count / flag / smoothed / min_count / hierarchical を追加したときのAUC変化を並べています。
| 対策 | 特徴量セット | AUC | AUC差(vs A_baseline) |
|---|---|---|---|
| なし(baseline) | A: baseline | 0.7342 | – |
| raw rate のみ | C: raw rate | 0.7600 | +0.0258 |
| + count | D: raw + count | 0.7608 | +0.0266 |
| + count + flags | E: raw + count + flag | 0.7606 | +0.0264 |
| smoothed α=3 | F: smoothed α=3 | 0.7604 | +0.0262 |
| smoothed α=5 | G: smoothed α=5 | 0.7601 | +0.0259 |
| smoothed α=10 | H: smoothed α=10 | 0.7609 | +0.0267 |
| min_count fallback | I: min_count fallback | 0.7608 | +0.0266 |
| 階層フォールバック | J: 階層フォールバック | 0.7595 | +0.0253 |
| recency weighted | K: recency weighted | 0.7530 | +0.0188 |
| ALL | ALL | 0.7614 | +0.0272 |
alpha 別比較(smoothed rate)
| alpha | AUC | logloss | Brier |
|---|---|---|---|
| α=3 | 0.7604 | 0.2813 | 0.0805 |
| α=5 | 0.7601 | 0.2813 | 0.0805 |
| α=10 | 0.7609 | 0.2810 | 0.0805 |
特徴量重要度(人気なし・1着・ALL)
| 特徴量名 | importance (gain) |
|---|---|
past3_avg_rank | 179319.6 |
past3_top3_rate | 111947.6 |
horse_jockey_avg_rank | 55570.9 |
jockey_trainer_top3_rate_fallback | 48992.5 |
jockey_trainer_win_rate_smoothed_a5 | 24580.7 |
馬体重 | 23751.6 |
同走馬の数 | 18318.9 |
距離 | 13823.5 |
horse_jockey_win_rate_raw | 13488.9 |
horse_jockey_runs | 13221.2 |
年齢 | 12401.2 |
horse_jockey_top3_rate_fallback | 10978.7 |
jockey_place_win_rate_raw | 9294.3 |
jockey_trainer_runs | 9278.3 |
jockey_place_top3_rate_smoothed_a5 | 9015.6 |
条件別分析(人気なし・1着・ALLモデル vs baseline)
条件内での baseline AUC と ALL_jockey_sparse_features モデルの AUC を並べています。 条件別AUCの絶対値は難易度差の影響を受けるため、差分(jockey – baseline) を重視して見てください。
| 条件 | n | baseline AUC | jockey model AUC | 差分 |
|---|---|---|---|---|
| 騎手乗り替わりあり | 57192 | 0.7118 | 0.7470 | +0.0352 |
| 騎手継続騎乗 | 75878 | 0.7471 | 0.7681 | +0.0210 |
| 馬×騎手履歴あり | 101610 | 0.7455 | 0.7675 | +0.0220 |
| 馬×騎手履歴なし | 36762 | 0.7037 | 0.7441 | +0.0404 |
| 馬×騎手過去1走のみ | 20715 | 0.7516 | 0.7759 | +0.0243 |
| 馬×騎手過去3走以上 | 66429 | 0.7367 | 0.7574 | +0.0207 |
| 騎手×調教師履歴あり | 135918 | 0.7346 | 0.7618 | +0.0272 |
| 騎手×調教師履歴なし | 2454 | 0.7031 | 0.7291 | +0.0260 |
| 騎手過去50走未満 | 1185 | 0.7377 | 0.7494 | +0.0117 |
| 騎手過去500走以上 | 130650 | 0.7333 | 0.7610 | +0.0277 |
考察
騎手乗り替わり特徴量は効いたか
B (乗り替わり基本のみ) はベースラインを +0.0037 改善しました。騎手乗り替わり情報単体でも一定の予測力があるようです。
スパース対策は効いたか
count / flag の追加(E vs C)は +0.0006 と微改善に留まりました。 smoothed rate(α=5)は raw rate 単独に対して +0.0001。 階層フォールバックは raw rate 単独に対して -0.0005。
raw rate は過学習しやすいか
raw rate 単独でもベースラインより +0.0258 改善しており、生の勝率にも一定の情報量があることが分かります。
count や履歴不足フラグは効いたか
count 特徴量を加えた D は C に対して +0.0008。 履歴不足フラグを加えた E は D に対して -0.0002。
smoothed rate は効いたか
alpha 別の AUC 変化から、prior に寄せる強さの最適点を評価します。
- 今回の実験では α=10 が最良で AUC=0.7609 でした。
人気ありモデルとの差
人気なしの方が改善幅が大きく、騎手情報の一部は市場人気に織り込まれている可能性があります。
条件別に見て効きやすかったところ
条件別の差分(jockey – baseline)は 馬×騎手履歴なし で最大 (+0.0404)、騎手過去50走未満 で最小(+0.0117)でした。 騎手系特徴量が特に効きやすい条件はサンプルの多い履歴あり組み合わせの傾向がありました。
まとめ
地方競馬データを用いて、騎手乗り替わり特徴量と、騎手・馬×騎手・騎手×調教師などの過去成績特徴量に対するスパース対策を LightGBM で比較しました。
| 項目 | 値 |
|---|---|
| 評価対象データ | テスト期間 2024-01-01 ~ 2024-12-31 |
| テストデータ件数 | 138,372件 |
| 人気なしベースライン AUC | 0.7342 |
| 人気なし最良モデル AUC | 0.7614 (ALL) |
| 人気ありベースライン AUC | 0.8459 |
| 人気あり最良モデル AUC | 0.8465 (C: raw rate) |

