1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Kerasで実現するディープラーニングによるAI競馬予想(二値分類)

Posted at

二値分類(binary)

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

「二値分類」は目的変数を0か1の二値に分類する方法です。

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

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

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

学習用ソースコード

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

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

dl_binary_train.py
import joblib
import numpy as np
import pandas as pd
from keras.layers import Dense, Dropout
from keras.models import Sequential
from sklearn.metrics import classification_report, roc_auc_score
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler

# CSVファイル読み込み
in_file_name = 'dl_binary_train.csv'
df = pd.read_csv(in_file_name, encoding='SHIFT_JIS')

# 説明変数(x)と目的変数(y)を設定
target = 'target'
x = df.drop(target, axis=1)
y = df[target]

# 訓練データとテストデータを分割
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=42)

# 特徴量の標準化
scaler = StandardScaler()
x_train = scaler.fit_transform(x_train)
x_test = scaler.transform(x_test)

# スケーラーを保存
joblib.dump(scaler, 'binary_scaler.joblib')

# モデルの構築
model = Sequential()
model.add(Dense(128, input_dim=x_train.shape[1], activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(64, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(1, activation='sigmoid'))

# モデルのコンパイル
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])

# モデルの学習
model.fit(x_train, y_train, epochs=50, batch_size=32, validation_data=(x_test, y_test))

# モデルをファイルに保存
model.save('binary_model.h5')

# 評価指標
loss, accuracy = model.evaluate(x_test, y_test)
# 正解率、適合率、再現率、F1
y_probs = model.predict(x_test)
y_pred = (y_probs > 0.5).astype(int)
# AUC
auc = roc_auc_score(y_test, y_probs)
print(f'正解率 = {accuracy:.4f}')
print(f'AUC    = {auc:.4f}')
print(classification_report(y_test, y_pred))

学習データを作る

説明変数は他の分析方法と共通にしました。内容は「Kerasで実現するディープラーニングによるAI競馬予想(準備編)」の記事を見てください。学習データのファイル名は「dl_binary_train.csv」とします。

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

  • 3着以内→1
  • 上記以外→0

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

Kerasに学習させる

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

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

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

画像

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

cd C:\pckeiba
python dl_binary_train.py

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

モデルを評価する

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

  1. 「正解率」= 全てのサンプルを正解した割合
  2. 「適合率」= 1と予測したサンプルのうち、実際に1であった割合
  3. 「再現率」= 実際に1であるサンプルのうち、1と予測した割合
  4. 「F値」= 適合率と再現率の調和平均を表す指標
  5. 「AUC」= ROC曲線の下の面積を示し、1に近いほど分類精度が高い

画像

正解率がやたら高いですが、これは実際の0が圧倒的に多いため、その影響が大きくなっています。そのため、正解率だけで判断するのは誤りです。今回のデータ分析では、適合率と再現率を主な指標として用いることが適切だと考えます。

これを競馬場や距離などレースの条件ごとに分析したら、もっと精度の高いモデルに出来るかもしれません。二値分類の評価指標は、この他にもあるのでググって研究してください。

このモデルを「binary_model.h5」に、スケーラーを「binary_scaler.joblib」に保存しています。このファイルは予想するとき使います。

画像

これを使って明日のレースを予想させます。

予測用ソースコード

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

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

dl_binary_pred.py
import joblib
import numpy as np
import pandas as pd
import os
import sys
from keras.models import load_model

# 出馬表ファイル読み込み
fname = sys.argv[1]
x_test = np.loadtxt(fname, delimiter=',', skiprows=1)

# 1行だけの場合でも2次元配列に変換
if x_test.ndim == 1:
    x_test = x_test.reshape(1, -1)

# モデル読み込み
model = load_model('binary_model.h5')
scaler = joblib.load('binary_scaler.joblib')

# 特徴量の標準化
scaled = scaler.transform(x_test)

# データの予測
y_probs = model.predict(scaled)
y_pred = (y_probs > 0.5).astype(int)

# 拡張子を除いたファイル名を取得
fname = os.path.splitext(os.path.basename(fname))[0]

# 予測値を出力
df = pd.DataFrame(y_pred, columns=['予測値'])
df.to_csv(fname + '_pred.csv', encoding='SHIFT_JIS', index=False)

# 予測確率を出力
df = pd.DataFrame(y_probs, columns=['確率'])
df.to_csv(fname + '_prob.csv', encoding='SHIFT_JIS', index=False)

出馬表データを作る

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

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

出馬表データのファイル名は何でも良いですが、ここでは「レースID(※1).csv」とします。
今回のサンプルでは「2023/02/04(土)小倉12R」を予想してみます。

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

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

予測(予想)させる

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

  • 出馬表(レースID(※1).csv)
  • モデル(binary_model.h5)
  • スケーラー(binary_scaler.joblib)
  • 予測用ソースコード(dl_binary_pred.py)

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

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

cd C:\pckeiba
python dl_binary_pred.py 202302041012.csv

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

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

画像

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

画像

「二値分類」による競馬予想AIの話は以上です。

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

1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?