競馬AI予測

【競馬AI #10】システム完全再構築。回収率0%からの再スタート

プロローグ:見たくなかった数字

2026年5月2日(土)。

新しいシステムでの初実戦。

期待を込めて予測を実行した。

リベルタアーラ(11番人気、35.0倍):
  予測勝率: 27.9%
  期待値: 876.9%

…は?

876.9%?

11番人気の馬が、27.9%の確率で勝つ?

明らかにおかしい。

この瞬間から、数時間に及ぶ格闘が始まった。


📊 第10週の結果

5/2(土)

投票なし

理由: システム不具合のため

異常な予測値を見て、即座に運用を停止した。

5/3(日)

システムを完全に作り直し、新システムで再挑戦。

項目数値
ベット数12頭
投資額1,200円
払戻額0円
収支-1,200円
回収率0.0%
的中数0頭
的中率0.0%

12頭すべて外れ。

厳しい結果だが、これは後で分析する。


🔍 システム不具合の発見

異常な予測値

5/2朝、race20260502.csvで予測を実行した。

出力された推奨馬リスト:

リベルタアーラ(11番人気、35.0倍):
  予測勝率: 27.9%
  期待値: 876.9% ← ありえない

アムールドパリ(15番人気、57.7倍):
  予測勝率: 3.4%
  期待値: 96.9% ← 異常

ロックウイズユー(5番人気、10.7倍):
  予測勝率: 16.0%
  期待値: 70.7% ← おかしい

11番人気が27.9%で勝つ?

期待値876.9%?

完全に壊れている。

第8週・第9週も同じ症状

遡って確認すると、第8週・第9週の惨敗も同じ原因だった。

第8週: 回収率41.7%
第9週: 回収率5.1%

→ システムのバグが原因

つまり、第8週から壊れていた


💡 原因究明の記録

仮説1: モデルファイルが壊れている?

まず、モデルを単体でテスト:

11番人気、35.0倍の馬を予測:
  予測勝率: 1.86%
  期待値: -34.92%

✅ モデルは正常

モデルは正しく動作している。

仮説2: 予測スクリプトに問題?

スクリプトのコードを確認:

predicted_probs = model.predict_proba(X)[:, 1]

✅ コードも正常

スクリプトも問題なし。

仮説3: データの前処理?

CSVから読み込んだリベルタアーラのデータを確認:

馬名: リベルタアーラ
人気: 11
オッズ: 35.0
芝ダ: 芝
距離: 2000
性別: 牝
年齢: 3

データも正常。

決定的な発見

実際の特徴量で予測してみた:

11番人気、35.0倍、2000m、牝、3歳:
  予測勝率: 27.91%
  期待値: 876.92%

❌ 異常!

でも、デフォルト値(1600m、牡、4歳)で予測すると:

11番人気、35.0倍、1600m、牡、4歳:
  予測勝率: 1.86%
  期待値: -34.92%

✅ 正常

特定の特徴量の組み合わせで異常な予測をする。

根本原因

さらに調査を進めた結果、判明した。

問題の特徴量:odds_popularity_gap

これは、オッズと人気の差を表す派生特徴量:

odds_popularity_gap = オッズ - (人気 × 2)

この特徴量が、モデルを混乱させていた。

特に:

  • 距離が長い(2000m)
  • 牝馬
  • 若い(3歳)

これらの組み合わせで、異常な予測をする。

つまり、モデルが過学習していた。


🔧 完全再構築

方針

派生特徴量をすべて削除し、基本特徴量のみで再学習する。

削除した特徴量

  • odds_popularity_gap ← 諸悪の根源
  • distance_category
  • odds_category

使用する特徴量(8個)

  • popularity(人気)
  • odds(オッズ)
  • track_condition_encoded(馬場状態)
  • track_type_encoded(芝ダ)
  • distance(距離)
  • horse_weight(馬体重)
  • sex_encoded(性別)
  • age(年齢)

モデルパラメータ

過学習を防ぐため、パラメータも調整:

n_estimators: 100
max_depth: 4(浅め)
min_samples_leaf: 50(過学習防止)
subsample: 0.8

学習結果

テストケース1: 11番人気、35.0倍、2000m、牝、3歳
  予測勝率: 1.75%
  期待値: -38.59%

✅ 正常!

テストケース2: 1番人気、1.5倍、1600m、牡、4歳
  予測勝率: 56.59%
  期待値: -15.12%

✅ 正常!

完璧に動作する。


📈 新システムの性能

バックテスト結果

2024年10月〜12月のテストデータで検証:

項目
期間2024年10月〜12月
ベット数858頭
的中数23頭
的中率2.7%
投資額85,800円
払戻額71,940円
収支-13,860円
回収率83.9%

期待値の閾値

閾値を変えて、最良の設定を探した:

期待値 5%以上: 回収率70.6%
期待値10%以上: 回収率74.7%
期待値15%以上: 回収率83.9% ← 最良
期待値20%以上: 回収率45.4%

期待値15%以上が最良と判明。

新システムの特徴

  • ✅ 異常な予測値なし
  • ✅ すべて妥当な範囲(期待値15-50%)
  • ✅ バックテスト検証済み(回収率83.9%)
  • ✅ 過学習なし

📊 5/3の結果と分析

推奨馬の着順

新システムで推奨された12頭の結果:

リュウゴピュア(新潟3R): 7着
  予測勝率: 2.4%、期待値: 50.7%

カウガールハット(東京3R): 12着
  予測勝率: 2.3%、期待値: 48.4%

ロックウイズユー(新潟6R): 6着
  予測勝率: 13.1%、期待値: 40.1%

ログラール(東京9R): 16着
  予測勝率: 17.9%、期待値: 30.7%

(他8頭も外れ)

12頭すべて外れ。

回収率0.0%。

統計的な評価

期待される的中数を計算:

12頭の予測勝率の合計:
2.4% + 2.3% + 13.1% + ... = 約120%

期待的中数: 約1.2頭
実際の的中数: 0頭

→ 統計的には誤差範囲内

判断

サンプル数が少なすぎて判断できない。

バックテストでは858頭で83.9%を達成している。

12頭(1週間)で判断するのは早計。

最低3週間(30-40頭)は続ける。


💭 エピローグ:データサイエンスの本質

学んだこと

1. 異常値は見逃さない

期待値876.9%という数字を見た瞬間、即座に運用停止した。

データサイエンスでは、異常値は必ず原因がある。

2. 問題の切り分けが重要

✅ モデル単体は正常
✅ スクリプトも正常
✅ データも正常
❌ 特定の組み合わせで異常

→ 特徴量エンジニアリングの問題

1つずつ検証して、原因を特定した。

3. シンプルが最強

派生特徴量を削除し、基本特徴量のみにした。

結果、正しく動作するようになった。

複雑さは敵。

4. 短期で判断しない

1週間で回収率0%。

でも、バックテストでは858頭で83.9%。

長期で評価する。

次週への期待

新システムの初戦は厳しい結果だった。

でも、システムは正しく動作している。

予測値は妥当。

バックテストも通過。

あとは、データを蓄積して評価するだけ。


📊 累計データ

第1-9週(旧システム)

項目
ベット数587頭
投資額58,500円
払戻額50,240円
収支-8,260円
回収率85.9%

※ 第8週・第9週はシステム不具合のため、参考値

第10週(新システム)

項目
ベット数12頭
投資額1,200円
払戻額0円
収支-1,200円
回収率0.0%

🔜 次回予告

次回は、第11週の結果を報告します。

新システムで、どこまで回復できるか。

3週間のデータで、システムの真価が見える。


📝 まとめ

第10週は、システムの完全再構築の週でした

異常な予測値を発見。

数時間の調査で根本原因を特定。

派生特徴量が原因と判明。

システムを完全に作り直し。

新システムは正常に動作。

でも、初戦は回収率0%。

統計的には誤差範囲内だが、厳しい結果。

データサイエンスは、短期で判断しない。

長期で評価する。

次週以降、データを蓄積して検証していく。


最後まで読んでいただき、ありがとうございました!

「システム再構築、お疲れ様」
「0%は厳しいけど、続けてほしい」
「データサイエンスの姿勢に共感」

コメントお待ちしています 💬

-競馬AI予測