【競馬AI 15】AI予測の精度を検証!単勝回収率を計算してみよう

競馬AI

競馬AIの最終的な評価は、どれだけ「当たったか」ではなく、どれだけ回収できたか(回収率)で決まります。
この記事では、AIモデルの単勝回収率を自動計算するSQLクエリを紹介します。
さらに、
「今年の全レース」データを取得してモデルを一括検証する方法
も解説。
記事の最後には、あなた自身の回収率をコメントでシェアしてもらえると嬉しいです!

処理概要

今回のテーマは、AI予測モデルの「回収率(ROI)」を算出することです。
「どれくらい当たるか」よりも、「どれくらい儲かるか」を可視化することで、モデルの本当の強さを測ります。

当日のレースデータを取得する

predict_work_tables.pycreate_ranked_race_base 内で

WHERE KAISAI_NEN = {year} AND KAISAI_GAPPI = {date}

となっている箇所のうち、
AND KAISAI_GAPPI = {date} 部分をコメントアウトします。

これにより、「指定した年の全レース」を一括で取得可能になります。
たとえば {year} = 2025 と指定すれば、2025年の全レースをAIが予測できるようになります。

予測結果(p_predict_results_all)を作成・保存

学習済みモデルを用いて、過去レースに対して予測を実施します。

大量の予測結果を別テーブルに残しておきたいので、「_all」を付けて新規にテーブルを作成しています。

SQLで回収率を算出

以下のクエリを実行して、単勝回収率を自動で計算します。

一定の閾値(確率0.8以上、期待値100以上)を満たす馬に絞り、
実際に1着になった場合のみ配当を集計します。

プログラム全文

WITH ranked AS (
  SELECT
    p.*,
    j.KAKUTEI_CHAKUJUN,
    ROW_NUMBER() OVER (
      PARTITION BY p.RACE_ID
      ORDER BY p.PRED_PROB DESC, p.ODDS_REAL DESC, p.KETTO_TOROKU_BANGO ASC
    ) AS rn
  FROM
    p_predict_results_all AS p
    LEFT JOIN umagoto_race_joho AS j
      ON p.RACE_CODE = j.RACE_CODE
     AND p.KETTO_TOROKU_BANGO = j.KETTO_TOROKU_BANGO
  WHERE
    p.PRED_PROB >= 0.8 AND p.EXPECTED_VALUE >= 100
)
SELECT
  ROUND(
    SUM(CASE WHEN KAKUTEI_CHAKUJUN = 1 THEN ODDS_REAL ELSE 0 END) / COUNT(*) * 100
  , 1) AS TANSYO_RETURN_RATE
FROM ranked
WHERE rn = 1;

解説

「ranked」CTEの役割

ranked 部分では、レースごとに予測確率が最も高い馬(=1位予想馬)を特定しています。

ROW_NUMBER() OVER (
  PARTITION BY p.RACE_ID
  ORDER BY p.PRED_PROB DESC, p.ODDS_REAL DESC
)

これにより、各レースで一番「勝ちそう」と予測された馬rn = 1 としてラベル付けされます。

的中した馬の配当を加算

KAKUTEI_CHAKUJUN = 1(=実際に1着)になった馬のみに対して、
その馬の実際の単勝オッズ(ODDS_REAL)を配当として加算します。

SUM(CASE WHEN KAKUTEI_CHAKUJUN = 1 THEN ODDS_REAL ELSE 0 END)

ここでの「配当」は、1点あたり100円購入を想定しています。
たとえば、オッズが5.0の馬が1着になれば、500円の払い戻しとカウントされます。

回収率の計算式

分母は「購入したレース数(=全レース数)」です。
分子は「的中したレースの合計配当」。
したがって、回収率(単勝ROI)の計算式は以下の通り:

\text{回収率(\%)} = \frac{\sum \text{的中時のオッズ}}{\text{購入レース数}} \times 100

このSQLでは、ROUND(..., 1) によって小数点1桁まで四捨五入して表示します。

ポイント解説

期待値と確率のダブル条件

このクエリのキモは、「PRED_PROB ≥ 0.8」かつ「EXPECTED_VALUE ≥ 100」の条件です。
この2つを掛け合わせることで、「勝つ確率が高く、かつ儲かる見込みがある馬」を選別しています。

  • PRED_PROB(予測確率):AIモデルが算出した勝率
  • EXPECTED_VALUE(期待値):理論的な回収率(100以上でプラス)

単勝で安定して勝つには、この2つをバランス良く見ることが重要です。

年単位でモデルを検証する

KAISAI_GAPPI のコメントアウトにより、1年分の全レースをまとめて取得できます。
この仕組みを使うと、年間回収率の傾向を自動でチェックできます。

たとえば:

year = 2025

と指定すれば、2025年の全レースをAIに予測させ、
このSQLを実行することで「2025年モデルの回収率」が一発で出ます。

これを毎年比較していけば、モデルの進化が数値で見えるようになります。

モデルの「現実的な強さ」を見る

AI予測で最もやってはいけないのが、「的中率だけを見て安心する」こと。
的中率が高くてもオッズが低ければ、トータルではマイナスになります。

回収率を出すことで、初めて「どんな買い方ならプラスになるか」が見えてきます。
このSQLは、まさにその“収益力”を定量化するための最初の一歩です。

回収率が高すぎるときの注意

もし結果が「500%」など極端に高い場合は、サンプル数が少ない可能性があります。
レース数を増やすか、条件を緩めて再計算してみましょう。
逆に、回収率が90~200%の範囲なら、モデルが現実的に機能している証拠です。

まとめ

この記事では、AI予測モデルの単勝回収率を計算する方法を紹介しました。

  • 当日のレースデータ取得方法
  • 年単位の検証設定
  • SQLでのROI算出ロジック
    を組み合わせることで、あなたのモデルの実力を数値化できます。

もし回収率が100%を超えていれば、理論的にはプラス収支の可能性が高いです。
AIが「勝てる」と判断した馬たちが、本当に結果を出せているのか?
このSQLを使えば、その答えがはっきり見えてきます。

最後にひとこと

この記事を読んで、自分のAIモデルの回収率を試した方は、
ぜひコメント欄に「自分の回収率」を投稿してください!

  • 例:「2025年モデルの単勝回収率 → 118.5%」
  • 例:「確率0.8&期待値100条件で → 92.4%」

みんなで比較することで、どのモデルがどれだけ強いのか見えてくるはずです。
あなたの回収率報告、お待ちしています!

ちなみに私の結果は250%ほどでした!信じたいですが、どこかで過学習しているかリークしているか。実際に購入して検証しています!

コメント