レース検証

レース検証のデータ漏洩とは?後から知った情報を除く

確定オッズや結果後の条件変更が過去検証を良く見せる仕組みを整理し、期間分割、欠場記録、ルール固定で再現可能にする方法を解説します。

  • #レース検証
  • #データ漏洩
  • #バックテスト
  • #検証記録

過去のレースを使って買い方や予測ルールを試す作業は、一般にバックテストと呼ばれます。ただし、表計算が正しく動き、回収率の式が合っていても、その結果が実戦で再現できるとは限りません。レース前には知らなかった情報が入力に混ざると、過去へ戻って未来を知っていたかのような検証になるためです。

この記事では、この問題を「データ漏洩」として整理します。特に起きやすいのが、レース後に取得した確定オッズの混入、結果を見てからの条件変更、欠場・取消行の削除です。対策の中心は、高度な予測モデルではありません。「その時点で何を知ることができたか」を列で残し、ルールを結果より先に固定することです。

ここで示す回収率や件数は書式を説明する架空例であり、実在レースの成績ではありません。検証表の基本項目はレース検証の記録のつけ方、回収率の分母と読み方は回収率という物差しも参照してください。

データ漏洩の意味

データ漏洩とは、判断する時点では利用できなかった情報を、予測ルールの作成や評価に使ってしまうことです。機械学習ライブラリscikit-learnの公式文書も、予測時点で利用できない情報をモデル構築に使うと、評価が過度に楽観的になると説明しています。また、テスト用データをモデル選択に使わず、前処理より先に訓練用とテスト用へ分けることを推奨しています(2026年7月23日確認:scikit-learn「Common pitfalls and recommended practices」)。

レース検証では「モデル」を作っていなくても同じ問題が起きます。たとえば、次のような情報は取得時点によって役割が変わります。

情報レース前の保存値レース後に判明する値漏洩になる使い方
オッズ自分が判断した時刻の表示オッズ最終オッズ、払戻金最終オッズで買えたと仮定する
出走状態その時点の出馬表、変更情報取消・除外を反映した確定状態取消馬を最初から存在しなかったことにする
着順不明確定着順、競走中止等的中馬の特徴を見てから条件に足す
馬場・気象判断時点の発表値発走時や結果画面の値後の状態を前から知っていた入力にする

重要なのは、結果データを使うこと自体が悪いのではない点です。着順や払戻金は成績を採点するために必要です。問題は、採点用の情報を「買うかどうかを決める入力」へ戻すことにあります。検証表では、少なくとも「判断に使える列」と「結果確定後に更新する列」を分けます。

次の三つの時刻を一行ごとに持つと、境界が見えやすくなります。

  1. decision_at:買う・見送るを決めた時刻
  2. observed_at:オッズや出馬表を実際に取得した時刻
  3. settled_at:結果と払戻しを記入した時刻

observed_atdecision_atより後なら、その値は当時の判断材料として使えません。空欄を後から埋めても、取得時刻を過去へ書き換えないことが原則です。

確定オッズを混ぜる失敗

JRA公式サイトは、開催中のページでは「最新の情報」を表示し、終了したレースでは「最終オッズ」を表示すると案内しています(2026年7月23日確認:JRA「ホームページでオッズを見ることができますか?」)。つまり、レース後に結果ページから集めたオッズは、レース前のある時刻に画面で見たオッズと同じとは限りません。

さらにJRAの用語辞典では、オッズは100円に対する概算払戻率であり、発売締切後に表示される最終オッズも、その後の競走除外で変動し得ると説明されています。同着など結果によっては、発表された最終オッズと異なる率の払戻金になる場合もあります(2026年7月23日確認:JRA競馬用語辞典「オッズ」)。

したがって、次の検証は意味が異なります。

  • 判断時点オッズを使う検証:その時刻に見えていた条件で選べたかを調べる
  • 最終オッズを使う集計:市場の最終評価や結果との関係を振り返る
  • 払戻金を使う精算:実際の的中時にいくら戻ったかを確定する

たとえば「単勝オッズ5.0倍以上を買う」というルールを調べるなら、判断時刻に4.8倍だった馬を、最終オッズが5.2倍だったから対象へ加えてはいけません。反対に、判断時刻に5.1倍でも最終オッズが4.7倍へ下がることがあります。最終オッズしか保存していないデータからは、このルールを当時そのまま実行できたか判断できません。

対策はオッズ列を一つにしないことです。

列名の例内容用途
odds_observed判断前に実際に確認した表示値買い目選定
odds_observed_atその値を取得した日時利用可能時点の監査
odds_finalレース後に確認した最終オッズ事後分析
payout_per_100100円当たりの確定払戻金収支精算
odds_source_url確認した公式ページ出典確認

判断時点オッズがない行は、0や最終オッズで補完せず「未取得」にします。その行はオッズ条件付きルールの評価対象から外し、除外件数を表示します。最終オッズしかない場合は、「最終オッズによる事後分類」と明記し、実行可能性を測るバックテストとは分けてください。

結果後に条件を変える失敗

過去データを見ながら条件を調整すると、偶然よく見える組み合わせを選べます。最初は「1番人気かつ単勝3倍以上」だったのに、成績が悪い月を見て「重馬場を除く」、さらに外れを見て「特定距離も除く」と変えていけば、同じデータへの当てはまりは良くなります。しかし、そのルールが未知の期間でも働く証拠にはなりません。

条件変更には、少なくとも三種類あります。

  1. 誤りの修正:券種の判定式や払戻計算のバグを直す
  2. 仮説の変更:距離、人気、オッズなどの採用条件を変える
  3. 集計定義の変更:取消、返還、同着、欠測の扱いを変える

誤りの修正は必要ですが、修正前後の版と影響件数を残します。仮説や集計定義を変えた場合は、同じ検証期間の成績を新ルールの合格点として使いません。変更後のルールは、まだ見ていない期間で改めて評価します。

「結果を見た後で気づいた良い条件」を捨てる必要はありません。ただし、それは検証済みの結論ではなく、次の検証に回す仮説です。記録上は次のように分けます。

旧ルール v1.0:距離と人気だけで判定。2024年分を探索に使用。
新仮説 v1.1:馬場状態を追加。2024年分を見て着想したため、同期間の成績は参考値。2025年分を未見の検証期間とする。

条件を何通り試したかも残してください。20通りを試して最も良かった1通りだけを示すのと、最初から決めた1通りが同じ成績だったのとでは、証拠の強さが違います。試行数を後から正確に復元できない場合は「条件探索あり・試行数不明」と注記し、単独の成功例を再現性のある傾向と断定しません。

条件探索と評価を同じデータで行う問題は、予測モデルの設定調整でも共通します。scikit-learnの公式例は、同じデータで設定を選び、その性能も評価する非ネスト型の交差検証では、データへの過適合によって評価が楽観的になり得ると説明しています。内側で設定を選び、外側の未使用データで評価するネスト型交差検証は、その分離を保つ方法の一つです(2026年7月24日確認:scikit-learn「Nested versus non-nested cross-validation」)。表計算で条件を比較する場合も、考え方は同じです。

よくある漏洩の見分け方

検証結果に見える兆候考えられる原因記録で確認する項目修正後の扱い
過去成績だけが不自然に良い結果を見ながら条件を追加したルール作成日時、変更履歴、試行数変更後に未使用期間で再評価
オッズ条件の境界付近で対象が増える最終オッズを判断時点の値として使用したodds_observed_atodds_final判断時点値がない行は未取得
取消や欠測が一件もない不都合な行を削除した原票件数、状態別件数、除外理由原票へ戻し、集計時に状態別処理
集計をやり直すと数字が変わるデータや計算式を上書きしたデータ版、ルール版、集計版旧版を残して影響件数を比較
検証期間を変えるたび条件も変わる評価期間が探索期間へ戻っている期間ごとの役割、ルール確定日時次の未使用期間を検証に回す

検証用期間を分ける

最も扱いやすい対策は、時系列に沿って期間を分けることです。過去側でルールを作り、それより未来側で一度だけ評価します。レースは時間順に発生するため、全期間を無作為に混ぜると、未来側の開催傾向やデータ処理結果が過去側の設計へ入りやすくなります。

scikit-learnの公式文書も、時系列データを通常の交差検証で分けると「未来のデータで学習し、過去で評価する」形になり得るため、時間順の分割を用いると説明しています(2026年7月23日確認:scikit-learn「TimeSeriesSplit」)。これは特定のソフトを使う場合だけの話ではなく、表計算でも守れる考え方です。

期間は、次の三つに分けると役割が明確になります。

期間役割してよいこと
探索期間傾向を見て仮説を作る条件を比較し、ルール案を作る
検証期間固定したルールを評価する事前登録した集計だけを実行する
運用記録期間実際の判断手順を確認する判断時点の入力と見送りを含めて保存する

架空例として、2023年を探索、2024年を検証、2025年を運用記録にします。2024年の結果を見て条件を変えたら、その時点で2024年は探索済みです。変更後ルールの検証には、まだ条件調整へ使っていない2025年以降が必要になります。

開催制度、データ形式、オッズ取得方法などが期間途中で変わった場合は、単純に結合しません。変更日を境界として版を分け、同じ定義で比較できるか確認します。公式資料で変更日や適用範囲を確認できない場合は「※要確認」とし、推測した境界で結論を出さないでください。

期間の前後に間隔を空ける方法もあります。たとえば、前日までの集計値を当日の特徴量に使う処理で当日結果まで誤って含める危険があるなら、集計対象終了日と評価開始日の間を空けます。何日空けるべきかはデータ更新の仕組みによるため、一律の正解はありません。必要な間隔を決めた根拠と、集計処理が参照する最終日時を検証票へ書きます。

欠場・取消データを残す

欠場や取消を単に行削除すると、「レース前には候補だったが、後で買えなくなった」という経過が消えます。JRAは、出走取消を装鞍所へ入る前、競走除外を装鞍所へ入ってから発走までに出走を取りやめることと説明しています(2026年7月23日確認:JRA「出走取消(あるいは競走除外)の意味」)。

JRAのレース結果の見方では、「失格」「中止」「除外」「取消」を別の状態として表示すると案内されています(2026年7月23日確認:JRA「レース結果の見方」)。これらをすべて着順0や外れへ変換すると、出走しなかった馬と出走後に競走中止となった馬を区別できません。

原票には行を残し、状態を別列にします。

列名の例記録例注意点
status_at_decision出走予定判断時点で見えていた状態
final_status正常、取消、除外、中止、失格公式結果の表記を保持
status_announced_at日時または未取得いつ知り得たかを区別
ticket_status購入、見送り、返還、購入不能予測結果と収支を分ける
exclusion_reason取消のため評価対象外空欄、0、対象外を混同しない

出走取消馬を的中率の分母へ含めるかは、何を評価するかで変わります。「予測が当たった割合」なら出走しなかった馬を着外扱いするのは不自然です。一方、「候補抽出後に実際に投票まで進めた割合」を測るなら、取消も運用上の発生件数として残す必要があります。原票を消さず、集計ごとの採用条件を明記すれば、両方を計算できます。

収支では、取消・除外を単純な外れとして扱わないようにします。JRA公式「馬券のルール」は、発売開始後に出走取消または競走除外があった場合、単勝・複勝では出走しない馬番、馬連・馬単・ワイド・3連複・3連単などではその馬番を含む組合せが返還対象になると案内しています。枠連は同じ枠に残る馬の数などで扱いが異なります(2026年7月24日確認:JRA「馬券のルール」)。検証表では、購入額、返還額、収支対象額を別列にし、券種ごとの公式ルールを反映してください。

レース結果が確定するまでの状態も区別します。JRA公式は、到達順位の表示後に確定ランプが点灯するとレースが確定し、その後に払戻金が発表されると説明しています(2026年7月23日確認:JRA「レースの確定」)。速報の着順を確定結果として保存せず、result_statusを「速報」「確定」に分けると上書き事故を防げます。

ルールと版を固定する

再現可能な検証には、ルールの文章と計算ファイルの版が必要です。「人気薄を買う」「悪天候を除く」のような言葉だけでは、実行する人によって対象が変わります。各条件を、機械的に同じ判定ができる形へ直します。

最低限、次を固定します。

  • 対象競技、競馬場、期間、券種
  • 1レースを一行にするか、1頭・1組合せを一行にするか
  • 判断時刻と、その時刻までに利用できる情報
  • オッズ条件に使う列と、欠測時の扱い
  • 的中、購入額、払戻額、返還の計算式
  • 取消、除外、中止、失格、同着の処理
  • 条件に一致しない見送り行を保存するか
  • 小数の丸め方と、率の分母
  • 探索期間と検証期間
  • ルール版、データ版、集計版

ルールIDはrule-001-v1.0のように付け、条件を変えたら上書きせずv1.1へ進めます。修正履歴には「何を」「なぜ」「どの結果を見る前に」変えたかを書きます。計算式だけを直した場合も、旧版の出力を残して影響行数を比較します。

データにも版を付けます。同じファイル名へ最新値を上書きすると、以前の集計を再現できません。取得日時、対象期間、出典URL、ファイルの識別値を残します。ファイル識別値としてハッシュ値を使う場合は、同じ内容から同じ値を得られる方式とツール名を記録します。方式が未定なら「※要確認」とし、架空の値を置きません。

ルールを固定しても、将来の利益や的中を保証するものではありません。過去の環境と今後の環境は同一ではなく、オッズ条件を満たす買い目が毎回得られるとも限りません。バックテストの役割は「決めた手順を過去データへ同じように適用した結果」を測ることであり、未来を確定することではありません。

再現可能な検証票を作る

最後に、第三者や数か月後の自分が同じ集計をやり直せる検証票へまとめます。結果の数字だけでなく、入力、時刻、除外、版を一枚で追える形にします。

検証票のひな型

項目記入内容
検証ID一意の番号
検証目的何を確かめるかを一文で記載
仮説登録日時結果集計を始める前の日時
ルールID・版例:rule-001-v1.0
探索期間条件作成に使った期間
検証期間条件調整に使わない期間
判断時刻発走何分前ではなく実際の取得日時を推奨
入力列判断時点で利用可能な列の一覧
結果列確定後にだけ更新する列の一覧
欠測処理除外、保留など。0埋めと区別
取消等の処理状態別の分母・収支への反映
データ出典公式URL、取得日、対象期間
対象件数全件、有効件、欠測、取消等を別掲
評価指標的中率、回収率などの式と分母
試した条件数採用しなかった条件も含む
実行日時集計を実行した日時
変更履歴変更内容、理由、変更前に見た期間

集計結果には、少なくとも「全候補件数」「購入条件一致件数」「実際に評価できた件数」「欠測件数」「取消・除外件数」を並べます。有効件だけを示すと、都合の悪い行を落としていないか確認できません。見送りも含めた全行を原票に残し、集計表は原票から作ります。

検品は次の順で行います。

  1. 検証期間の開始前にルール版が作成されているか
  2. 入力列の取得時刻が判断時刻以前か
  3. 最終オッズや確定着順が選定条件へ入っていないか
  4. 条件変更に使った期間が検証期間へ残っていないか
  5. 取消・除外・中止・欠測の原票が消えていないか
  6. 同じルール版とデータ版で再計算して同じ結果になるか
  7. 結果表に分母、除外件数、試行数が表示されているか

一つでも確認できない項目があれば、結果を捨てる必要はありません。「判断時点オッズ未取得」「条件探索回数不明」など、証拠として弱い理由を明記します。完全な記録に見せるより、どこまで再現できるかを正直に示す方が、次の検証を改善できます。

よくある質問

最終オッズしかないデータでもバックテストできますか

最終オッズと結果の関係を調べる事後分析はできます。ただし、判断時点のオッズ条件を当時実行できたかは確認できないため、「最終オッズによる事後分類」と明記し、実行可能性を評価する検証とは分けます。

探索期間と検証期間は何対何に分ければよいですか

一律の比率はありません。件数、条件数、開催制度の変更、配当のばらつきによって必要量が変わります。期間の比率を先に固定するより、時間順を守り、検証期間を条件調整に使わないことを優先します。件数の考え方は回収率は何レースで判断できるかも参照してください。

条件を一度変えたら、それまでのデータは使えませんか

使えなくなるわけではありません。条件変更に使った期間は探索済みとして、旧ルールとの比較や仮説作りに使えます。変更後ルールの評価だけを、まだ見ていない期間へ移します。

取消・除外・返還は回収率の分母へ入れますか

購入額をそのまま分母にするか、返還額を差し引いた実質投資額を分母にするかで値が変わります。採用する式を事前に決め、購入額・返還額・実質投資額を別々に表示してください。取消行そのものは原票から削除しません。

表計算だけでもデータ漏洩を防げますか

防げます。入力列と結果列の分離、取得日時、ルール版、期間の役割、欠測・取消の状態を残すことが中心です。途中オッズと最終オッズの記録例は最終オッズの変動を検証する記録方法、条件別集計の例は人気薄ほど有利に見える?本命・大穴バイアスの検証も参考になります。

この記事では、scikit-learnのデータ漏洩対策、時系列分割、条件探索と評価の分離、およびJRAのオッズ表示・定義、取消・除外、結果画面、レース確定、返還ルールの公式情報を参照しました。既存7件は2026年7月23日、追加2件は2026年7月24日に確認しています。ページの内容やデータ提供方法は今後変わる可能性があるため、実際の検証開始時にも取得日とURLを残してください。