メインコンテンツへスキップ
見出し画像

ボタン一つで組み上がる競馬AIがついに完成しました【#66】

    この【競馬AI開発】シリーズでは、機械学習で各馬の勝率を予測し、期待値の高い馬券を自動投票することでリターンを得る競馬AIを開発してきました。

    色々と試行錯誤を重ね、ついに、そのような競馬AIをボタン一つで構築できる仕組みが完成したので、今回はその全貌と使い方をまとめて解説します。

    画像

    これを使うと、ブラウザ上でボタンを押すだけであなたのPCに競馬AIが構築され、実行の様子やシミュレーション結果等を上記のようなグラフ上で視覚的に把握することができます。

    また、各自で考案したファクターや学習設定の変更等のカスタマイズも柔軟に行うことができ、このブラウザ上で実験の比較も行うことができます。

    1. この競馬AIの全体像

    AIを使った競馬では、各馬券の的中確率にオッズを掛けた「期待値」‍が高い馬券を買う、というのが基本戦略となります。

    期待値 = 的中確率(機械学習で予測) × オッズ

    ここで、この「馬券の的中確率」を機械学習モデルで正確に予測することにより、期待値の高い(=市場で過小評価されている)ものを検知することができるわけです。

    画像

    以下はこの戦略に基づいた時シミュレーション結果で、横軸が期待値の閾値(=この期待値以上のものを買う、という設定)、縦軸がその閾値で単勝馬券を買ったときの回収率です。(JRA-VAN の発走6分前のオッズを使い、2020年〜2024年の5年間で学習したモデルを使って2025年の1年間のレースで検証)

    画像

    青線が回収率を表していて、例えば期待値 1.16 を超える馬券を買い続けると回収率が 136.2% に達する、ということが読み取れます。

    画像

    馬連についても同様に、期待値1.5を超えたあたりから回収率が100%を超え始め、高い期待値のものに絞れば絞るほど、回収率が上がっていくことが分かります。

    レース当日はサーバーを起動しておき、発走直前に全馬券種の全ての組み合わせの期待値を計算して自動投票を行います。

    1.1 全体の流れ

    全体の流れは、大きく4つの工程に分かれます。

    画像

    1. 集める。‍netkeiba.com から、過去のレースのデータを集めます。

    2. 作る。‍集めたデータから、前処理・特徴量作成・モデルの学習・評価・回収率のシミュレーションまでを行います。この工程を担うのが、この後紹介する dagster というツールで、ブラウザ上でボタン一つで全工程を実行することができ、進み具合や結果も同じ画面で確認できます。

    3. 準備する。‍レース当日の出走馬のデータと直前のオッズを取得して、予測の準備をします。

    4. 買う。‍本番用のモデルで予測して、馬券を自動で買います。

    2. dagster とは

    2.1 dagster がやること

    dagster は、データ処理の流れを「これを作るには、あれが要る」という依存関係つきで管理して、ブラウザの画面から実行と確認ができる Python のツールです。

    画像

    この競馬AIでは、前処理・特徴量作成・モデルの学習・評価・回収率のシミュレーションまでの処理を、この依存関係つきで dagster に登録しています。

    そのため、画面でボタンを一つ押すだけで、必要なものから順にすべてが作られ、どこまで進んだか・何が作られたかも同じ画面で確認できます。全部を作り直さなくても、選んだものだけを作ることもできます。

    dagster そのものについてさらに詳しくは、#58の記事で入門として解説しています。

    2.2 基本用語と画面

    この先の操作で出てくる語を、起動後の実際の画面と一緒に説明します。

    左のメニューの Lineage を開くと、箱が矢印でつながったグラフが表示されます。この箱の1つ1つが‍「アセット(asset)」‍で、処理の結果として作られるデータのことです。

    画像

    特徴量テーブル・学習済みのモデル・回収率シミュレーションの結果など、この競馬AIで作られる物はそれぞれ1つのアセットで、1つのアセットが1つのファイルとして保存されます。矢印は「このデータを作るには、あのデータが要る」という依存関係です。

    アセットを実際に作ることを materialize(マテリアライズ)‍と呼びます。画面の Materialize のボタンを押すと、そのアセットを作る処理が実行されて、結果がファイルに保存されます。

    Lineage は、このアセットのつながりを表すグラフの画面です。この競馬AIではアセットが工程ごとのグループに分かれていて、起動直後はグループが畳まれた状態で表示されます。グループをクリックすると、中のアセットが展開されます。

    画像

    ‍「ジョブ(job)」‍は、いつも同じ組み合わせで作るアセットのまとまりです。左のメニューの Jobs を開くと、この競馬AIの4つのジョブが並びます。

    画像

    ‍「パーティション(partition)」‍は、同じアセットを名前ごとに分けて残す仕組みです。この競馬AIでは実験名で分けていて、本番用のモデルは main という実験名で作ります。実行するときに実験名を1つ選ぶと、その名前で結果が保存されます。

    画像

    run は、1回の実行のことです。左のメニューの Runs を開くと、これまでの実行が一覧で並び、それぞれの状態(実行中は Started、終われば Success か Failure)と所要時間が確認できます。

    画像

    アセットを開くと、そのアセットの詳細の画面が表示されます。Overview に、説明文と、作られた結果の情報(Metadata)が並びます。

    画像

    3. 競馬AIを作る手順

    ここからは、実際に競馬AIを作る手順を通しで見ていきます。
    ソースコードは以下の記事に添付されているので、ダウンロードしてそのまま使うことができます。

    3.1 dagsterの起動

    ターミナルで v3_6_0/src に移動し、

    cd v3_6_0/src

    次のコマンドを実行します。

    uv run python run_dagster.py

    しばらくすると dagster の起動のログが流れ、最後に画面のアドレスが表示されます。

    出力例(抜粋):

    2026-10-07 10:42:53 +0900 - dagster - INFO - Launching Dagster services...
    2026-10-07 10:42:58 +0900 - dagster-webserver - INFO - Serving dagster-webserver on http://127.0.0.1:3000 in process 43599

    ブラウザで http://127.0.0.1:3000 を開きます。(ポート 3000 を他のアプリが使っているときは、自動で別のポートになります。ターミナルの Serving dagster-webserver on … の行に出ているアドレスを開いてください。)

    画像

    dagster を止めるときは、ターミナルで Ctrl+C を押します。

    【補足】
    run_dagster.py がやっていることは3つです。

    1. 履歴の保存先を用意する。‍実行の履歴や Metadata を保存するフォルダ(v3_6_0/src/.dagster_home)を作ります。メモリを多く使う計算を同時に1つに絞る設定など、dagster の設定ファイル(dagster.yaml)もここにコピーされます。

    2. 実験名 main を登録する。‍本番用の実験名 main を登録します。起動のたびに登録するので、消えてしまっても起動し直せば戻ります。

    3. dagster を起動する。‍ブラウザで操作する画面を立ち上げます。

    3.2 ジョブを実行する

    早速、01_full_pipeline_for_fixed_odds_simulationのジョブを実行してみましょう。

    左のメニューの Jobs から、01_full_pipeline_for_fixed_odds_simulation を選択します。‍

    画像

    02と03のジョブは、時系列オッズ(発走前のオッズを時点ごとに記録したデータ)でのシミュレーションを含んでいるので、時系列オッズを別途用意することで実行できるものです(後ほど詳しく解説)。

    すると、ジョブの画面が開きます。左にこのジョブで作るアセットのグラフ、右に Description(ジョブの説明)が表示されます。

    画像

    Description は Show more を押すと全文が読めます。ジョブの役割・事前に必要なもの・条件を変えて実行する方法が書いてあるので、迷ったときはここを見てください。

    画像

    右上の Materialize all… を押すと「Launch runs to materialize 18 assets」という画面が開くので、Partition selection の選択欄(Select a partition or create one)から main を選びます。

    この「Partition」が「実験名」として扱われ、デフォルトの「main」は本番用モデルとして扱われます。後ほど解説しますが、このPartitionは好きな名前を追加することができ、元のパーティションを残しつつ新しいモデルで実験を試したりすることができます。

    画像

    右下の Launch 1 run を押すと実行が始まります。

    グループをクリックして展開してから、右下の+の虫眼鏡のボタン(もしくは二本指)で拡大すると、アセットごとの状態が表示されます。作り終わったアセットは緑の Materialized に、実行中のアセットは Materializing… に変わっていきます。

    画像

    最後の return_rate_fixed_tansho まで緑になれば完了です。‍これで前処理から単勝の回収率シミュレーションまでの一通りの処理が回り終わって完成しています。

    画像

    学習の設定から先のアセットは実験名ごとに保存されるので、Materialized の代わりに、作られた実験名の数が「1 partition」と緑で表示されます。同じ実験名 main でもう一度実行すると、前回の結果は上書きされます。

    3.3 何が作られたか

    実行が終わると、生テーブルから回収率までの工程のアセットが完成しています。

    画像

    Lineage で見ると、同じ並びでグループが畳まれています。

    画像

    rawdf は、netkeiba.com から集めた生テーブルです。dagster の外で用意するデータなので、グループをクリックして展開すると、中の生テーブルは灰色の破線の枠で表示されます。dagster で作るアセット(作り終わると緑の枠)と違って、クリックしても materialize はできません。

    画像

    前処理の各テーブル(create_features)‍

    create_features では、population を起点に8つのテーブルを前処理し、払い戻し以外の7つを population に結合して特徴量テーブルを作ります。

    画像

    それぞれの中身を、実際のデータで見ていきましょう。
    表では、同じ ID の列を同じ色にしています(race_id は青、horse_id は橙、騎手・調教師・父などの ID は緑)。

    ‍■population(出走の一覧)‍
    まずは「母集団」を表す「population」アセットです。

    画像

    1行が1頭の出走(あるレースに出た1頭)で、レースの ID・日付・馬の ID の3列だけを持ちます。

    ‍■results(レース結果)‍

    画像

    そのレースの結果です。1行が1頭の出走で、着順・馬番・単勝オッズ(確定オッズ)・人気・馬体重・騎手の ID など、レースが終わって決まる値を持ちます。

    ‍■race_info(レース情報)‍

    画像

    レースの条件です。1行が1レースで、芝かダートか・距離・天候・馬場などを数字のコードで持ちます。

    ‍■horse_results(馬の過去成績)‍

    画像

    馬の過去成績です。1行が馬の1走で、同じ馬の過去のレースが何行も並びます。ここから、直近3・5・10走の着順や賞金の平均(rank_5races など)が計算されて特徴量になります。

    ‍■peds(血統)‍

    画像

    血統です。1行が1頭で、父(sire_id)と母の父(bms_id)の ID を持ちます。

    ‍■騎手・調教師・種牡馬のリーディング

    画像

    騎手・調教師・種牡馬の年ごとの成績です。1行が騎手×年などで、勝率・連対率・複勝率・出走数を持ちます。種牡馬は芝とダートで行が分かれます。

    ‍■return_tables(払い戻し)‍

    画像

    払い戻しです。1行が1レースの券種×的中馬番で、100円あたりの払戻金を持ちます。特徴量には使わず、回収率の計算に使います。

    学習データ(dataset_tansho_train)‍

    ここで、アセット詳細の画面で中身を確認してみましょう。
    アセット詳細を開くには、ジョブの画面のグラフでグループをクリックして展開し、アセットをクリックして選びます。右側の Info がそのアセットの概要に切り替わるので、View in Asset Catalog を押します。

    画像
    画像

    dataset_tansho_trainは、特徴量テーブルを期間で分けた、学習用のデータです。検証用(dataset_tansho_valid)・テスト用(dataset_tansho_test)と合わせて3つが作られ、Metadata には行数と期間の設定が記録されます。

    画像

    3つの期間は、時系列の順に分けています。モデルが学習するのは学習データだけです。検証データは、学習の途中で精度を見ながら止めどきを決める early stopping と、確率補正モデルの学習に使います。

    テストデータは学習に一切使わない、未来のレースの代わりのデータで、モデルの精度と回収率はこのテストデータで確かめます。期間の分け方について詳しくは、#42の記事で解説しています。

    学習の設定(train_config)‍
    学習に使う特徴量の列と、LightGBM のハイパーパラメータです。

    画像
    画像

    実験名ごとに保存されるので、あとから別の設定で実験を足すこともできます(5.1で詳しく解説)。

    単勝予測モデル(model)‍
    LightGBM で学習した、各馬の勝率を予測するモデルです。

    画像
    画像

    LightGBM について詳しくは、#8の記事で解説しています。

    Metadata の importance の [Show Markdown] を開くと、どの特徴量が予測に効いているかの図が表示されます。

    画像

    確率補正モデル(calibration_model)‍
    モデルが出す予測確率を、実際の勝率に近づけるように補正(キャリブレーション)するモデルです。

    画像
    画像

    期待値の計算には、この補正後の確率を使います。キャリブレーションについて詳しくは、#49の記事で解説しています。

    評価テーブル(evaluation_df_fixed)‍
    テストデータの各馬に、予測確率と確定オッズを付けた表です。

    画像
    画像

    ▼v3_6_0/data/assets/evaluation_df_fixed/main.parquet の中身(抜粋)

    race_id       horse_id    target  target_mod  rank  tansho_odds  popularity  umaban  pred      pred_calibrated
    202506010101  2022102642  0       0           11    231.3        15          1       0.004326  0.002547
    202506010101  2022101022  0       0           6     50.1         7           2       0.023532  0.016147
    202506010101  2022106581  0       0           2     12.0         6           3       0.086071  0.066138
    202506010101  2022100105  0       0           8     8.4          4           4       0.109912  0.086142
    202506010101  2022102964  0       0           10    196.9        13          5       0.003669  0.002128
    202506010101  2022107201  0       0           15    75.8         9           6       0.013303  0.008670
    202506010101  2022101692  0       0           9     11.6         5           7       0.095148  0.073715
    202506010101  2022106350  0       0           7     211.8        14          8       0.003726  0.002164
    202506010101  2022102984  0       0           12    131.9        10          9       0.009860  0.006254
    202506010101  2022103727  0       0           4     2.8          2           10      0.309921  0.260131
    202506010101  2022105247  1       1           1     2.5          1           11      0.307763  0.258230
    202506010101  2022100076  0       0           5     7.3          3           12      0.133421  0.106141
    202506010101  2022107050  0       0           3     156.0        11          13      0.006822  0.004185
    202506010101  2022102350  0       0           14    189.5        12          14      0.004377  0.002579
    202506010101  2022103312  0       0           16    556.3        16          15      0.003462  0.001998
    202506010101  2022101055  0       0           13    73.0         8           16      0.017353  0.011585

    pred がモデルの予測確率、pred_calibrated が確率補正モデルで補正した確率で、期待値の計算には pred_calibrated を使います。rank は着順、tansho_odds は確定オッズ、target は1着なら1になる正解の列、target_mod は学習に使った目的変数です。この表から、次の回収率のシミュレーションが計算されます。

    回収率シミュレーション結果(return_rate_fixed_tansho)‍
    評価テーブルと払い戻しのテーブルから計算した、確定オッズ×単勝の回収率シミュレーション結果です。

    画像
    画像

    ここに出ているのは、回収率カーブの中で sharp_ratio(回収率の安定度)が最も高い閾値の行の値です。指標の意味は次のとおりです。

    指標            意味
    expect_return   期待値の閾値(この値を超えた馬券を買う)
    total_bets      買った馬券の点数(1点100円)
    hits            払い戻しがあったレース数
    hit_rate        レース単位の的中率(hits ÷ 買ったレース数)
    return_rate     回収率(払い戻しの合計 ÷ 購入点数)
    std             回収率のぶれ幅(標準誤差)
    sharp_ratio     回収率の安定度((return_rate − 1) ÷ std。大きいほど安定)

    return_rate_curve の [Show Markdown] を開くと、回収率プロットが表示されます。

    画像

    グラフの横軸は期待値の閾値、縦軸は回収率で、帯はぶれ幅を表しています。


    以上が、1つのジョブで完成するアセットです。
    これらの結果は、次のようにファイルとして保存されます。

    v3_6_0/data/assets/
    ├── population.parquet              出走の一覧
    ├── results.parquet                 レース結果
    ├── race_info.parquet               レース情報
    ├── horse_results.parquet           馬の過去成績
    ├── peds.parquet                    血統
    ├── jockey_leading.parquet          騎手の年次成績
    ├── trainer_leading.parquet         調教師の年次成績
    ├── sire_leading.parquet            種牡馬の年次成績
    ├── return_tables.parquet           払い戻し
    ├── features.parquet                特徴量テーブル
    ├── dataset_tansho_train.parquet    学習データ
    ├── dataset_tansho_valid.parquet    検証データ
    ├── dataset_tansho_test.parquet     テストデータ
    ├── train_config/
    │   └── main.pkl                    学習の設定
    ├── model/
    │   └── main.pkl                    単勝予測モデル
    ├── calibration_model/
    │   └── main.pkl                    確率補正モデル
    ├── evaluation_df_fixed/
    │   └── main.parquet                評価テーブル(確定オッズ)
    └── return_rate_fixed_tansho/
        └── main.parquet                回収率カーブ(確定オッズ×単勝)

    保存されたファイルは、pandas で読み込んで中身を確かめられます。リポジトリの直下で uv run python を実行して Python を起動し、例えば次のように入力します。

    import pandas as pd
    
    # 特徴量テーブル
    features = pd.read_parquet("v3_6_0/data/assets/features.parquet")
    print(features.shape)   # (行数, 列数)
    print(features.head())  # 先頭の5行
    
    # 評価テーブル(実験名 main)
    evaluation = pd.read_parquet("v3_6_0/data/assets/evaluation_df_fixed/main.parquet")
    print(evaluation.head())
    
    # 学習の設定(実験名 main)
    train_config = pd.read_pickle("v3_6_0/data/assets/train_config/main.pkl")
    print(train_config["params"])  # LightGBM のハイパーパラメータ

    ほかのファイルも、.parquet は pd.read_parquet、.pkl は pd.read_pickle で同じように読み込めます。

    4. データの追加・設定の変更

    次に、データを追加したい場合の設定方法や、時系列オッズを使ったシミュレーションの方法等を見ていきます。

    4.1 データを足したとき

    学習期間等の設定を変えて実行するときは、Launchpad(ランチパッド)‍という画面を使います。

    01_full_pipeline_for_fixed_odds_simulation の画面で Materialize all… の横の ▼ を押し、Open launchpad を選びます。‍

    画像

    Launchpad は、アセットを実行する前に、今回はどんな設定(Config)で動かすかをその場で書き換えられる画面です。(詳しくは#59の記事で解説しています。)

    Launchpad が開いたら、Partition の欄で main を選びます。‍

    画像

    設定欄には、このジョブに含まれるアセットの設定が YAML で並んでいます。例えば2026年6月末までのデータを使うなら、母集団に含めるレースの終了日:to_date と、テストデータの終了日:test_end_date を'2026-06-30'にすれば良い、というわけです。

    ops:
      dataset_tansho:
        config:
          rank_threshold: 1
          target_strategy: 2
          test_end_date: '2026-06-30'
          test_start_date: '2025-01-01'
          train_start_date: '2020-01-01'
          valid_start_date: '2024-12-01'
      population:
        config:
          from_date: '2020-01-01'
          to_date: '2026-06-30'

    これで Materialize を押すことで実行が始まり、このジョブの全部のアセットが、書き換えた期間で作り直されます。

    4.2 デフォルト設定を変えたいとき

    Launchpad に入力した値はこの実行にだけ使われ、次に Launchpad を開いたときや Materialize のボタンから実行したときは既定値に戻ります。毎回同じ期間で実行したいなら、コードの次の2箇所を書き換えます。

    ‍▼v3_6_0/src/pipeline/assets/features.py(抜粋)‍

    class PopulationConfig(dg.Config):
        from_date: str = "2020-01-01"
        to_date: str = "2025-12-31"

    from_date と to_date が、母集団(population)に含めるレースの期間です。

    ‍▼v3_6_0/src/pipeline/assets/training_datasets.py(抜粋)‍

    class DatasetConfig(dg.Config):
        """学習・検証・テストデータ分割の期間・目的変数・着順閾値設定。"""
    
        train_start_date: str = "2020-01-01"
        valid_start_date: str = "2024-12-01"
        test_start_date: str | None = "2025-01-01"
        test_end_date: str | None = "2025-12-31"
        target_strategy: int = 2
        rank_threshold: int = 1

    train_start_date・valid_start_date・test_start_date・test_end_date が、学習・検証・テストの期間です。

    例えば2026年6月末までのデータを使うなら、to_date と test_end_date を 2026-06-30 に書き換えます(Launchpad に入力した値と同じです)。

    コードを書き換えたら、Reload definitions を押します。‍Lineage の画面の右上にボタンがあります。

    画像

    Reload definitions は、直したコードを dagster の画面に読み込み直す操作で、これを押せばdagster上に設定が反映されます。

    4.3 時系列オッズでシミュレーションしたいとき

    時系列オッズ(発走直前のオッズ)でのシミュレーションは、手元にある時系列オッズに合うジョブで行います。時系列オッズは、JRA-VAN の公式ソフトから取得するか、JRA の公式サイトからスクレイピングして集めます。

    ジョブ                                          必要なもの                           券種
    01_full_pipeline_for_fixed_odds_simulation      netkeiba.com の生テーブル(rawdf)    単勝(確定オッズ)
    02_full_pipeline_for_jravan_odds_simulation     + JRA-VAN の時系列オッズ             単勝・馬連
    03_full_pipeline_for_scraping_odds_simulation   + スクレイピングの時系列オッズ       単勝・馬連・馬単・三連複・三連単
    04_full_pipeline_for_additional_models          + 両方の単複の時系列オッズ           複勝(複勝のモデルを作る)

    確定オッズと直前オッズの違いと、時系列オッズの集め方は、JRA-VAN なら#28の記事、スクレイピングなら#25の記事で解説しています。

    01のジョブを実行して学習まで作ってあれば、特徴量やモデルを作り直す必要はありません。新しく作るのは、時系列オッズの取り込み(latest_odds_for_simulation)と評価・回収率(simulation)のアセットだけです。

    • JRA-VAN のオッズでシミュレーションしたい場合: 02_full_pipeline_for_jravan_odds_simulation

    • スクレイピングしたオッズでシミュレーションしたい場合: 03_full_pipeline_for_scraping_odds_simulation

    の画面を開き、latest_odds_for_simulation と simulation のグループのアセットを選びます。‍

    複数のアセットを選ぶときは、Shift を押しながらクリックします。選ぶと、右上のボタンが Materialize selected (5)… のように選んだ数の付いた表示に変わります。

    画像

    Materialize selected (5)… を押し、Partition selection で main を選んで Launch 1 run を押します。‍

    画像

    学習済みのモデルと同じ実験名を選ぶのがポイントです。1〜2分ほどで終わり、結果は先ほどと同じように、return_rate_jravan_tansho などの Metadata に出ます。

    04_full_pipeline_for_additional_models は複勝のモデルを作るジョブで、単勝のモデルと同じ仕組みで複勝のモデルも作れます。

    4.4 シミュレーションの条件を変えるとき

    発走の何分前のオッズを使うか(minutes_before)と、期待値の閾値をどの範囲で動かすか(min_exp・max_exp)等も、アセットの設定で変えられます。オッズを変えると評価と回収率も作り直しになるので、前の節と同じ5つのアセットを選んだ状態から Launchpad を開きます。

    画像

    Partition の欄で main を選び、設定欄を書き換えます。‍

    画像

    設定欄には、選んだアセットの設定がまとめて並びます。

    ops:
      odds_jravan_tanpuku:
        config:
          minutes_before: 6
      odds_jravan_umaren:
        config:
          minutes_before: 6
      return_rate_jravan_tansho:
        config:
          max_exp: 1.7
          min_exp: 1
          min_pred: 0.01
          n_samples: 100
      return_rate_jravan_umaren:
        config:
          max_exp: 4
          min_exp: 1
          min_pred: 0.01
          n_samples: 100

    例えば JRA-VAN のオッズを発走10分前のものに変えるなら、2つのオッズのアセットの minutes_before を 10 にします。回収率の閾値の範囲を変えるなら、回収率のアセットの min_exp と max_exp を書き換えます(min_pred と n_samples はそのままで構いません)。

    設定が終わったら、同様に右下の Materialize を押すことでオッズの取り込みから回収率までが、書き換えた条件で1回の実行で作り直されます。学習済みのモデルはそのままです。

    5. 実験の追加・比較・削除

    学習の設定を変えて試すときは、main とは別の実験名を付けて実行します。実験をいくつ足しても、当日投票が読むのは main のモデルだけです。実験は main とは別の名前で保存されるので、本番用のモデルを残したまま、別の設定を試せます。実験名とパーティションの仕組みについて詳しくは、#65の記事で解説しています。

    5.1 実験を足すとき

    例えば試しに、オッズと人気を特徴量から外す実験をしてみましょう。

    01_full_pipeline_for_fixed_odds_simulation の画面で train のグループを開き、train_config をクリックして選びます。‍

    画像

    ▼ を押して Open launchpad を選びます。‍

    画像

    Launchpad の Add new partition を押し、Partition name に実験名を入力して Save を押します。‍

    画像
    画像

    実験名に使える文字は、英数字と _ だけにしてください。追加した実験名は、そのまま Partition の欄で選ばれた状態になります。

    次に、設定欄の features(学習に使う列)や params(ハイパーパラメータ)を書き換えます。‍

    画像

    features の {col} の下にある列名の一覧から tansho_odds と popularity の2行を消しています。

    Materialize を押すと実行が始まり、新しい実験名の学習の設定(train_config)が作られます。

    次に、ジョブの画面に戻り、▼ボタンから Materialize unsynced を選びます。‍

    画像

    後ほど詳しく説明しますが、Materialize unsynced は、上流より古くなったアセットと、まだ作っていないアセットをまとめて選ぶ機能です。ここでは、新しい実験名の結果がまだ無いアセット(モデル・確率補正モデル・評価テーブル・回収率)が一覧に出ます。

    この画面でMaterialize 4 assets を押し、Partition selection で実験名を選んで Launch 1 run を押します。‍

    画像

    これで依存関係に従って、モデルの学習から回収率までが新しい実験名で作られます。

    5.2 実験を比べるとき

    アセット詳細の Partitions タブを開くと、左に実験名の一覧が並び、選んだ実験名の結果が右側に表示されます。

    画像

    Overview の Metadata を Plots に切り替えると、回収率などの数値を、実験名を横軸にして並べたグラフで見比べられます。

    画像

    5.3 実験を消すとき

    実験を消したいときは、アセット詳細でMaterialize… の横の ▼ を押し、Delete partitions を選びます。‍

    画像

    Delete experiment partitions のダイアログで消したい実験名を選び、Delete 1 partition を押します。‍

    画像

    6. コードの修正

    6.1 コードを改修したとき

    先ほど見たように、コードを改修したら Lineage の画面の右上の Reload definitionsで反映します。

    画像

    Reloadしたら以下の手順で反映するとスムーズです。

    • まずは直したアセットだけを選んで Materialize selected… を押し、作り直す

    • 下流のアセットに Unsynced の印が付くので、Materialize unsynced で必要なアセットを作り直す。

    上流のアセットが作り直されると、それを読む下流のアセットは古くなった状態(Unsynced)になり、アセットの左上に橙色の点が付きます。

    画像
    population を作り直した直後の 01_full_pipeline_for_fixed_odds_simulation の画面の例。
    下流のpeds, race_info, results, featuresの左上に橙色の点が付いていることがわかる。

    Materialize unsynced を選ぶと、印の付いたアセットの一覧が出るので、Materialize 6 assets のように一覧の数が付いたボタンを押して流します。

    画像

    7. 失敗時のデバッグ方法

    7.1 実行が失敗したとき

    実行が途中で失敗すると、run の状態が Failure になるので、Viewで詳細を確認します。

    画像

    Events で STEP_FAILURE の行を探し、View full message を押すことで、どのアセットで、どんなエラーが出たかが表示されます。

    画像

    原因を直したら、run の画面の Re-execute all の横の ▼ を押し、From failure を選ぶと、失敗したところから再実行することができます。

    画像

    7.2 check が失敗したとき

    この競馬AIのアセットには、データの検査(asset check)が付いています。アセットが作られるたびに自動で実行され、結果はアセット詳細の Checks タブに Passed か Failed で表示されます。ERROR の検査が失敗すると、その下流のアセットは実行されずに run が Failure になります。WARN は警告だけで、下流は止めません。‍

    画像
    check                  対象                                            何を見ているか                        落ちる典型                      対処
    covers_population      race_info・horse_results・peds・return_tables   母集団のレースと馬が全部あるか        rawdf の一部が古い              データを集め直して作り直す
    covers_prev_years      騎手・調教師・種牡馬のリーディング              各年の前年のリーディングがあるか      新しい年を足したが前年分が無い  同上
    bet_types_complete     return_tables                                   全レースに7券種の払い戻しがあるか     払い戻しの取りこぼし            同上
    no_degenerate_columns  features                                        全欠損・全0の列が無いか               前処理の不具合                  失敗した列を Metadata で見て直す
    race_coverage          時系列オッズのアセット                          テスト期間のレースにオッズがある割合  時系列オッズが期間に無い        0件なら ERROR で止まる。0.85未満は WARN で進む

    asset check について詳しくは#62の記事で解説しています。

    8. ソースコードのダウンロード

    ソースコードは、以下の記事に最新版が添付されているので、そこからダウンロードすることができます。

    上記記事には、今回の記事で紹介したソースコード含め、データ収集・機械学習モデル構築・サーバー上での自動投票など、本格的な競馬AIの運用に必要な全工程のコードが含まれています。

    また、この【競馬AI開発】シリーズでは、#1から開発過程(上記コードの作り方)を詳しく解説しているので、ご自身で競馬予想AIを開発・活用してみたいとお考えの方は、ぜひ過去の記事も併せてご覧ください。


    この記事が参加している募集

     
     
    競馬予想AIを作ることを通して、機械学習・データサイエンスの勉強になるコンテンツの発信や、筆者が行った実験の共有などを行っていきます。

    あなたへのおすすめ