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

【競馬AI開発#14】LightGBMのハイパーパラメータって結局どうすれば良いの?

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

    学習から予測までの競馬予想AIのコードが一通り完成したので、今は実験を繰り返して精度をさらに高めていくフェーズに入っています。

    ■今回やること
    今回は「ハイパーパラメータの調整」について、ベストな方法を探っていきます。
    「ハイパーパラメータ」とは、機械学習モデルの学習プロセスを制御する設定値のことで、これらはモデルの訓練前に外から設定します。例えば、決定木モデルの「木の深さ」や「葉の数」などがこれに該当します。

    画像
    決定木のイメージ。
    インプットした変数の大小によって、データを分類していくことで予測を行う。

    特に、今使用している「LightGBM」という機械学習モデルは、ハイパーパラメータを適切に設定しないと、モデルが訓練データに過度に適応する「過学習」が起きやすく、予測精度が落ちてしまいます。

    「LightGBM」については、以下の記事で詳しく解説しているので、参考までに。

    ■LightGBMのハイパーパラメータ調整が難しい理由
    LightGBMには多数のハイパーパラメータが存在しており、ざっと列挙するだけでも以下のようなものがあります。

    ・learning_rate
    ・num_leaves
    ・max_depth
    ・min_data_in_leaf
    ・min_sum_hessian_in_leaf
    ・bagging_fraction
    ・bagging_freq
    ・feature_fraction
    ・early_stopping_round
    ・lambda_l1
    ・lambda_l2
    ・min_gain_to_split
    ・max_bin
    ・metric

    前提として、最適なハイパーパラメータは一概に決められるものではなく、学習させるデータによって変わってくるので、厳密に最適化しようと思うと、インプットするデータを変える度(特徴量の追加も含む)にこれらのハイパーパラメータを全て調整しなければなりません。

    ですが、様々な特徴量を試してモデルの精度を上げていきたい局面では、特徴量を変える度にハイパーパラメータを微調整するのは非効率なため、「ある程度適当な値」で固定しておきたい事情もあります。

    そこでこの記事では、「Kaggle」でGoldの成績を残した実績のあるハイパーパラメータ一覧の集計や、自動最適化ツール「optuna」ではどのように最適化されているか?コードを読み解くことを通じて、

    ✅ ハイパーパラメータは大体どの程度の値に設定しておけば間違いないか?
    ✅ 上記ハイパーパラメータの中でも、どれが特に重要で、どの順に最適化するのが良いのか?

    について探っていきます。また、それを今作成している競馬予想AI作成のコードに適応し、精度の変化について見ていきます。
    使用するソースコードは、下に進んでダウンロード・解凍すればそのまま使うことができるので、適宜手元で参照・実行しながらお読みください。

    ■動画

    ■筆者のプロフィール
    東京大学大学院卒業後、データサイエンティストとしてWEBマーケティング調査会社でWEB上の消費者行動ログ分析などを経験。
    現在は、大手IT系事業会社で、転職サイトのレコメンドシステムの開発を行っています。

    定期購読をすると、今月更新される記事に加えて#1〜#4の記事が980円で全て読めるので、単品購入より圧倒的にお得です。

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

    ■ファイルに含まれるソースコード一覧
    main.ipynbを実行することで、データ取得〜予測まで全て行うことができます。

    .
    ├── requirements.txt                ・・・必要なライブラリを記載
    ├── README.md                       ・・・ディレクトリ構成を記載(本ファイル)
    ├── common
    │   ├── data
    │   │   ├── html
    │   │   │   ├── race
    │   │   │   │   └── {race_id}.bin   ・・・スクレイピングしたraceページのhtml
    │   │   │   └── horse
    │   │   │       └── {horse_id}.bin  ・・・スクレイピングしたhorseページのhtml
    │   │   ├── rawdf
    │   │   │   ├── results.csv
    │   │   │   ├── horse_results.csv
    │   │   │   ├── horse_results_prediction.csv
    │   │   │   ├── return_tables.csv
    │   │   │   └── race_info.csv
    │   │   ├── mapping                 ・・・カテゴリ変数から整数へのマッピング
    │   │   │   ├── around.json
    │   │   │   ├── ground_state.json
    │   │   │   ├── race_class.json
    │   │   │   ├── race_type.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_2
    │   ├── data
    │   └── src
    ├── v3_exp3                     ・・・今回の実験を行うディレクトリ
    │   ├── data
    │   │   ├── 00_population       ・・・学習母集団を保存するディレクトリ
    │   │   │   └── population.csv
    │   │   ├── 01_preprocessed     ・・・前処理済みのデータを保存するディレクトリ
    │   │   │   ├── horse_results.csv
    │   │   │   ├── horse_results_prediction.csv
    │   │   │   ├── return_tables.pickle
    │   │   │   ├── results.csv
    │   │   │   └── race_info.csv
    │   │   ├── 02_features         ・・・全てのテーブルを集計・結合した特徴量を保存するディレクトリ
    │   │   │   └── features.csv
    │   │   ├── 03_train            ・・・学習結果を保存するディレクトリ
    │   │   │   ├── model.pkl           ・・・学習済みモデル
    │   │   │   ├── evaluation.csv      ・・・検証データに対する予測結果
    │   │   │   ├── importance.csv      ・・・特徴量重要度(一覧)
    │   │   │   └── importance.png      ・・・特徴量重要度(上位を可視化)
    │   │   └── 04_evaluation       ・・・検証データに対する精度評価結果を保存するディレクトリ
    │   └── src
    │       ├── dev.ipynb               ・・・開発用notebook
    │       ├── main.ipynb              ・・・コードを実行するnotebook
    │       ├── create_population.py    ・・・学習母集団を作成する関数を定義
    │       ├── preprocessing.py        ・・・/common/rawdf/のデータを前処理する関数を定義
    │       ├── feature_engineering.py  ・・・機械学習モデルにインプットする特徴量を作成するクラスを定義
    │       ├── config.yaml             ・・・学習に用いる特徴量一覧
    │       ├── train.py                ・・・学習処理を行うクラスを定義
    │       ├── evaluation.py           ・・・モデルの精度評価を行うクラスを定義
    │       └── prediction.py           ・・・予測処理を行う関数を定義
    └── v3_0_3                      ・・・実験結果を反映した新しいバージョン
        ├── data
        └── src
     
     
    競馬予想AIを作ることを通して、機械学習・データサイエンスの勉強になるコンテンツの発信や、筆者が行った実験の共有などを行っていきます。

    あなたへのおすすめ