競馬AI開発メモ:騎手乗り替わり特徴量とスパース対策は予測精度を上げるのか?

競馬AI開発

はじめに

地方競馬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,65039.8%
前走と同じ騎手(継続)592,14155.8%
前走なし(初出走等)47,3164.5%

組み合わせ履歴数の分布

馬×騎手

履歴件数割合
0走277,12326.1%
1走157,61314.8%
2走110,77510.4%
3-4走148,46814.0%
5-9走184,17817.3%
10走以上183,95017.3%

騎手×調教師

履歴件数割合
0走27,4632.6%
1走18,5891.8%
2走15,8491.5%
3-4走27,5472.6%
5-9走56,3455.3%
10走以上916,31486.3%

騎手×競馬場

履歴件数割合
0走3,3020.3%
1走2,7550.3%
2走2,2540.2%
3-4走3,7660.4%
5-9走7,2550.7%
10走以上1,042,77598.2%

騎手×距離帯

履歴件数割合
0走1,7800.2%
1走1,6460.2%
2走1,5540.1%
3-4走2,9000.3%
5-9走6,5310.6%
10走以上1,047,69698.6%

騎手単体

履歴件数割合
0走5370.1%
1走5250.0%
2走5160.0%
3-4走1,0200.1%
5-9走2,4820.2%
10走以上1,057,02799.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_rawraw rate
jockey_trainer_has_history履歴ありフラグ
jockey_trainer_less_than_5_runs履歴5走未満フラグ

F. 騎手×競馬場・距離の過去成績

特徴量名内容
jockey_place_runs騎手×競馬場の過去出走数
jockey_place_win_rate_raw / _top3_rate_rawraw rate
jockey_place_less_than_10_runs履歴10走未満フラグ
jockey_distance_bin_runs騎手×距離帯の過去出走数
jockey_distance_bin_win_rate_raw / _top3_rate_rawraw rate

距離帯の定義

距離帯範囲
sprint〜1200m
mile1201〜1700m
middle1701〜2100m
long2101m〜

スパース対策

1. raw rate

win_rate_raw = wins / runs の単純な過去率。件数が少ないと極端な値になりやすい。

2. count特徴量

raw rate と一緒に *_runs を投入し、モデルに「この率が何件から作られたか」を伝える。

3. 履歴不足フラグ

has_historyless_than_3_runsless_than_5_runsless_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

特徴量セットAUCloglossBrierAUC差logloss差
A: baseline0.73420.28950.0823
B: 乗り替わり基本0.73790.28830.0820+0.0037-0.0012
C: raw rate0.76000.28130.0805+0.0258-0.0082
D: raw + count0.76080.28110.0805+0.0266-0.0084
E: raw + count + flag0.76060.28110.0804+0.0264-0.0084
F: smoothed α=30.76040.28130.0805+0.0262-0.0082
G: smoothed α=50.76010.28130.0805+0.0259-0.0082
H: smoothed α=100.76090.28100.0805+0.0267-0.0085
I: min_count fallback0.76080.28110.0804+0.0266-0.0084
J: 階層フォールバック0.75950.28170.0806+0.0253-0.0078
K: recency weighted0.75300.28390.0811+0.0188-0.0056
ALL0.76140.28080.0804+0.0272-0.0087

人気なしでは ALL が最もAUCを改善しました(+0.0272)。

人気ありモデル:1着予測

ベースライン AUC(テスト期間): 0.8459

特徴量セットAUCloglossBrierAUC差logloss差
A: baseline0.84590.24380.0714
B: 乗り替わり基本0.84580.24380.0714-0.0001+0.0000
C: raw rate0.84650.24340.0713+0.0006-0.0004
D: raw + count0.84620.24360.0713+0.0003-0.0002
E: raw + count + flag0.84600.24370.0714+0.0001-0.0001
F: smoothed α=30.84600.24370.0713+0.0001-0.0001
G: smoothed α=50.84630.24360.0713+0.0004-0.0002
H: smoothed α=100.84580.24380.0714-0.0001+0.0000
I: min_count fallback0.84600.24370.0714+0.0001-0.0001
J: 階層フォールバック0.84630.24360.0713+0.0004-0.0002
K: recency weighted0.84540.24410.0714-0.0005+0.0003
ALL0.84610.24370.0713+0.0002-0.0001

人気ありでは C: raw rate がわずかにAUCを改善しました(+0.0006)。

補助検証:3着内予測(人気なし)

ベースライン AUC(テスト期間): 0.7195

特徴量セットAUCloglossBrierAUC差logloss差
A: baseline0.71950.54230.1820
B: 乗り替わり基本0.72230.54040.1812+0.0028-0.0019
C: raw rate0.74130.52770.1764+0.0218-0.0146
D: raw + count0.74150.52750.1764+0.0220-0.0148
E: raw + count + flag0.74160.52750.1763+0.0221-0.0148
F: smoothed α=30.74080.52810.1765+0.0213-0.0142
G: smoothed α=50.74050.52830.1766+0.0210-0.0140
H: smoothed α=100.74070.52820.1766+0.0212-0.0141
I: min_count fallback0.74040.52840.1767+0.0209-0.0139
J: 階層フォールバック0.73940.52900.1770+0.0199-0.0133
K: recency weighted0.73490.53240.1781+0.0154-0.0099
ALL0.74210.52720.1762+0.0226-0.0151

スパース対策別の比較(人気なし・1着)

同じ raw rate ベースに対して、count / flag / smoothed / min_count / hierarchical を追加したときのAUC変化を並べています。

対策特徴量セットAUCAUC差(vs A_baseline)
なし(baseline)A: baseline0.7342
raw rate のみC: raw rate0.7600+0.0258
+ countD: raw + count0.7608+0.0266
+ count + flagsE: raw + count + flag0.7606+0.0264
smoothed α=3F: smoothed α=30.7604+0.0262
smoothed α=5G: smoothed α=50.7601+0.0259
smoothed α=10H: smoothed α=100.7609+0.0267
min_count fallbackI: min_count fallback0.7608+0.0266
階層フォールバックJ: 階層フォールバック0.7595+0.0253
recency weightedK: recency weighted0.7530+0.0188
ALLALL0.7614+0.0272

alpha 別比較(smoothed rate)

alphaAUCloglossBrier
α=30.76040.28130.0805
α=50.76010.28130.0805
α=100.76090.28100.0805

特徴量重要度(人気なし・1着・ALL)

特徴量名importance (gain)
past3_avg_rank179319.6
past3_top3_rate111947.6
horse_jockey_avg_rank55570.9
jockey_trainer_top3_rate_fallback48992.5
jockey_trainer_win_rate_smoothed_a524580.7
馬体重23751.6
同走馬の数18318.9
距離13823.5
horse_jockey_win_rate_raw13488.9
horse_jockey_runs13221.2
年齢12401.2
horse_jockey_top3_rate_fallback10978.7
jockey_place_win_rate_raw9294.3
jockey_trainer_runs9278.3
jockey_place_top3_rate_smoothed_a59015.6

条件別分析(人気なし・1着・ALLモデル vs baseline)

条件内での baseline AUC と ALL_jockey_sparse_features モデルの AUC を並べています。 条件別AUCの絶対値は難易度差の影響を受けるため、差分(jockey – baseline) を重視して見てください。

条件nbaseline AUCjockey model AUC差分
騎手乗り替わりあり571920.71180.7470+0.0352
騎手継続騎乗758780.74710.7681+0.0210
馬×騎手履歴あり1016100.74550.7675+0.0220
馬×騎手履歴なし367620.70370.7441+0.0404
馬×騎手過去1走のみ207150.75160.7759+0.0243
馬×騎手過去3走以上664290.73670.7574+0.0207
騎手×調教師履歴あり1359180.73460.7618+0.0272
騎手×調教師履歴なし24540.70310.7291+0.0260
騎手過去50走未満11850.73770.7494+0.0117
騎手過去500走以上1306500.73330.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件
人気なしベースライン AUC0.7342
人気なし最良モデル AUC0.7614 (ALL)
人気ありベースライン AUC0.8459
人気あり最良モデル AUC0.8465 (C: raw rate)

タイトルとURLをコピーしました