0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

LightGBMによるAI競艇予想(多クラス分類)

Last updated at Posted at 2024-05-31

多クラス分類(multiclass)

この記事を読む前に「LightGBMによるAI競艇予想(準備編)」の記事を先に読んでください。その中には、機械学習の基礎知識や、学習データで使う説明変数の内容など、他のデータ分析方法と共通する説明が含まれています。

「多クラス分類」は目的変数を多クラスに分類する方法です。「二値分類」の三値以上版みたいなイメージ。

ここに公開するPythonのソースコードは「正解率・適合率・再現率」の評価指標と「特徴量重要度」の可視化を実装しています。学習データを作るSQLで目的変数の項目名を「target」にすれば、オリジナルの学習データで分析する場合でもそのまま使えます。

目的変数が3値以外の場合、LightGBMハイパーパラメータ(num_class)の修正が必要です。

ソースコードは学習用と予測用に分けてます。

欠損値(null)は、SQLで何らかの値(0など)に変換しておくことを前提にしてます。欠損値についてPythonでは何もしてないってことです。

学習用ソースコード

以下が「多クラス分類」で学習するPythonのソースコードです。この学習用ソースコードのファイル名は「multiclass_train.py」とします。

PythonのソースコードはUTF-8で保存する必要があります。

multiclass_train.py
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
from sklearn.metrics import precision_score
from sklearn.metrics import recall_score

# CSVファイル読み込み
in_file_name = 'multiclass_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':'multiclass', # 目的 : 多クラス分類
  'metric':{'multi_error'}, # 評価指標 : 正答率
  'num_class':3             # クラス数 : 3
}

# モデルの学習
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('multiclass_model.txt')

# テストデータの予測
y_prob = model.predict(x_test)
y_pred = np.argmax(y_prob, axis=1)

# 評価指標
accuracy = accuracy_score(y_test, y_pred)
precision = precision_score(y_test, y_pred, average=None)
recall = recall_score(y_test, y_pred, average=None)
print('正解率 = ', accuracy)
print('適合率 = ', precision)
print('再現率 = ', recall)

# 特徴量重要度
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.savefig('multiclass_train.png', bbox_inches='tight', dpi=500)
plt.show()

学習データを作る

説明変数は他の分析方法と共通にしました。内容は「LightGBMによるAI競艇予想(準備編)」の記事を見てください。学習データのファイル名は「multiclass_train.csv」とします。

今回のサンプルでは目的変数の「着順」を、次のように分類してみます。

  • 1着→2
  • 2〜3着→1
  • 上記以外→0

PC-KYOTEIのWebサイトで、サンプルのSQLを公開しています。ユーザーがカスタマイズして利用することも可能ですし、SQLを学習したい方の参考にもなります。
https://pc-kyotei.com/multiclass/

LightGBMに学習させる

今回の例では、Cドライブの直下に「pckyotei」というフォルダを作って、

  • 学習データ(multiclass_train.csv)
  • 学習用ソースコード(multiclass_train.py)

2つのファイルを置きます。こういう状態です。

画像

そして、コマンドプロンプトを起動し、次の2つのコマンドを「1行ずつ」実行してください。

cd C:\pckyotei
python multiclass_train.py

LightGBMが学習を開始します。処理が終わると評価指標を表示します。

モデルを評価する

今回のサンプルでは、次の3つの評価指標を表示します。

  1. 「正解率」= 全てのサンプルを正解した割合
  2. 「適合率」= 1と予測したサンプルのうち、実際に1であった割合
  3. 「再現率」= 実際に1であるサンプルのうち、1と予測した割合

画像

適合率と再現率の評価指標は、目的変数=0,1,2の順で表示されます。

今回のモデルでは、このような結果になりました。これを競艇場ごとに分析したら、もっと精度の高いモデルに出来るかもしれません。多クラス分類の評価指標は、この他にもあるのでググって研究してください。

このモデルを「multiclass_model.txt」に保存しています。このファイルは予想するとき使います。

画像

特徴量重要度

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

画像

これを見ながら説明変数を取捨選択したり、LightGBMパラメータをチューニングしたりします。

今回のモデルによる結果であるため、この結果がすべてのレースに当てはまると言うわけじゃないです。

いろいろ試してモデルの精度に納得したら、これを使って明日のレースを予想させます。

予測用ソースコード

以下が「多クラス分類」で予想するPythonのソースコードです。

PythonのソースコードはUTF-8で保存する必要があります。

multiclass_pred.py
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=',', skiprows=1)

# モデル読み込み
bst = lgb.Booster(model_file='multiclass_model.txt')

# テストデータの予測
y_prob = bst.predict(x_test, num_iteration=bst.best_iteration)
y_pred = np.argmax(y_prob, axis=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の確率':y_prob[:,0], '1の確率':y_prob[:,1], '2の確率':y_prob[:,2]})
df.to_csv(fname + '_prob.csv', encoding='SHIFT_JIS', index=False)

出走表データを作る

予測させる出走表データは、学習データ作成のSQLと出力後のファイルを少し改造すれば作れます。学習データとの違いは次の2つです。

  1. SQLで目的変数「target」の項目を消す。
  2. SQLで予想するレースでレコードの抽出条件を設定する。

出走表データのファイル名は何でも良いですが、ここでは「レースID(※1).csv」とします。
今回のサンプルでは「2022/10/25(火)常滑12R 第69回ボートレースダービー(SG)」を予想してみます。

(※1)レースID
年月日場R
yyyymmddjjrr(12桁)

PC-KYOTEIのWebサイトで、サンプルのSQLを公開しています。ユーザーがカスタマイズして利用することも可能ですし、SQLを学習したい方の参考にもなります。
https://pc-kyotei.com/multiclass/

予測(予想)させる

先ほどと同じ「pckyotei」というフォルダに、

  • 出走表(レースID(※1).csv)
  • モデル(multiclass_model.txt)
  • 予測用ソースコード(multiclass_pred.py)

3つのファイルを置きます。こういう状態です。

画像

そして、コマンドプロンプトを起動し、次の2つのコマンドを「1行ずつ」実行してください。2番目は、予測用ソースコードの後に、半角スペースと出馬表のファイル名です。

cd C:\pckyotei
python multiclass_pred.py 202210250812.csv

処理が終わると2つのファイルが出力されます。「予測値」と「確率」のファイルです。

  • レースID(※1)_pred.csv (予測値)
  • レースID(※1)_prob.csv (確率)

画像

このファイルには数値データしか含まれていないので、分かりにくいかもしれませんが、出走表データと同じ艇番の昇順で出力されます。舟券を買うときは、SQLで艇番とレーサー氏名だけの出走表をCSVに出力して、そこへ貼り付けて確率で並べ替えると便利です。例えば、こんな感じです。

画像

「2の確率」上位4艇で、レース結果は3連複の払戻金が470円となりました。

画像

「多クラス分類」による競艇予想AIの話は以上です。

今回のサンプルはあくまで1つの「サンプル」でしかありません。完成させるのはユーザーのあなたです。

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?