Prédisez les courses de chevaux avec l'apprentissage automatique et visez un taux de récupération de 100%.
En utilisant toutes les données de résultats de course 2019 obtenues dans Article précédent, nous prédisons les chevaux qui seront dans le top 3 de LightGBM.
Tout d'abord, le prétraitement
import datetime
def preprocessing(results):
df = results.copy()
#Supprimer les éléments contenant des chaînes de caractères non numériques dans l'ordre d'arrivée
df = df[~(df["Ordre d'arrivée"].astype(str).str.contains("\D"))]
#L'utilisation de barres obliques inverses dans qiita est boguée, donc je l'ai mise en majuscule.
df["Ordre d'arrivée"] = df["Ordre d'arrivée"].astype(int)
#Diviser l'âge sexuel en sexe et âge
df["sexe"] = df["sexe齢"].map(lambda x: str(x)[0])
df["âge"] = df["Âge sexuel"].map(lambda x: str(x)[1:]).astype(int)
#Divisez le poids du cheval en poids et changement de poids
df["poids"] = df["馬poids"].str.split("(", expand=True)[0].astype(int)
df["Changement de poids"] = df["Poids du cheval"].str.split("(", expand=True)[1].str[:-1].astype(int)
#Données internationales,Convertir en flottant
df["Gagner"] = df["Gagner"].astype(float)
#Supprimer les colonnes inutiles
df.drop(["temps", "Différence", "Entraîneur", "Âge sexuel", "Poids du cheval"], axis=1, inplace=True)
df["date"] = pd.to_datetime(df["date"], format="%Y année%m mois%jour j")
return df
results_p = preprocessing(results)
Je veux le diviser en données d'entraînement et données de test, mais train_test_split ne peut pas être utilisé dans ce cas car les données d'entraînement doivent être plus anciennes que les données de test. Par conséquent, nous allons créer une fonction qui sépare les données d'entraînement et les données de test dans l'ordre chronologique à l'aide de la colonne appelée'date 'qui est maintenant de type datetime.
def split_data(df, test_size=0.3):
sorted_id_list = df.sort_values("date").index.unique()
train_id_list = sorted_id_list[: round(len(sorted_id_list) * (1 - test_size))]
test_id_list = sorted_id_list[round(len(sorted_id_list) * (1 - test_size)) :]
train = df.loc[train_id_list].drop(['date'], axis=1)
test = df.loc[test_id_list].drop(['date'], axis=1)
return train, test
La variable catégorielle est transformée en une variable factice, mais le nom du cheval a trop de catégories, il est donc omis cette fois.
results_p.drop(["Nom du cheval"], axis=1, inplace=True)
results_d = pd.get_dummies(results_p)
Si l'ordre d'arrivée est à moins de 3, étiquetez-le comme 1, sinon étiquetez-le comme 0 et traitez-le comme une variable objective.
results_d["rank"] = results_d["Ordre d'arrivée"].map(lambda x: 1 if x < 4 else 0)
results_d.drop(['Ordre d'arrivée'], axis=1, inplace=True)
À l'aide de la fonction split_data créée, divisez-la en données d'entraînement et données de test et entraînez-les avec LightGBM.
import lightgbm as lgb
train, test = split_data(results_d, 0.3)
X_train = train.drop(["rank"], axis=1)
y_train = train["rank"]
X_test = test.drop(["rank"], axis=1)
y_test = test["rank"]
params = {
"num_leaves": 4,
"n_estimators": 80,
"class_weight": "balanced",
"random_state": 100,
}
lgb_clf = lgb.LGBMClassifier(**params)
lgb_clf.fit(X_train.values, y_train.values)
Évaluer par score AUC.
y_pred_train = lgb_clf.predict_proba(X_train)[:, 1]
y_pred = lgb_clf.predict_proba(X_test)[:, 1]
print(roc_auc_score(y_train, y_pred_train))
print(roc_auc_score(y_test, y_pred))
Le résultat est, Données d'entraînement: 0,819 Données de test: 0.812 était. Je pense que c'est un bon score pour le fait que je n'ai pas encore fait de fonctionnalités. En regardant l'importance des quantités de caractéristiques,
importances = pd.DataFrame(
{"features": X_train.columns, "importance": lgb_clf.feature_importances_}
)
importances.sort_values("importance", ascending=False)[:20]
En regardant cela, cela dépend presque entièrement des données de cotes gagnantes, c'est-à-dire que c'est devenu un modèle pour parier sur des cotes faibles </ font>, alors créez des fonctionnalités, etc. Je veux l'améliorer.
Nous avons une explication détaillée dans la vidéo! Analyse des données / apprentissage automatique à partir de la prédiction des courses de chevaux
Recommended Posts