LightGBMによるAI競馬予想(チューニング編)

AI競馬

チューニングの知識

PC-KEIBA Database」と「LightGBM」で優れたAI競馬予想を作るために最低限必要なチューニング方法をまとめました。その前に、この記事を読む前に最低限知っておく必要がある単語を2つ説明します。

  1. 決定木
  2. 過学習

決定木

「決定木(けっていぎ)」とはデータをツリー状に分類して予測するデータ分析の手法です。LightGBMアルゴリズムの核でもあります。予測精度を改善するには、いかに良い決定木を作れるかにかかってます。

過学習

「過学習(かがくしゅう)」とは学習データに一致しすぎて、未知のデータを予測できない状態を指します。その原因は名前のとおり、学習データに対する学習が過剰すぎるからです。また、過学習対策は予測精度の改善に欠かせない重要課題です。

学習データをチューニング

まずこいつが先。役に立たない学習データを使ってたらLightGBMのパラメータをチューニングしても意味がない(笑)

学習データを増やす

データ分析の世界では一般的にデータが多いほど信頼できるけど、競馬の場合はルールや条件とか時代とともに色々変わります。なので古すぎるデータは使わないことに注意しつつ、上手く増やしてください。データの内容によっては古すぎても多いほどOKですが。

データクレンジングする

統計学におけるデータの基本処理。競馬予想においては、学習データから競走中止、失格、降着があったレースを除外する。

説明変数をチューニング

ポイントは次の3つ。

  1. いきなり学習データを作るんじゃなくて、SQLで1つ1つ回収率と的中率を検証しながら説明変数を加える。これも「PC-KEIBA Database」が得意とする仕事です。
  2. レース結果に影響がないモノを説明変数に加えても意味がない。逆に単勝オッズなど影響が強すぎて結局は人気と同じ予想になるモノを説明変数に加えても意味がない。
  3. 新聞と赤ペンだけで予想してる凡人が思いつかないようなアイデア(説明変数)を考える。例えば馬体重はそのまんま使うんじゃなくて、レース単位の相対的な順位に変換するとか。

パラメータをチューニング

競馬予想でも例外なく使えそうなLightGBMの代表的なパラメータをピックアップしました。このサイトではSQLで学習データを作ることを前提にしてるので、SQLで同じことができるパラメータは無視してます。それとコンテストで速さを競うつもりも無いから、そういうのも無視してます。

管理人@PC-KEIBAがピックアップしたパラメータは次の6つです。たぶんこれだけで良いのでは?と思ってます。

  1. num_iterations
  2. num_leaves
  3. max_depth
  4. min_data_in_leaf
  5. lambda_l1
  6. lambda_l2

num_iterations

型 int
初期値 100

決定木を何本まで試作するか。この値を大きくするほど予測精度の高いモデルが誕生する可能性が高くなります。当然、増やすほど時間はかかるけど。

num_leaves

型 int
初期値 31

決定木の「葉」の最大数。この値が大きいほど過学習に。例えばnum_leavesを6から5にした決定木は、こんな感じに変わります。

max_depth

型 int
初期値 -1 (上限なし)

決定木の「深さ」の最大数。この値が大きいほど過学習に。深くなるほど複雑な決定木になります。

min_data_in_leaf

型 int
初期値 20

1枚の葉に含むデータの最小数。この値が小さいほど過学習に。例えばmin_data_in_leafを100から200にした決定木は、こんな感じに変わります。

データ数180の葉が除外されて1つ手前の葉で終了、ということ。

lambda_l1

型 double
初期値 0.0 (正則化しない)

L1正則化。この値が小さいほど過学習に。大きくするほど不要な説明変数を除外します。

lambda_l2

型 double
初期値 0.0 (正則化しない)

L2正則化。この値が小さいほど過学習に。過学習を防ぐために使います。

L1正則化とL2正則化の違いや、それぞれの仕組みについてはちょっと複雑なのであえて書きません。ググって勉強してください。

パラメータを書く場所

この記事で紹介したパラメータは「学習用ソースコード」に書きます。

この「AI競馬」のカテゴリで無料で公開しているソースコードを例に説明します。

二値分類(binary)

二値分類の場合「# LightGBM パラメータ」のコメントがある部分に追記します。こんな感じです。区切り文字のカンマ(,)を忘れないよう注意。

# LightGBM パラメータ
params = {
  'objective':'binary',    # 目的 : 二値分類
  'metric':'binary_error', # 評価指標 : 不正解率(1 - 正解率)
  'num_iterations':100,
  'num_leaves':31,
  'max_depth':-1,
  'min_data_in_leaf':20,
  'lambda_l1':0.0,
  'lambda_l2':0.0
}
  • 多クラス分類(multiclass)
  • 回帰分析(regression)

の場合も同じです。

ランキング学習(lambdarank)

ランキング学習の場合は「# モデルの学習」のコメントがある部分に追記します。こんな感じです。区切り文字のカンマ(,)を忘れないよう注意。

# モデルの学習
model = lgb.LGBMRanker(
  random_state=0,
  num_iterations=100,
  num_leaves=31,
  max_depth=-1,
  min_data_in_leaf=20,
  lambda_l1=0.0,
  lambda_l2=0.0
)

チューニングとは(まとめ)

  1. 使える学習データを作る。目的変数に影響を与えている説明変数を追求する。
  2. 過学習を防ぐためにシンプルな決定木を作る。
  3. 予測精度を上げるために複雑な決定木を作る。

これらをええ塩梅に調整するのが腕の見せ所。

チューニングは、この記事だけじゃなくてLightGBMの技術に特化したサイトとかも参考にしてください。

以上、「PC-KEIBA Database」が皆様のお役に立てれば幸いでございます。