【モデル編②】3モデル連携アーキテクチャ:競馬のプロセスを模倣する
【モデル編②】3モデル連携アーキテクチャ:競馬のプロセスを模倣する
はじめに:一枚岩モデルの限界
前回の記事で導入した「ランク学習」は、レース内の相対的な強さを評価できる強力な手法です。
しかし、競馬の予測はそれほど単純ではありません。
- どの馬がハナを主張するのか?(展開)
- それによって全体のペースはどうなるのか?(ペース)
- ハイペースなら、どの馬が最後に脚を使えるのか?(上がり)
これらの要素は複雑に絡み合っており、単一の巨大なモデルに「全部まとめて考えろ」と丸投げしても、なかなか安定した予測はできません。
そこで、**「人間がレースを分析するプロセス」**を模倣し、複数の専門家モデルを連携させるアーキテクチャを考案しました。
1. 3モデル連携アーキテクチャの全体像
レースの結果は、一連の因果関係によって決まります。この流れを模倣するため、予測プロセスを以下の3つのフェーズに分解し、それぞれを専門のモデルに担当させます。
-
Model 1: 位置取り予測モデル (回帰)
- 入力: 過去の成績、枠順、騎手など
-
予測: 各馬がレースのどの位置につけるか(
pred_position_score)
-
Model 2: 道中ペース予測モデル (回帰)
- 入力: Model 1の予測結果(先行馬の数など)+基本特徴量
-
予測: レース全体の道中のペース(
pred_mid_pace)
-
Model 3: 上がり3Fタイム予測モデル (回帰)
- 入力: Model 1, 2の予測結果+基本特徴量
-
予測: 各馬が使うであろう上がり3Fのタイム(
pred_last_3f_time)
この構造のキモは、前段モデルの予測結果を、後段モデルの入力(特徴量)として使う点です。
これにより、「先行馬が多い(とModel 1が予測した)から、ペースは速くなる(とModel 2が予測する)」といった、ドミノ倒しのような予測が可能になります。
最終的に、これらのサブモデル群が生み出した予測結果(pred_position_score, pred_mid_pace, pred_last_3f_time)を全ての特徴量に加えて、メインのモデル(ランク学習 or タイム予測)が最終的な着順を予測します。
2. 実装の核心:パイプライン処理
この「予測結果のバケツリレー」は、src/keiba/services/analysis/application/training_service.py の中でパイプラインとして実装されています。
# c:\keiba_app\src\keiba\services\analysis\application\training_service.py
if __name__ == '__main__':
# ... (データロード・特徴量生成) ...
# モデル1: 位置取り
model1 = train_model_1(df)
df = apply_model_1_prediction(df, model1) # ★予測結果をdfに追加
# モデル2: ペース
model2 = train_model_2(df)
df = apply_model_2_prediction(df, model2) # ★予測結果をdfに追加
# モデル3: 上がり3F
model3 = train_model_3(df)
df = apply_model_3_prediction(df, model3) # ★予測結果をdfに追加
# モデル4: 走破タイム (最終モデル)
model4 = train_model_4(df)
apply_model_X_prediction 関数が、学習済みモデルを使って予測を行い、その結果を新しい列としてデータフレームに追加しています。
これにより、次のモデルは前のモデルの「思考結果」を踏まえて、より高度な判断を下すことができます。
3. 依存関係の厳格な管理
このアーキテクチャで最も重要なのが、データリーク(未来情報の参照)の徹底的な防止です。
例えば、Model 2(ペース予測)が、本来知るはずのないModel 3(上がり予測)の結果や、レースの最終着順を見てしまってはいけません。
この依存関係は、src/keiba/config/columns.py で定義された除外リストによって厳格に管理されています。
# c:\keiba_app\src\keiba\config\columns.py
# モデル2 (道中ペース予測) で除外するカラム
DROP_COLS_M2 = [
'mid_pace', # 自分自身の答え
# レース結果(リーク)
'last_3f_time', # Model3以降で予測される情報
'finish_time', # 最終結果
'rank', # 最終結果
...
]
各モデルの学習時には、このリストに基づいて特徴量がフィルタリングされます。
これにより、「Model 2はModel 1の結果は知っているが、それ以降の未来は知らない」という状態を保証し、モデルがカンニングすることを防いでいます。
まとめ:専門家集団による分業体制
単一の万能モデルを目指すのではなく、プロセスを分解し、それぞれの専門家モデルに分業させる。
この3モデル連携アーキテクチャにより、以下のメリットが生まれました。
- 解釈性の向上: 最終予測が外れた場合、どのサブモデルの予測が原因だったのかを追跡しやすくなります。
- モデルの安定化: 各モデルはより単純なタスクに集中できるため、学習が安定し、改善も容易になります。
- 柔軟な拡張性: 「上がり3F予測」モデルだけを、より高度なアルゴリズムに差し替える、といった改善が簡単に行えます。
次回は、この連携システムの根幹をなす「位置取り予測モデル」と「タイム予測モデル」が、開発の過程でどのように進化していったのか、その具体的な改善の道筋について解説します。
Discussion