予測モデル:デフォルトのモデルと自分で育てるモデル
アプリには学習済みのデフォルトのモデルを同梱しています。インストールしてデータを取得すれば、すぐに出馬表に予測が表示されます。ただしデフォルトのモデルは出発点にすぎません。特徴量・パラメーター・学習の期間を自分で変えて、モデルを何度でも作り直せます。
自分でチューニングできる範囲
[データ] - [モデルの学習] の画面で、次のすべてを自分で決めて学習できます。学習したモデルは世代として保存され、アプリの予測にそのまま使用できます。手順は自分のモデルを作るのページで説明しています。
- 約4,000個の候補からモデルごとに使用する特徴量を選択
- 特徴量のグループの作成・入れ子・名前の変更・移動と、カテゴリ変数の指定
- LightGBMのパラメーター(分類とランキングで別々に)と、木の本数・早期打ち切り
- 学習の年・検証の年・テストの年
- 学習するモデルの選択(全部でも一部だけでも)
- 検証の年のAUCによる特徴量の自動選択
- 世代ごとの成績の比較と、使用する世代の切り替え(以前の世代にも戻せます)
作ったモデルは、予測の集計で過去のレースに当てはめて、的中率・回収率・キャリブレーションまで確認できます。出馬表の「内訳」(SHAP)や決定木の可視化で、モデルが何を見て予測しているかも確認できます(モデルの中身)。特徴量を足して学習し直し、過去のレースで確かめて、また調整する。この繰り返しをすべてアプリの中で完結できます。
使用できる特徴量の一覧は特徴量の全リストにあります。
デフォルトのモデルの構成
デフォルトのモデルは、予測の対象ごとに分割したLightGBM(決定木を何本も重ねる機械学習の手法)のモデルです。1段目で逃げ・先行を予測し、その結果を2段目が材料にして着順を予測します。芝とダートは別々に学習するので、合計で12のモデルを使用します。自分で学習するときも、この構成のまま特徴量やパラメーターを変更できます。
| 段 | モデル | 予測の対象 |
|---|---|---|
| 1段目 | 逃げ | 3コーナーも4コーナーも1番手で通過する |
| 1段目 | 先行 | 3コーナーも4コーナーも5番手以内で通過する |
| 2段目 | メイン | 3着以内に入る |
| 2段目 | 単勝 | 1着になる |
| 2段目 | 連対 | 2着以内に入る |
| 2段目 | ランキング | 着順の並び(1着=3・2着=2・3着=1・ほか=0として学習する) |
1着・2着以内・3着以内は、それぞれ別のモデルで学習しています。ランキングのモデルは、1頭ずつの的中・不的中ではなく、レースの中での順序そのものを学習します。
展開の材料としての1段目の予測
どの馬が前に行くかはレース前には分かりません。そこで、まず1段目のモデルが、各馬が逃げる確率・先行する確率を予測します。その確率から、レースの中での順位、偏差値、最大値との差、偏差値70や60を超える馬の頭数と割合などの数値を作成し、2段目のモデルの特徴量に追加します。
これで2段目は、「この馬は先行できそうか」と「このレースに先行したい馬がほかに何頭いるか」も材料にできます。
特徴量に含めないオッズ・人気・着順
デフォルトのモデルは、今回のレースのオッズ・人気はもちろん、過去の走の人気や着順も、そのままの数値では特徴量にしていません。作者は、これらを含めるとモデルの予測が市場の見立てに近づいていき、モデルの選択した馬を購入しても回収率は控除率の分だけ下回るところに落ち着く、と考えています。デフォルトのモデルには、時計・指数・レーティング・調教・血統・騎手や厩舎の成績など、市場とは別の材料で判断させています。
今回のレースの結果に相当する列(着順・人気・オッズ・通過順・タイム差など)は、自分で学習するときも選択できないようにしてあります。含めると正解を参照して学習することになるからです。オッズは期待値の計算など予測を算出したあとで使用します。
デフォルトのモデルの精度
デフォルトのモデルは、2011〜2023年で学習し、2024年で検証し、2025年でテストしています。テストの年のAUCは次のとおりです。
| モデル | 芝 | ダート |
|---|---|---|
| メイン(3着以内) | 0.7966 | 0.8062 |
| 単勝(1着) | 0.8066 | 0.8266 |
| 連対(2着以内) | 0.7949 | 0.8185 |
| 逃げ | 0.8292 | 0.8374 |
| 先行 | 0.8015 | 0.8193 |
自分で学習したモデルにも、同じ形式でテストの年の成績が記録されます。デフォルトのモデルと並べて比較できます。
学習の仕組み
学習データ
学習データは年ごとのファイル(独自のバイナリの形式)で保持します。特徴量の計算を変更したら再作成します。年ごとに別のプロセスで計算し、20年分を8つ同時に作成して18.6分でした。読み込みは3秒で、同じ内容のCSVの読み込みには109秒かかります。
学習
学習は64ビットの別のプログラムで、LightGBMのCのAPIを呼び出して実行します。全部のモデルで1〜2時間ほどです。
特徴量の自動選択
2段目のモデル1つとトラック1つについて、パラメーターは固定したまま特徴量を追加・削除し、検証の年のAUCで選択します。重要度の低いものから削除していき、削除してもAUCがほとんど低下しなければ採用します。追加のほうは、候補の重要度を計測してから高いものを5つずつ追加し、一定以上AUCが向上したときだけ採用します。
特徴量を1つ変更するだけでも、学習の乱数の影響でAUCが変動します。そこで、1回の試行ごとに乱数の種を変えて3通り学習し、その平均で比較しています。選択した組み合わせは最後にテストの年で1回だけ評価します。
アプリ内での予測の算出
LightGBMの公式のライブラリは64ビット版しかありません。一方、JRA-VANのデータを取得するJV-Linkは32ビットなので、このアプリ本体も32ビットで動作しています。そこで、学習したモデルの決定木をC#で読み込み、自前でたどって予測を算出します。分岐の扱いはLightGBM 4.xと同じにしてあります。
次は特徴量:予測モデルに渡す約1,000個の材料です。