Je suis un étudiant spécialisé en systèmes d'information dans une certaine université T. Quand je regardais divers articles sur Qiita, j'ai trouvé cet article.
Concernant l'atteinte du taux de récupération de 100% dans cet article, puisque le nombre de billets de paris simulés à l'achat est faible, je ne sais pas s'il sera établi sur d'autres périodes. Le code source est également facturé, donc je ne connais pas les détails sur la façon de le faire. Cependant, j'ai pensé qu'il serait intéressant de prédire moi-même les courses de chevaux, alors je l'ai essayé avec l'intention d'étudier.
Ce sera une excellente expérience d'apprentissage car vous ferez toute la collecte de données, l'analyse et la prévision.
Il y avait un désir que ce soit de l'argent, mais les courses de chevaux semblent avoir un taux de déduction élevé, donc je ne peux pas m'attendre à grand chose. La raison principale est que cela a été un sujet brûlant récemment et que je voulais essayer l'apprentissage profond.
Une autre raison de choisir les courses de chevaux est
――Le résultat de la course est moins influencé par les spectateurs
Cela est mentionné.
Il semble bon de faire le thème des actions, mais comme le prix fluctue en fonction des décisions de nombreuses personnes, il est difficile de prévoir avec une bonne précision à moins que des informations telles que les nouvelles que les traders voient souvent ne soient incorporées. C'est vrai. De plus, de nombreux investisseurs institutionnels passent des ordres automatiquement selon l'algorithme, qui en dépendra probablement.
De ce qui précède, j'ai pensé que ce ne serait pas facile avec la technologie actuelle, alors j'ai pensé que les courses de chevaux étaient plus adaptées à l'apprentissage en profondeur.
Le nombre de chevaux qui participent aux courses de chevaux varie d'une course à l'autre, mais il semble que le nombre d'athlètes participant aux courses de bateaux soit constant. Il semble que l'apprentissage automatique sera plus facile si des données détaillées peuvent être obtenues.
"Les courses de chevaux (Keiba, anglais: courses de chevaux) sont une compétition de courses dans laquelle des chevaux sur lesquels sont montés des chevaux sont concourus, et un jeu de hasard qui prédit l'ordre d'arrivée de celui-ci" (citation: [courses de chevaux --Wikipedia](https: //) ja.wikipedia.org/wiki/horse racing)).
J'avais peu de connaissances sur les courses de chevaux jusqu'à ce que j'analyse ces données, je vais donc résumer les connaissances que je pensais nécessaires pour lire cet article.
Tout d'abord, connaissons les types de billets de paris en tant que connaissances de base. Il est normal de lire simplement une victoire simple ou une double victoire. Référence: [Type de ticket de pari: JRA pour les nouveaux utilisateurs](https://www.google.com/url?sa=t&rct=j&q½esrc=s&source=web&cd=1&ved=2ahUKEwjj9cC71eHlAhXgy4sBHXKtA0QQFjAAegQIAh jra.go.jp% 2Fkouza% 2Fbeginner% 2Fbaken% 2F & usg = AOvVaw12f8T5GSlozZG9tnRspGtC)
Pour les autres termes, reportez-vous à ce qui suit
--Odds: Multiplicateur qui montre combien de fois l'argent que vous gagnez est le nombre d'argent que vous dépensez ――Rise: La fin de la course et l'entraînement --Umaban: un numéro attribué uniquement à un cheval courant
Référence: Horse Racing Glossary JRA
Je ne suis pas si familier avec cela, alors faites-le moi savoir si vous faites une erreur ...
La connaissance du domaine est considérée comme importante dans l'apprentissage automatique, il sera donc nécessaire de se familiariser avec les courses de chevaux afin d'améliorer la précision des prévisions.
Même si vous faites des prédictions sur les courses de chevaux, il y a beaucoup de choses à penser et à faire. La procédure peut être grossièrement divisée comme suit.
Le premier enjeu majeur pour ceux qui veulent prédire les courses de chevaux est la collecte et la mise en forme des données. Dans des compétitions comme Kaggle, c'est assez facile car le jeu de données est donné depuis le début, mais cette fois, nous devons commencer par collecter les données.
De plus, il est difficile de créer un modèle car diverses méthodes peuvent être envisagées. De nos jours, vous pouvez facilement utiliser l'amplification de gradient, l'apprentissage en profondeur, etc. dans la bibliothèque, mais vous devrez essayer différentes méthodes pour améliorer la précision de la prédiction.
Des données d'utilisation
--Données d'apprentissage: janvier 2008-23 juillet 2017 --Données de vérification: 23 juillet 2017-novembre 2019
résultat
J'ai fait un modèle avec une précision plus élevée que moi en tant que débutant en courses de chevaux
L'apprentissage automatique n'est pas possible soudainement même s'il n'y a pas de données. Faisons l'exploration et le grattage.
Tout d'abord, récupérez les résultats des courses et les informations sur les chevaux du site cible.
Les données obtenues ici doivent être aussi proches que possible des données brutes, et les données seront formatées ultérieurement pour la formation.
Il s'agit du plus grand site d'information sur les courses de chevaux au Japon. Des données de course passées aux informations sur le pedigree du cheval, vous pouvez obtenir gratuitement des données assez détaillées.
Il semble que des données plus détaillées puissent être obtenues en devenant membre payant. Il est efficace lorsque vous souhaitez améliorer la précision du modèle.
Cette fois, nous avons décidé de collecter des données en se concentrant sur les résultats de la course à l'hippodrome central, qui dispose d'une grande quantité d'informations et d'un système unifié.
Comme il y a beaucoup de données, vous pouvez créer un bon modèle en collectant et en utilisant diverses données. Cependant, il est assez difficile de collecter des informations et des données généalogiques telles que les propriétaires et les formateurs, j'ai donc décidé de ne pas le faire cette fois. Il semble que la précision des prévisions s'améliorera si vous ajoutez des données ici.
Depuis l 'Écran de recherche détaillée de la course sur le site, utilisez Selenium pour obtenir toutes les URL des résultats de la course.
La raison de ne pas utiliser les requêtes et Beautiful Soup, qui sont souvent utilisés lors de l'exploration et du scraping en Python, est que l'URL de recherche et l'URL du résultat de la recherche sont [https://db.netkeiba.com/?pid=race_search_detail](https :: //db.netkeiba.com/?pid=race_search_detail) n'a pas changé.
Si l'écran est généré dynamiquement par JavaScript ou PHP, vous ne pouvez pas obtenir les données souhaitées en téléchargeant simplement le html.
Avec Selenium, les transitions d'écran peuvent être effectuées par des opérations réelles du navigateur, de sorte que l'exploration Web peut être effectuée même sur des sites où l'affichage change en cliquant sur un bouton ou des sites nécessitant une connexion. (Veuillez noter que de nombreux sites nécessitant une connexion interdisent l'exploration en raison d'accords d'adhésion, etc.).
import time
from selenium import webdriver
from selenium.webdriver.support.ui import Select,WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.chrome.options import Options
options = Options()
options.add_argument('--headless') #En mode sans tête
driver = webdriver.Chrome(chrome_options=options)
wait = WebDriverWait(driver,10)
Remplissez les champs obligatoires du formulaire. Après l'envoi, attendez que les résultats de la recherche s'affichent.
URL = "https://db.netkeiba.com/?pid=race_search_detail"
driver.get(URL)
time.sleep(1)
wait.until(EC.presence_of_all_elements_located)
#Recherche par mois
year = 2019
month = 1
#Sélectionnez une période
start_year_element = driver.find_element_by_name('start_year')
start_year_select = Select(start_year_element)
start_year_select.select_by_value(str(year))
start_mon_element = driver.find_element_by_name('start_mon')
start_mon_select = Select(start_mon_element)
start_mon_select.select_by_value(str(month))
end_year_element = driver.find_element_by_name('end_year')
end_year_select = Select(end_year_element)
end_year_select.select_by_value(str(year))
end_mon_element = driver.find_element_by_name('end_mon')
end_mon_select = Select(end_mon_element)
end_mon_select.select_by_value(str(month))
#Découvrez l'hippodrome central
for i in range(1,11):
terms = driver.find_element_by_id("check_Jyo_"+ str(i).zfill(2))
terms.click()
#Sélectionnez le numéro à afficher(20,50,De 100 au maximum 100)
list_element = driver.find_element_by_name('list')
list_select = Select(list_element)
list_select.select_by_value("100")
#Soumettre le formulaire
frm = driver.find_element_by_css_selector("#db_search_detail_form > form")
frm.submit()
time.sleep(5)
wait.until(EC.presence_of_all_elements_located)
Par souci de simplicité, j'essaie d'obtenir l'URL de janvier 2019. Si vous souhaitez une plus large gamme de données, effectuez l'une des opérations suivantes:
--Ne remplissez pas le formulaire année / mois
(Dans le code github, nous essayons de collecter des données de course qui n'ont pas été acquises depuis 2008.)
Si vous ne remplissez pas la sélection de l'hippodrome, les données sur les courses organisées à l'étranger seront également incluses. Vérifions correctement 10 hippodromes centraux.
J'ai décidé de ne pas utiliser les données autres que l'hippodrome central cette fois car il peut y avoir peu de chevaux en course ou les données peuvent être incomplètes.
Cliquez sur le bouton dans Selenium et enregistrez les URL affichées pour chaque 100 éléments.
with open(str(year)+"-"+str(month)+".txt", mode='w') as f:
while True:
time.sleep(5)
wait.until(EC.presence_of_all_elements_located)
all_rows = driver.find_element_by_class_name('race_table_01').find_elements_by_tag_name("tr")
for row in range(1, len(all_rows)):
race_href=all_rows[row].find_elements_by_tag_name("td")[4].find_element_by_tag_name("a").get_attribute("href")
f.write(race_href+"\n")
try:
target = driver.find_elements_by_link_text("Suivant")[0]
driver.execute_script("arguments[0].click();", target) #Traitement des clics avec javascript
except IndexError:
break
Ouvrez le fichier et écrivez l'URL obtenue ligne par ligne. L'URL de la course est dans la 5ème colonne du tableau, donc en Python où les éléments du tableau commencent à 0, sélectionnez quelque chose comme find_elements_by_tag_name (" td ") [4]
.
La pagination est effectuée dans une boucle while. J'utilise try
pour attraper l'exception car je ne peux pas cliquer sur la dernière page.
Le driver.execute_script (" arguments [0] .click (); ", target)
fait partie de l'essai, mais si vous en faites un simple target.click ()
, vous obtiendrez une ʻElementClickInterceptedException` en mode sans tête. Cela s'est produit.
Apparemment, il a été reconnu que les éléments se chevauchaient et je ne pouvais pas bien cliquer dessus. Il y avait une solution dans ici, mais j'ai pu le faire bien en cliquant avec JavaScript comme ci-dessus.
Le html que j'ai obtenu plus tôt ne semble pas utiliser beaucoup PHP ou JavaScript pour afficher la page, je vais donc enfin utiliser les requêtes ici. Sur la base des informations de l'URL ci-dessus, j'obtiens le html et je l'enregistre, mais cela prend quelques secondes pour obtenir chaque page, donc cela prend beaucoup de temps.
import os
import requests
save_dir = "html"+"/"+str(year)+"/"+str(month)
if not os.path.isdir(save_dir):
os.makedirs(save_dir)
with open(str(year)+"-"+str(month)+".txt", "r") as f:
urls = f.read().splitlines()
for url in urls:
list = url.split("/")
race_id = list[-2]
save_file_path = save_dir+"/"+race_id+'.html'
response = requests.get(url)
response.encoding = response.apparent_encoding
html = response.text
time.sleep(5)
with open(save_file_path, 'w') as file:
file.write(html)
En raison du code de caractère, si vous l'obtenez avec obéissance, il peut être déformé. Je l'ai fait avec response.encoding = response.apparent_encoding
et cela a fonctionné.
Référence: Corriger les caractères brouillés lors du traitement du japonais dans les requêtes
Détails de la course ・ Les informations sur chaque coureur sont stockées dans csv. J'ai décidé de créer un csv avec le format suivant.
Détails de la course
ID de race ――Combien de tours
Titre de la course --A propos du cours
la météo
État du sol --Date et l'heure
Stade ――Le numéro de cheval et le numéro de cadre du 1er au 3ème --Odds de chaque billet de pari
Détails du cheval
ID de race --Classement
ID de cheval -Numéro de cheval --Numéro de cadre
Âge du sexe -Poids de charge
Différence de poids et de poids --Temps --Différence
Temps de montée --Chances --Populaire
Il y a d'autres informations qui peuvent être obtenues. Il semble que les membres payants peuvent également obtenir ce qu'on appelle un indice de vitesse.
import numpy as np
import pandas as pd
from bs4 import BeautifulSoup
CSV_DIR = "csv"
if not os.path.isdir(CSV_DIR):
os.makedirs(CSV_DIR)
save_race_csv = CSV_DIR+"/race-"+str(year)+"-"+str(month)+".csv"
horse_race_csv = CSV_DIR+"/horse-"+str(year)+"-"+str(month)+".csv"
# race_data_columns, horse_data_Les colonnes seront longues, donc omettez
race_df = pd.DataFrame(columns=race_data_columns )
horse_df = pd.DataFrame(columns=horse_data_columns )
html_dir = "html"+"/"+str(year)+"/"+str(month)
if os.path.isdir(html_dir):
file_list = os.listdir(html_dir)
for file_name in file_list:
with open(html_dir+"/"+file_name, "r") as f:
html = f.read()
list = file_name.split(".")
race_id = list[-2]
race_list, horse_list_list = get_rade_and_horse_data_by_html(race_id, html) #Omis car ce sera long
for horse_list in horse_list_list:
horse_se = pd.Series( horse_list, index=horse_df.columns)
horse_df = horse_df.append(horse_se, ignore_index=True)
race_se = pd.Series(race_list, index=race_df.columns )
race_df = race_df.append(race_se, ignore_index=True )
race_df.to_csv(save_race_csv, header=True, index=False)
horse_df.to_csv(horse_race_csv, header=True, index=False)
Pour chaque course, ajoutez les détails de la course, des informations sur chaque coureur, etc. à la liste et ajoutez une ligne au bloc de données pandas.
La fonction get_rade_and_horse_data_by_html
, race_data_columns
et horse_data_columns
seront compliquées et ne seront pas incluses ici.
Pour expliquer brièvement, la fonction get_rade_and_horse_data_by_html
est une fonction qui utilise BeautifulSoup pour lister et renvoyer les données souhaitées à partir de html.
race_data_columns
et horse_data_columns
sont les noms de colonne des données à acquérir.
Lors de l'exploration, assurez-vous de laisser du temps pour y accéder afin qu'il n'attaque pas le serveur.
Il y a d'autres personnes qui ont résumé les précautions juridiques détaillées, donc si vous le faites réellement, Liste des précautions pour le scraping Web-Qiita ) Etc., veuillez vous référer à.
Maintenant que nous avons les données au format csv, nettoyons-les pour qu'elles soient faciles à gérer.
Ensuite, réfléchissez au type de modèle à créer tout en regardant l'état des données. Après cela, créons des données de train en fonction du modèle que vous souhaitez créer.
Formalisons les données pour qu'elles soient faciles à gérer.
Par exemple, convertissez les données de date ou les nombres d'une chaîne en objet datetime ou int. De plus, comme il sera plus facile à l'avenir si les données d'une colonne sont aussi simples que possible, le sexe et l'âge sont divisés en deux colonnes. Il y a plusieurs choses à faire.
Il aurait peut-être été préférable de le faire en même temps que le grattage, mais comme le code de grattage semblait compliqué, j'ai décidé de le faire séparément cette fois.
Voici quelques-uns d'entre eux.
#Extraire les informations d'heure et les combiner avec les informations de date. Faites-en un type datetime
race_df["time"] = race_df["time"].str.replace('Début: (\d\d):(\d\d)(.|\n)*', r'\1 heure\2 minutes')
race_df["date"] = race_df["date"] + race_df["time"]
race_df["date"] = pd.to_datetime(race_df['date'], format='%Y année%m mois%jour j%H heure%M minutes')
#L'heure d'origine n'est pas nécessaire, supprimez-la
race_df.drop(['time'], axis=1, inplace=True)
#Supprimez le R supplémentaire et les blancs / sauts de ligne dans certaines colonnes rondes
race_df['race_round'] = race_df['race_round'].str.strip('R \n')
Nous analyserons les données formatées et vérifierons grossièrement le type de distribution dont elles disposent. Lors de la création d'un modèle, il est nécessaire de le former pour que les données ne soient pas biaisées autant que possible, c'est donc également important pour la définition des problèmes du modèle.
En outre, l'analyse des données est importante lorsque l'on considère comment créer des fonctionnalités. Dans le cas de l'apprentissage en profondeur, etc., il semble qu'il ne soit pas nécessaire de s'en tenir à l'ingénierie de la quantité de fonctionnalités, mais lorsque vous effectuez un apprentissage automatique non profond ordinaire tel que le boosting de gradient tel que LightGBM, il est nécessaire de réfléchir attentivement à la quantité de fonctionnalités. il y a.
Même avec Kaggle, si vous pouvez trouver une bonne quantité de fonctionnalités, il semble que la possibilité d'entrer dans les rangs supérieurs augmentera.
Après avoir décidé du type de modèle à créer en se référant à l'analyse de données mentionnée précédemment, créons des données de train.
Bien qu'il s'agisse de données d'entrée, c'est à peu près comme suit.
Les cotes de la course que vous souhaitez prédire fluctueront juste avant le match, nous ne les inclurons donc pas dans les données.
Tout d'abord, je vais donner un aperçu, cette fois je ferai un apprentissage profond avec keras. Utiliser les données d'un cheval comme entrée
J'en ai fait deux.
Il faut se demander s'il faut résoudre le problème de classification ou le problème de régression.
Dans le cas du problème de régression, je pense que cela permettra de prédire combien le cheval sera (cela permettra quelque chose comme 1,2) et le temps.
Dans le cas d'un problème de classement, il vous sera demandé de prédire combien de chevaux il y aura (celui-ci est classé par nombres naturels de 1 à 16), s'il sera le premier, s'il sera en tête, etc. ..
Les temps et les vitesses varient énormément en fonction de l'hippodrome et du parcours, il sera donc difficile de ne pas les prévoir séparément. Cette fois, prévoyons simplement «si nous sommes ou non parmi les premiers» comme un problème de classification.
J'écrirai sur diverses choses que j'ai essayées lors de la création du modèle.
De plus, même si vous faites un modèle, il est indispensable de concevoir un moyen d'éviter le surapprentissage et de vérifier s'il est sur-appris. Même si vous faites du machine learning et que vous obtenez de bons résultats avec les données disponibles, cela ne signifie pas que le modèle peut prédire d'autres données avec une bonne précision.
Tout d'abord, des bases. Il est inutile de créer un modèle à moins que vous ne puissiez évaluer s'il est bon ou non.
80% des données collectées et formatées ont été utilisées comme données de formation et 20% ont été utilisées comme données de test. En d'autres termes
--Données d'apprentissage: janvier 2008-23 juillet 2017 --Données d'essai: 23 juillet 2017-novembre 2019
C'est sous la forme de. Ces données de test sont utilisées pour le taux de réponse correct écrit au début.
Au moment de la formation, les données de formation ont été divisées en une pour la formation et une pour la validation.
La régularisation du poids et les abandons sont quelques-uns des moyens de prévenir le surapprentissage, et les keras les rendent faciles à utiliser.
Ajouter un coût en fonction du poids à la fonction de perte du réseau est la régularisation du poids, et l'abandon consiste à réduire (supprimer) de manière aléatoire la quantité de caractéristiques de la couche pendant l'entraînement.
Nous avons utilisé la régularisation L2 pour la régularisation du poids.
Référence: Connaître le surapprentissage et le manque d'apprentissage | TensorFlow Core
model = tf.keras.Sequential([
tf.keras.layers.Dense(300, kernel_regularizer=tf.keras.regularizers.l2(0.001), activation=tf.nn.relu, input_dim=df_columns_len), #l2 Couche régularisée
tf.keras.layers.Dropout(0.2), #Abandonner
tf.keras.layers.Dense(100, kernel_regularizer=tf.keras.regularizers.l2(0.001), activation=tf.nn.relu), #l2 Couche régularisée
tf.keras.layers.Dropout(0.2), #Abandonner
tf.keras.layers.Dense(1, activation=tf.nn.sigmoid)
])
Une simple validation d'exclusion utilisant seulement une période de temps spécifique peut se révéler surentraînée pour donner de bons résultats pendant cette période.
Vérifions si le modèle est bon avec les données disponibles, car la validation croisée est effectuée dans des compétitions telles que Kaggle.
Le problème est qu'il s'agit de données de séries chronologiques, vous ne pouvez donc pas simplement utiliser KFold pour diviser les données. Lors de la saisie de données de séries chronologiques, si les informations futures sont définies pour s'entraîner et que les informations passées sont validées, le résultat peut être meilleur qu'il ne devrait l'être. En fait, j'ai fait une erreur au début et je me suis entraîné en saisissant des données futures, mais la probabilité de prédiction de double victoire dépassait 70%.
Donc, cette fois, j'ai utilisé la méthode de fractionnement utilisée pour la validation croisée des données de séries temporelles ([TimeSeries Split] de sklearn (https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.TimeSeriesSplit. html)).
En gros, comme le montre la figure ci-dessous, l'ensemble de données est divisé en ajoutant des séries chronologiques et une partie est utilisée comme données de vérification.
Dans cette figure, vous apprendrez trois fois. Cependant, certaines données d'entraînement seront réduites, donc si le nombre de données est petit, un simple blocage peut être préférable.
tscv = TimeSeriesSplit(n_splits=3)
for train_index, val_index in tscv.split(X_train,Y_train):
train_data=X_train[train_index]
train_label=Y_train[train_index]
val_data=X_train[val_index]
val_label=Y_train[val_index]
model = train_model(train_data,train_label,val_data,val_label,target_name)
Les hyperparamètres dans l'apprentissage automatique sont importants. Par exemple, dans l'apprentissage en profondeur, plus la couche intermédiaire est grande, plus il y a de variables intermédiaires, et moins il y a de données d'entraînement, plus il est facile de surpasser. En revanche, s'il est petit, même si la quantité de données est suffisante, il peut ne pas être assez flexible pour apprendre correctement.
Il y aura beaucoup de controverse sur la façon de le faire. Cela semble varier d'une personne à l'autre.
Cette fois, il y avait une bibliothèque appelée hyperas qui ajuste automatiquement le réglage des paramètres des keras, j'ai donc décidé de l'utiliser. C'était relativement intuitif et facile à comprendre.
Pour une utilisation simple, passez simplement la fonction de préparation des données et la fonction qui renvoie la valeur que vous voulez minimiser en apprenant à ʻoptim.minimize`.
Spécifiez la largeur que vous souhaitez ajuster avec choice
pour les valeurs entières et ʻuniform` pour les nombres réels.
Pour plus de détails, consultez ici: https://github.com/maxpumperla/hyperas
import keras
from keras.callbacks import EarlyStopping
from keras.callbacks import CSVLogger
from keras.models import Sequential
from keras.layers.core import Dense, Dropout, Activation
from hyperopt import Trials, STATUS_OK, tpe
from hyperas import optim
from hyperas.distributions import choice, uniform
def prepare_data_is_hukusyo():
"""
Je vais préparer diverses données ici
"""
return X_train, Y_train, X_test, Y_test
def create_model_is_hukusyo(X_train, Y_train, X_test, Y_test):
train_size = int(len(Y_train) * 0.8)
train_data = X_train[0:train_size]
train_label = Y_train[0:train_size]
val_data = X_train[train_size:len(Y_train)]
val_label = Y_train[train_size:len(Y_train)]
callbacks = []
callbacks.append(EarlyStopping(monitor='val_loss', patience=2))
model = Sequential()
model.add(Dense({{choice([512,1024])}}, kernel_regularizer=keras.regularizers.l2(0.001), activation="relu", input_dim=train_data.shape[1]))
model.add(Dropout({{uniform(0, 0.3)}}))
model.add(Dense({{choice([128, 256, 512])}}, kernel_regularizer=keras.regularizers.l2(0.001), activation="relu"))
model.add(Dropout({{uniform(0, 0.5)}}))
if {{choice(['three', 'four'])}} == 'three':
pass
elif {{choice(['three', 'four'])}} == 'four':
model.add(Dense(8, kernel_regularizer=keras.regularizers.l2(0.001), activation="relu"))
model.add(Dropout({{uniform(0, 0.5)}}))
model.add(Dense(1, activation="sigmoid"))
model.compile(
loss='binary_crossentropy',
optimizer=keras.optimizers.Adam(),
metrics=['accuracy'])
history = model.fit(train_data,
train_label,
validation_data=(val_data, val_label),
epochs=30,
batch_size=256,
callbacks=callbacks)
val_loss, val_acc = model.evaluate(X_test, Y_test, verbose=0)
print('Best validation loss of epoch:', val_loss)
return {'loss': val_loss, 'status': STATUS_OK, 'model': model}
#Ajuster réellement avec des hyperas
best_run, best_model = optim.minimize(model=create_model_is_hukusyo,
data=prepare_data_is_hukusyo,
algo=tpe.suggest,
max_evals=15,
trials=Trials())
Vous pourrez peut-être faire des prédictions plus précises en mélangeant les sorties de différents modèles.
En faisant la moyenne de la prédiction de la 1ère place et de la 3ème place et au-dessus de la prédiction, nous avons pu obtenir une valeur légèrement supérieure à la valeur de prédiction d'origine.
Les caractéristiques des chevaux susceptibles d'être classés premiers et les caractéristiques des chevaux susceptibles d'être classés élevés peuvent être légèrement différentes, et l'on pense qu'une prédiction plus précise est possible en mélangeant les deux. Je vais.
Par exemple, il semble que les caractéristiques d'un cheval qui peut être classé 1er mais qui n'en fait pas trop s'il semble échouer au milieu de la course et un cheval qui entre de manière stable dans le top sont légèrement différentes.
Au final, j'ai réalisé un modèle plus précis que moi, qui est un débutant en courses de chevaux.
Il y a encore plus d'informations qui semblent être importantes dans les courses de chevaux, il semble donc y avoir place à l'amélioration.
Le solde lorsque je continue d'acheter la 1ère place lors d'une victoire est le suivant. Je l'ai tracé correctement en utilisant des pandas.
Dans la double victoire, c'est devenu comme suit.
C'est un gros déficit. Ce sera un peu mieux si vous n'achetez que ceux avec des prédictions élevées et non ceux avec des cotes faibles.
En faisant cette prédiction de courses de chevaux, je laisserai certaines des choses que j'ai essayées qui n'ont rien à voir avec la ligne principale.
Le crédit gratuit GCP était sur le point d'expirer vers la fin du mois de novembre, mon deuxième objectif était donc de le consommer.
Vous pouvez lancer le programme avant d'aller vous coucher et le vérifier lorsque vous vous réveillez le matin.
Soyez prudent si vous utilisez GCP, car l'instance gratuite ne dispose pas de suffisamment de mémoire pour créer du CSV et du deep learning.
En ce qui concerne GCP, j'avais l'habitude d'envoyer LINE Notify si le programme se terminait ou si une erreur se produisait.
Dès que j'ai terminé, j'ai pu voir les résultats et exécuter le programme suivant, ce qui représentait beaucoup de travail.
C'est un divertissement approprié pour les étudiants, donc si vous le connaissez, je pense qu'il y a beaucoup de choses à faire. Si vous faites une erreur, ce sera une expérience d'apprentissage, donc je vous serais reconnaissant de bien vouloir le signaler dans les commentaires ou sur Twitter.
Identifiant Twitter (je ne tweet pas trop): @ 634kami
Il est publié sur github. Je voulais faire quelque chose qui fonctionne pour le moment, donc ce n'est pas quelque chose que les gens peuvent voir, mais s'il vous plaît ne voyez que ceux qui disent que ça va.
Le code sur Qiita a été partiellement modifié pour le rendre plus facile à lire.
J'ai ajouté ce qui suit parce que j'ai fait ce qui suit.
Voici les résultats.
total: 8, random tansyo accuracy:0.125, hukusyo accuracy:0.375
tansyo accuracy: 0.3497536945812808
hukusyo accuracy: 0.7044334975369458
total: 9, random tansyo accuracy:0.1111111111111111, hukusyo accuracy:0.3333333333333333
tansyo accuracy: 0.2693726937269373
hukusyo accuracy: 0.6568265682656826
total: 10, random tansyo accuracy:0.1, hukusyo accuracy:0.3
tansyo accuracy: 0.30563002680965146
hukusyo accuracy: 0.6407506702412868
total: 11, random tansyo accuracy:0.09090909090909091, hukusyo accuracy:0.2727272727272727
tansyo accuracy: 0.2582278481012658
hukusyo accuracy: 0.5468354430379747
total: 12, random tansyo accuracy:0.08333333333333333, hukusyo accuracy:0.25
tansyo accuracy: 0.2600806451612903
hukusyo accuracy: 0.5826612903225806
total: 13, random tansyo accuracy:0.07692307692307693, hukusyo accuracy:0.23076923076923078
tansyo accuracy: 0.2894736842105263
hukusyo accuracy: 0.5855263157894737
total: 14, random tansyo accuracy:0.07142857142857142, hukusyo accuracy:0.21428571428571427
tansyo accuracy: 0.23014586709886548
hukusyo accuracy: 0.5380875202593193
total: 15, random tansyo accuracy:0.06666666666666667, hukusyo accuracy:0.2
tansyo accuracy: 0.2525399129172714
hukusyo accuracy: 0.532656023222061
Dans chaque cas, le taux d'exactitude était meilleur que la méthode de sélection complètement aléatoire.