4
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【第6回】Python で競馬予想してみる  ~ LightGBM :馬券の回収率 ~

Last updated at Posted at 2020-12-10

前回、ロジスティック回帰に見切りをつけて LightGBM で学習モデルを作ってみた。
競馬予想で重要なのは、モデルの精度よりも馬券の回収率が目的になるので、とりあえず馬券の回収率を計算できるコードを追加してみるのだ

前回:【第5回】Python で競馬予想してみる  ~ LightGBM ~

ベースとなるモデル

前回(【第5回】Python で競馬予想してみる  ~ LightGBM ~)作成したモデルをそのまま使用
コードが汚くなってきたのとデータフレームを作り過ぎてしまったので、関数化したほうが便利なのかなと思いつつコードを整理して、再学習

### AUC
前回と変わらず(あたりまえなのだ)0.770くらい

Out
train  roc_auc_score = 0.801985175031238
eval  roc_auc_score = 0.7701583550634967

### ROC曲線
きれいな曲線描いてます(良い悪いは別として)
image.png

回収率の計算方法

LightBGM に学習させる前に、X_train X_test のデータフレームから 回収率に必要そうな 単勝オッズ, 複勝配当, 人気, 確定着順, 3着以内 のデータの入ったデータフレームを作成しておいた。
下の df_rslt

build.ipynb
# データの分割を行う(学習用データ 0.8 評価用データ 0.2) stratify:層化抽出
X_train, X_eval, y_train, y_eval = train_test_split(dataX, dataY, test_size=0.2, stratify=dataY)

# 学習データの修正
X_train = X_train.drop(['レースID(新)', '単勝オッズ', '複勝配当', '人気', '確定着順', '3着以内'], axis=1) # 不要なデータを削除

# 検証データの修正
df_rslt = X_eval[['レースID(新)', '単勝オッズ', '複勝配当', '人気', '確定着順', '3着以内']]
X_eval = X_eval.drop(['レースID(新)', '単勝オッズ', '複勝配当', '人気', '確定着順', '3着以内'], axis=1) # 不要なデータを削除

スクリーンショット 2020-12-10 14.47.07.png

###回収率の計算方法
このデータフレームに、y_pred_proba, y_pred を追加
y_pred は、y_pred_proba の数値を 0.5 を境に 1と 0に変換(今回は使わなかったが。。)
そして、y_pred_probaの値を 0 から 1 までスライドさせながら単勝と複勝の回収率を計算した。

build.ipynb
y_pred_proba = model.predict(X_eval)
y_pred = np.where(y_pred_proba < 0.5, 0, 1) # 1と0に変換

df_rslt['予測'] = y_pred_proba
df_rslt['予測1'] = y_pred
df_rslt.drop(['予測','予測1','馬券期待値', '馬券期待値2'], axis=1) 
build.ipynb
# 単勝と複勝の回収率を、y_pred_proba の閾値を変化させながら計算
gain_tan = {}
gain_fuku = {}
n_sample = 100
for i in tqdm(range(n_sample)):
    threshold = i / n_sample
    
    gain_tan[threshold] = df_rslt[(df_rslt['予測'] > threshold)&(df_rslt['確定着順'] == 1)]['単勝オッズ'].sum()/len(df_rslt[df_rslt['予測'] > threshold])
    gain_fuku[threshold] = df_rslt[df_rslt['予測'] > threshold]['複勝配当'].sum()/len(df_rslt[df_rslt['予測'] > threshold])

####単勝の回収率
image.png

####複勝の回収率
image.png

y_pred_proba の閾値 0.8を超えるとグラフがばらつくので、サンプル数を確認すると 20万件中の 600件
かなり少ないのだ
スクリーンショット 2020-12-10 15.40.06.png

今回、回収率の計算ができるモデルも完成。今回はここまでなのだ:wave:
コードを書きながら、馬券の買い方次第でもどうにかなりそうな気がしてきたが。。

次回は特徴量の整理して、回収率の変化を見るのだ


参考:【機械学習】競馬予想AIの回収率を上げた意外な方法とは?〜前編〜【Python】


4
8
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
4
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?