Prédisez les courses de chevaux avec l'apprentissage automatique et visez un taux de récupération de 100%
Cet article est une continuation de l'article suivant.
Cette fois, je vais essayer de simuler combien je peux gagner si je parie réellement sur des doubles victoires en utilisant ce modèle.
Commencez par gratter le tableau de remboursement. Si vous grattez normalement, double win et wide ne seront pas séparés comme indiqué ci-dessous, donc convertissez la balise de saut de ligne </ font> en une chaîne de caractères.
f = urlopen(url)
html = f.read()
html = html.replace(b'<br />', b'br')
Comme dans l'article précédent, si vous incluez une liste de race_id, créez et exécutez une fonction qui gratte les données de remboursement et les convertit en type DataFrame.
import pandas as pd
import time
from tqdm.notebook import tqdm
from urllib.request import urlopen
def scrape_return_tables(race_id_list, pre_return_tables={}):
return_tables = pre_return_tables
for race_id in tqdm(race_id_list):
if race_id in return_tables.keys():
continue
try:
url = "https://db.netkeiba.com/race/" + race_id
f = urlopen(url)
html = f.read()
html = html.replace(b'<br />', b'br')
dfs = pd.read_html(html)
return_tables[race_id] = pd.concat([dfs[1], dfs[2]])
time.sleep(1)
except IndexError:
continue
except:
break
return return_tables
return_tables = scrape_return_tables(race_id_list)
for key in return_tables:
return_tables[key].index = [key] * len(return_tables[key])
return_tables = pd.concat([return_tables[key] for key in return_tables])
Ensuite, créez une classe Retrun et traitez les données double win afin qu'elles puissent être utilisées.
class Return:
def __init__(self, return_tables):
self.return_tables = return_tables
@property
def fukusho(self):
fukusho = self.return_tables[self.return_tables[0]=='Double victoire'][[1,2]]
wins = fukusho[1].str.split('br', expand=True).drop([3], axis=1)
wins.columns = ['win_0', 'win_1', 'win_2']
returns = fukusho[2].str.split('br', expand=True).drop([3], axis=1)
returns.columns = ['return_0', 'return_1', 'return_2']
df = pd.concat([wins, returns], axis=1)
for column in df.columns:
df[column] = df[column].str.replace(',', '')
return df.fillna(0).astype(int)
rt = Return(return_tables)
rt.fukusho
Ensuite, insérez le LightGBM et les données de remboursement que vous venez de récupérer, puis créez une classe ModelEvaluator qui calculera le score AUC et équilibrera et évaluera le modèle.
from sklearn.metrics import roc_auc_score
class ModelEvaluator:
def __init__(self, model, return_tables):
self.model = model
self.fukusho = Return(return_tables).fukusho
def predict_proba(self, X):
return self.model.predict_proba(X)[:, 1]
def predict(self, X, threshold=0.5):
y_pred = self.predict_proba(X)
return [0 if p<threshold else 1 for p in y_pred]
def score(self, y_true, X):
return roc_auc_score(y_true, self.predict_proba(X))
def feature_importance(self, X, n_display=20):
importances = pd.DataFrame({"features": X.columns,
"importance": self.model.feature_importances_})
return importances.sort_values("importance", ascending=False)[:n_display]
def pred_table(self, X, threshold=0.5, bet_only=True):
pred_table = X.copy()[['Numéro de cheval']]
pred_table['pred'] = self.predict(X, threshold)
if bet_only:
return pred_table[pred_table['pred']==1]['Numéro de cheval']
else:
return pred_table
def calculate_return(self, X, threshold=0.5):
pred_table = self.pred_table(X, threshold)
money = -100 * len(pred_table)
df = self.fukusho.copy()
df = df.merge(pred_table, left_index=True, right_index=True, how='right')
for i in range(3):
money += df[df['win_{}'.format(i)]==df['Numéro de cheval']]['return_{}'.format(i)].sum()
return money
Quand je calcule réellement ...
me = ModelEvaluator(lgb_clf, return_tables)
gain = {}
n_samples = 100
for i in tqdm(range(n_samples)):
threshold = i / n_samples
gain[threshold] = me.calculate_return(X_test, threshold)
pd.Series(gain).plot()
Je perds vraiment, donc j'ai encore besoin de m'améliorer ...
Explication détaillée dans la vidéo ↓ Analyse de données / apprentissage automatique à partir de la prédiction des courses de chevaux
Recommended Posts