この記事を読む前に「LightGBMによるAI競馬予想(準備編)」の記事を先に読んでください。
二値分類(binary)
「二値分類」は目的変数を0か1の二値に分類にする方法です。
ここに公開するPythonのソースコードは「正解率」の評価指標と「特徴量重要度」の可視化を実装しています。学習データを作るSQLで目的変数の項目名を「target」にすれば、オリジナルの学習データで分析する場合でもそのまま使えます。
ソースコードは学習用と予測用に分けてます。
欠損値(null)は、SQLで何らかの値(0など)に変換しておくことを前提にしてます。欠損値についてPythonでは何もしてないってことです。
学習用ソースコード
以下が「二値分類」で学習するPythonのソースコードです。
このページの最後の、有料会員限定のダウンロードリンクからもファイルをダウンロードできます。
import pandas as pd
import numpy as np
import lightgbm as lgb
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
# CSVファイル読み込み
in_file_name = 'binary_train.csv'
df = pd.read_csv(in_file_name, encoding='SHIFT_JIS')
# 説明変数(x)と目的変数(y)を設定
target = 'target'
x = df.drop(target, axis=1).values # y以外の特徴量
y = df[target].values
# 説明変数の項目名を取得
feature = list(df.drop(target, axis=1).columns)
# 訓練データとテストデータを分割
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=0)
# LightGBM パラメータ
params = {
'objective':'binary', # 目的 : 二値分類
'metric':'binary_error' # 評価指標 : 不正解率(1 - 正解率)
}
# モデルの学習
train_set = lgb.Dataset(x_train, y_train)
valid_sets = lgb.Dataset(x_test, y_test, reference=train_set)
model = lgb.train(params, train_set=train_set, valid_sets=valid_sets)
# モデルをファイルに保存
model.save_model('binary_model.txt')
# テストデータの予測
y_prob = model.predict(x_test)
y_pred = np.where(y_prob < 0.5, 0, 1)
# 評価指標
acc = accuracy_score(y_test, y_pred)
print('正解率 = ', acc)
# 特徴量重要度
importance = np.array(model.feature_importance())
df = pd.DataFrame({'feature':feature, 'importance':importance})
df = df.sort_values('importance', ascending=True)
n = len(df) # 説明変数の項目数を取得
values = df['importance'].values
plt.barh(range(n), values)
values = df['feature'].values
plt.yticks(np.arange(n), values) # x, y軸の設定
plt.show()
学習データを作る
説明変数は他の分析方法と共通にしました。内容は「LightGBMによるAI競馬予想(準備編)」の記事を見てください。学習データのファイル名は「binary_train.csv」とします。
今回のサンプルでは目的変数の「確定着順」を、次のように分類してみます。
- 5着以内→1
- 上記以外→0
このページの最後に、サンプルのSQLを有料会員に公開しています。ユーザーがカスタマイズして利用することも可能ですし、SQLを学習したい方の参考にもなります。
LightGBMに学習させる
今回の例では、Cドライブの直下に「pckeiba」というフォルダを作って、
- 学習データ(*.csv)
- 学習用ソースコード(*.py)
2つのファイルを置きます。こういう状態です。

そしてコマンドプロンプトを起動して、次の2つのコマンドを「1行ずつ」実行してください。
cd C:\pckeiba
python binary_train.py
LightGBMが学習を開始します。処理が終わると評価指標を表示します。
モデルを評価する
今回のサンプルでは評価指標として「正解率」を表示します。

正解率という評価指標は、名前のまんまで100%に近いほど良い数字です。今回のモデルでは正解率 = 71%という結果になりました。これを競馬場や距離などレースの条件ごとに分析したら、もっと精度の高いモデルに出来るかもしれません。二値分類の評価指標は、正解率の他にもあるのでググって研究してください。
このモデルを「binary_model.txt」に保存しています。このファイルは予想するとき使います。

特徴量重要度
参考として「特徴量重要度」の可視化を実装してます。特徴量重要度をざっくり言うと、重要度が高い説明変数ほど、目的変数である確定着順に対して影響力が強いということです。

これを見ながら説明変数を取捨選択したり、LightGBMパラメータをチューニングしたりします。今回のモデルでは「1走前 タイム差」が最も影響力が強いと判断されました。「JRA-VANタイム型データマイニング」が4位で意外と頑張ってます。
あくまで今回のモデルによる結果だから、すべての競馬においてこの結果が当てはまると言うわけじゃないです。
いろいろ試してモデルの精度に納得したら、これを使って明日のレースを予想させます。
予測用ソースコード
以下が「二値分類」で予想するPythonのソースコードです。
このページの最後の、有料会員限定のダウンロードリンクからもファイルをダウンロードできます。
import pandas as pd
import numpy as np
import lightgbm as lgb
import os
import sys
# 出馬表ファイル読み込み
fname = sys.argv[1]
x_test = np.loadtxt(fname, delimiter=',')
# モデル読み込み
bst = lgb.Booster(model_file='binary_model.txt')
# データの予測
y_prob = bst.predict(x_test, num_iteration=bst.best_iteration)
y_pred = np.where(y_prob < 0.5, 0, 1)
# 拡張子を除いたファイル名を取得
fname = os.path.splitext(os.path.basename(fname))[0]
# 予測値を出力
df = pd.DataFrame({'予測値':y_pred})
df.to_csv(fname + '_pred.csv', encoding='SHIFT_JIS', index=False)
# 予測確率を出力
df = pd.DataFrame({'0の確率':1 - y_prob, '1の確率':y_prob})
df.to_csv(fname + '_prob.csv', encoding='SHIFT_JIS', index=False)
出馬表データを作る
予測させる出馬表データは、学習データ作成のSQLと出力後のファイルを少し改造すれば作れます。学習データとの違いは次の2つです。
- SQLで目的変数「確定着順」の項目を消す。
- SQLで予想するレースでレコードの抽出条件を設定する。
出馬表データのファイル名は何でも良いですが、ここでは「yyyymmddjjrr.csv」とします。
今回のサンプルでは「2021年 天皇賞(秋)」を予想してみます。
このページの最後に、サンプルのSQLを有料会員に公開しています。ユーザーがカスタマイズして利用することも可能ですし、SQLを学習したい方の参考にもなります。
予測(予想)させる
先ほどと同じ「pckeiba」というフォルダに、
- 出馬表(*.csv)
- モデル(*.txt)
- 予測用ソースコード(*.py)
3つのファイルを置きます。こういう状態です。

そしてコマンドプロンプトを起動して、次のコマンドを実行してください。予測用ソースコードの後に、半角スペースと出馬表のファイル名です。
python binary_pred.py 202110310511.csv
処理が終わると2つのファイルが出力されます。「予測値」と「確率」のファイルです。
- yyyymmddjjrr_pred.csv (予測値)
- yyyymmddjjrr_prob.csv (確率)

このファイルは数値のデータ以外に何も無いので分かりにくいですが、出馬表データと同じ馬番の昇順で出力されます。これで馬券を買うときは、馬番と馬名だけの出馬表をSQLでCSVに出力して、そこへ貼り付けて確率で並べ替えるとかして使えば良いでしょう。例えばこんな感じです。

レース結果は5着以内の確率上位3頭で3連複を的中してます。

「二値分類」による競馬予想の話は以上です。
今回のサンプルはあくまで1つの「サンプル」でしかありません。完成させるのはユーザーのあなたです。