【競馬AI開発#16】特定条件における馬の過去成績を特徴量に追加する
この【競馬AI開発】シリーズでは、競馬予想AIを作ることを通して、機械学習・データサイエンスの勉強になるコンテンツの発信や、筆者が行った実験の共有などを行っていきます。
■今回やること
今回は、競馬予想AIに以下の予測材料を追加することで、精度向上を目指します。
予測対象レースと同じ距離における、各馬の最速タイム
予測対象レースと同じレース階級/開催場所/馬場状態/天気における、各馬の成績
1については、走破タイムを利用した特徴量(=機械学習モデルにインプットする予測材料のこと)を作成したいというモチベーションになります。
同じ距離における走破タイムを比較することで、着順などの相対的な値(=他の馬の強さによって決まる値)に比べて、より純粋に「その距離における速さ」を評価して学習させることができるのではないか、という仮説です。
2については、例えば同じ1着でも未勝利クラスでの成績なのか、G1クラスでの成績なのかによって意味合いが全く違うので、まずはそこを考慮したい、というのが目的になります。
また、現在馬の過去成績として使用している特徴量(計88個)は、どんな条件のレースかによらずに着順や賞金などの成績を集計しているので、開催場所/馬場状態ごとの成績なども追加することで、特定条件で好走する馬の特徴を拾って精度を上げることできないかも試していきます。
馬場状態の得意/不得意はなんとなく想像がつきますが、特定の競馬場が得意な馬なども存在するらしいのです(コメント欄でも複数意見をいただきました)。
この記事ではこのように、競馬というゲームの特性・知識(=ドメイン知識)を踏まえながら、上記のような特徴量追加の実装方法やどのように比較実験を行えば良いかを、実際のソースコードと共に解説していきます。
使用するソースコードは、下に進んでダウンロード・解凍すればそのまま使うことができるので、適宜手元で参照・実行しながらお読みください。
■筆者のプロフィール
東京大学大学院卒業後、データサイエンティストとしてWEBマーケティング調査会社でWEB上の消費者行動ログ分析などを経験。
現在は、大手IT系事業会社で、転職サイトのレコメンドシステムの開発を行っています。
定期購読をすると、今月更新される記事に加えて#1〜#4の記事が980円で全て読めるので、単品購入より圧倒的にお得です。
ソースコードのダウンロード
■ディレクトリ構成
.
├── requirements.txt ・・・必要なライブラリを記載
├── README.md ・・・ディレクトリ構成を記載(本ファイル)
├── common
│ ├── data
│ │ ├── html
│ │ │ ├── race
│ │ │ │ └── {race_id}.bin ・・・スクレイピングしたraceページのhtml
│ │ │ ├── horse
│ │ │ │ └── {horse_id}.bin ・・・スクレイピングしたhorseページのhtml
│ │ │ └── leading
│ │ │ ├── jockey_leading ・・・スクレイピングした騎手リーディングページのhtml
│ │ │ │ └── trainer_leading ・・・スクレイピングした調教師リーディングページのhtml
│ │ ├── rawdf
│ │ │ ├── results.csv
│ │ │ ├── horse_results.csv
│ │ │ ├── horse_results_prediction.csv
│ │ │ ├── jockey_leading.csv
│ │ │ ├── trainer_leading.csv
│ │ │ ├── return_tables.csv
│ │ │ └── race_info.csv
│ │ ├── mapping ・・・カテゴリ変数から整数へのマッピング
│ │ │ ├── around.json
│ │ │ ├── ground_state.json
│ │ │ ├── race_class.json
│ │ │ ├── race_type.json
│ │ │ ├── place.json
│ │ │ ├── sex.json
│ │ │ └── weather.json
│ │ └── prediction_population ・・・予測母集団(開催日, race_id, horse_id)
│ │ └── population.csv
│ └── src
│ ├── create_rawdf.py ・・・htmlをDataFrameに変換する関数を定義
│ ├── main.ipynb ・・・コードを実行するnotebook
│ ├── dev.ipynb ・・・開発用notebook
│ ├── create_prediction_population.py ・・・予測母集団を作成する関数を定義
│ └── scraping.py ・・・スクレイピングする関数を定義
├── v3_0_4
├── v3_exp5 ・・・実験用のバージョン
└── v3_0_5
├── data
│ ├── 00_population ・・・学習母集団を保存するディレクトリ
│ │ └── population.csv
│ ├── 01_preprocessed ・・・前処理済みのデータを保存するディレクトリ
│ │ ├── horse_results.csv
│ │ ├── horse_results_prediction.csv
│ │ ├── return_tables.pickle
│ │ ├── results.csv
│ │ ├── jockey_leading.csv
│ │ ├── trainer_leading.csv
│ │ └── race_info.csv
│ ├── 02_features ・・・全てのテーブルを集計・結合した特徴量を保存するディレクトリ
│ │ └── features.csv
│ ├── 03_train ・・・学習結果を保存するディレクトリ
│ │ ├── model.pkl ・・・学習済みモデル
│ │ ├── evaluation.csv ・・・検証データに対する予測結果
│ │ ├── importance.csv ・・・特徴量重要度(一覧)
│ │ └── importance.png ・・・特徴量重要度(上位を可視化)
│ │ ├── model_odds_removed.pkl ・・・学習済みモデル(オッズと人気を抜いたモデル)
│ │ ├── evaluation_odds_removed.csv ・・・検証データに対する予測結果(オッズと人気を抜いたモデル)
│ │ ├── importance_odds_removed.csv ・・・特徴量重要度(オッズと人気を抜いたモデル)
│ │ └── importance_odds_removed.png ・・・特徴量重要度(オッズと人気を抜いたモデル)
│ └── 04_evaluation ・・・検証データに対する精度評価結果を保存するディレクトリ
└── src
├── dev.ipynb ・・・開発用notebook
├── main.ipynb ・・・コードを実行するnotebook
├── create_population.py ・・・学習母集団を作成する関数を定義
├── preprocessing.py ・・・/common/rawdf/のデータを前処理する関数を定義
├── feature_engineering.py ・・・機械学習モデルにインプットする特徴量を作成するクラスを定義
├── config.yaml ・・・学習に用いる特徴量一覧
├── config_odds_removed.yaml・・・学習に用いる特徴量一覧(オッズと人気を抜いたモデル)
├── train.py ・・・学習処理を行うクラスを定義
├── evaluation.py ・・・モデルの精度評価を行うクラスを定義
└── prediction.py ・・・予測処理を行う関数を定義
ここから先は
¥ 1,480
この記事が気に入ったらサポートをしてみませんか?