BoatraceCSV

モーターpt パラメータ調整 — エキスパート評価を正解にしたスコア表最適化

実施日: 2026-07-19 / 対象: motor_ability_score.csv + モーター能力指数 v2 の定数群

結論(提案)

以下の 3 変更で、エキスパート評価との場別 Spearman 加重平均が +0.581 → +0.620 に改善する。 leave-one-stadium-out 検証で 4 場すべてが一貫して改善(加重平均 +0.037)し、過学習の兆候はない。

パラメータ 現行 提案 効果
スコア表の形状 着順に線形(等間隔) 凸カーブ γ=1.5(1着プレミアム、proposed_motor_ability_score.csv) 全場で改善。「上位着の価値は等間隔より大きい」
MOTOR_NEGATIVE_SCORE -100 -50 -100 は過大ペナルティ。転/落/沈/エ 1回で評価が壊れすぎていた
MOTOR_HISTORY_SESSIONS 6 5 6節目はノイズ寄与が優勢

変更しない(調整の結果、現行値が最適圏と確認): 半減期 60 日 / 収縮 k=10 / lane補正 ON。

提案スコア表

現行の行別スケール(125/100/125/75/100/50)は維持し、行内の間隔だけを ((6-着順+1)/5... 正確には u=(6-k)/5 の u^1.5 で凸化して整数丸め:

級別,グレード分類,1着pt,2着pt,3着pt,4着pt,5着pt,6着pt
B2,全,125,89,58,32,11,0
B1,全,100,72,46,25,9,0
A2,SG_G1,125,89,58,32,11,0
A2,G2_G3_一般,75,54,35,19,7,0
A1,SG_G1,100,72,46,25,9,0
A1,G2_G3_一般,50,36,23,13,4,0

整数丸めによる劣化は +0.0005 と無視できる。

正解データ

4 場のドメインエキスパート評価スナップショット(2026-07-19 取得、計 183 機)。 詳細は ground_truth/README.md。

場 スケール n 正解値への変換
04 平和島(おかぺん) SS〜E 11段階 43 SS=11 … E=1
23 唐津(素性ランク) S〜D 5段階 60 S=5 … D=1
24 大村(評価平均) 1〜7点 70 そのまま
14 鳴門(イチオシ) 金/銀/銅・上位10のみ 10 金3/銀2/銅1/非掲載0 の打ち切り扱い

superboatmotor.com は JS レンダリング必須のため今回除外。

手法

  1. 各場の評価集計期間末尾に合わせた target_day(平和島 07-15 / 唐津 07-16 / 大村 07-18 / 鳴門 06-14)で load_motor_history() を実行し、全 24 場の走レコード(各 ~5.9 万走)をフラット化して前計算 (scripts/precompute_runs.py)。
  2. スコア表形状(行別 γ, スケール A)・ペナルティ・半減期・収縮 k・節数・lane補正 ON/OFF を 引数に motor_ability_pt を numpy で再計算するハーネスを実装 (scripts/harness.py)。現行構成で本番実装 (index_features.motor_ability_pt)と最大誤差 7e-15 の一致を確認 (scripts/validate_harness.py)。
  3. 目的関数 = 場別 Spearman ρ のラベル数加重平均。正解機番は全 183 機が履歴と突合できた。

結果

ベースライン

構成 平和島 唐津 大村 鳴門 加重平均
現行モーターpt +0.623 +0.590 +0.589 +0.290 +0.581
(参考)公式2連対率のみ +0.660 +0.386 +0.600 +0.338 +0.530
提案構成 +0.656 +0.611 +0.641 +0.372 +0.620

注: 過去の motor_pt_okapen_validation.ipynb では「現モーターpt は相関ほぼ 0」だったが、 これは能力指数 v2 化(z残差+減衰+収縮)前の値。v2 は既に 2連対率単体を上回っており、 今回の調整でさらに引き離した。

全パラメータ Optuna 探索(3000 trials)は過学習

行別 γ・A まで自由にすると全体 +0.629 まで上がるが、LOSO で平和島が現行割れ (+0.589 vs +0.623)。行別の形状差・スケール差は 1 スナップショットのノイズを拾っている。 詳細は tune_result.json / trials.csv。

1 次元感度分析(頑健に効く方向だけを採用)

LOSO 検証(小グリッド: γ×ペナルティ×節数×半減期×k)

held-out 調整後 現行 差
平和島 +0.653 +0.623 +0.030
唐津 +0.607 +0.590 +0.017
大村 +0.639 +0.589 +0.050
鳴門 +0.374 +0.290 +0.084

3 場学習で選ばれる構成は fold 間でほぼ同一(γ=1.5〜1.8, pen=-50, N=5, H=60)であり、 提案構成はどの場を隠しても安定して選ばれる。

設計上の注記

限界

次のステップ(v4_motor 投入時)

  1. data/estimate/motor_ability_score.csv を提案表に差し替え……はしない。現行 v1_basic の 意味を変えないため、新予想者 v4_motor 用に別テーブル/定数セットとして実装する (例: score CSV をバージョン付きで並置し、predictor ごとに参照を切り替え)
  2. registry.py に v4_motor を追加(component は waku/racer/motor/exhibit/weather の 5 成分、 motor の計算パラメータのみ変更)+ infra/run-*.sh の ACTIVE_PREDICTORS 同期
  3. 対象月の重みを build_weights.py で学習し、回収率を control (v1_basic) と比較
  4. CLAUDE.md ルールに従い docs/data/estimate.md / docs/data/motor_ability_score.md / 設計書(本レポートを docs/design/ に昇格するか新設)を同 PR で更新

再現方法

# データ前計算(リポジトリ直下に repo/ としてデータを配置する想定。パスは要調整)
python scripts/precompute_runs.py
# 本番実装との一致検証
python scripts/validate_harness.py
# 全パラメータ探索 + LOSO
python scripts/tune_optuna.py 3000