[PYTHON] Spezifische Implementierungsmethode zum Hinzufügen früherer Leistungsdaten von Pferden, um die Menge des maschinellen Lernens zu bestimmen

Zweck

Prognostizieren Sie Pferderennen mit maschinellem Lernen und streben Sie eine Wiederherstellungsrate von 100% an.

Was ist diesmal zu tun?

Letztes Mal habe ich ein Modell für maschinelles Lernen erstellt, das die Pferde vorhersagt, die mit LightGBM unter den Top 3 sein werden. Dieses Mal möchte ich "frühere Leistung von Pferden" als Merkmalsmenge hinzufügen, aber wenn ich es tatsächlich versuche, sind Schaben und Datenverarbeitung ziemlich schwierig. Daher möchte ich zusammenfassen, welche Art von Code geschrieben und implementiert werden soll </ font>. スクリーンショット 2020-07-09 18.13.19.png

Quellcode

Kratzen Sie zuerst die früheren Ergebnisse aller Pferde, die 2019 von netkeiba.com gelaufen sind. Auf netkeiba.com wird für jedes Pferd die Pferde-ID angegeben, und die Seiten-URL der vergangenen Ergebnisse lautet 「https://db.netkeiba.com/horse/(horse_id)」 Da es die Struktur hat, wird die in Vorheriger Artikel erstellte Funktion scrape_race_results verarbeitet, um die erforderliche Pferde-ID (und auch die Reiter-ID) zu entfernen.

import time
from tqdm.notebook import tqdm
import requests
from bs4 import BeautifulSoup
import re
import pandas as pd

def scrape_race_results(race_id_list, pre_race_results={}):
    race_results = pre_race_results
    for race_id in tqdm(race_id_list):
        if race_id in race_results.keys():
            continue
        try:
            url = "https://db.netkeiba.com/race/" + race_id
            df = pd.read_html(url)[0]

            # horse_ID und Jockey_Scraping ID
            html = requests.get(url)
            html.encoding = "EUC-JP"
            soup = BeautifulSoup(html.text, "html.parser")
            # horse_id
            horse_id_list = []
            horse_a_list = soup.find("table", attrs={"summary": "Rennergebnis"}).find_all(
                "a", attrs={"href": re.compile("^/horse")}
            )
            for a in horse_a_list:
                horse_id = re.findall(r"\d+", a["href"])
                #Es wird groß geschrieben, weil es einen Fehler verursacht, wenn Backslash in Qiita verwendet wird.
                horse_id_list.append(horse_id[0])
            # jockey_id
            jockey_id_list = []
            jockey_a_list = soup.find("table", attrs={"summary": "Rennergebnis"}).find_all(
                "a", attrs={"href": re.compile("^/jockey")}
            )
            for a in jockey_a_list:
                jockey_id = re.findall(r"\d+", a["href"])
                jockey_id_list.append(jockey_id[0])

            df["horse_id"] = horse_id_list
            df["jockey_id"] = jockey_id_list
            race_results[race_id] = df
            time.sleep(1)
        except IndexError:
            continue
        except Exception as e:
            print(e)
            break
    return race_results

In DataFrame-Typ konvertieren, der auf den vorherigen Artikel verweist. Dadurch erhalten Sie eine Liste der Pferde_IDs, die Sie benötigen.

results = scrape_race_results(race_id_list)
results = pd.concat([results[key] for key in results])
horse_id_list = results['horse_id'].unique()

Dies wird verwendet, um vergangene Leistungsdaten zu kratzen.

def scrape_horse_results(horse_id_list, pre_horse_id=[]):
    horse_results = {}
    for horse_id in tqdm(horse_id_list):
        if horse_id in pre_horse_id:
            continue
        try:
            url = 'https://db.netkeiba.com/horse/' + horse_id
            df = pd.read_html(url)[3]
            if df.columns[0]=='Preisgeschichte':
                df = pd.read_html(url)[4]
            horse_results[horse_id] = df
            time.sleep(1)
        except IndexError:
            continue
        except Exception as e:
            import traceback
            traceback.print_exc()
            print(e)
            break
        except:
            break
    return horse_results

Es dauert lange, aber machen Sie es nach dem Scraping wieder zu einem DataFrame-Typ und speichern Sie es in einer Pickle-Datei.

horse_results = scrape_horse_results(horse_id_list)
for key in horse_results:
    horse_results[key].index = [key] * len(horse_results[key])
df = pd.concat([horse_results[key] for key in horse_results])
df.to_pickle('horse_results.pickle')

Erstellen Sie als Nächstes eine Klasse namens HorseResults und implementieren Sie eine Funktion, die die Reihenfolge der Ankunft und den Durchschnitt der Preise zusammenführt.

class HorseResults:
    def __init__(self, horse_results):
        self.horse_results = horse_results[['Datum', 'Reihenfolge der Ankunft', 'Preis']]
        self.preprocessing()
        
    def preprocessing(self):
        df = self.horse_results.copy()

        #Entfernen Sie Elemente, die nicht numerische Zeichenfolgen in der Reihenfolge ihrer Ankunft enthalten
        df['Reihenfolge der Ankunft'] = pd.to_numeric(df['Reihenfolge der Ankunft'], errors='coerce')
        df.dropna(subset=['Reihenfolge der Ankunft'], inplace=True)
        df['Reihenfolge der Ankunft'] = df['Reihenfolge der Ankunft'].astype(int)

        df["date"] = pd.to_datetime(df["Datum"])
        df.drop(['Datum'], axis=1, inplace=True)
        
        #Fülle den Preis NaN mit 0
        df['Preis'].fillna(0, inplace=True)
    
        self.horse_results = df
        
    def average(self, horse_id_list, date, n_samples='all'):
        target_df = self.horse_results.loc[horse_id_list]
        
        #Geben Sie an, wie viele Läufe in der Vergangenheit ausgeführt wurden
        if n_samples == 'all':
            filtered_df = target_df[target_df['date'] < date]
        elif n_samples > 0:
            filtered_df = target_df[target_df['date'] < date].\
                sort_values('date', ascending=False).groupby(level=0).head(n_samples)
        else:
            raise Exception('n_samples must be >0')
            
        average = filtered_df.groupby(level=0)[['Reihenfolge der Ankunft', 'Preis']].mean()
        return average.rename(columns={'Reihenfolge der Ankunft':'Reihenfolge der Ankunft_{}R'.format(n_samples), 'Preis':'Preis_{}R'.format(n_samples)})
    
    def merge(self, results, date, n_samples='all'):
        df = results[results['date']==date]
        horse_id_list = df['horse_id']
        merged_df = df.merge(self.average(horse_id_list, date, n_samples), left_on='horse_id',
                             right_index=True, how='left')
        return merged_df
    
    def merge_all(self, results, n_samples='all'):
        date_list = results['date'].unique()
        merged_df = pd.concat([self.merge(results, date, n_samples) for date in tqdm(date_list)])
        return merged_df

Wenn Sie beispielsweise die Ergebnisse der letzten 5 Rennen zur Feature-Menge hinzufügen möchten, können Sie Folgendes implementieren.

hr = HorseResults(horse_results)
results_5R = hr.merge_all(results_p, n_samples=5)

Jetzt können Sie sehen, dass die Reihenfolge der Ankunft und der Durchschnitt der letzten 5 Preisrennen zu den beiden Spalten ganz rechts hinzugefügt wurden. スクリーンショット 2020-07-09 18.41.01.png

Details werden im Video ↓ erklärt Datenanalyse / maschinelles Lernen beginnend mit der Vorhersage von Pferderennen スクリーンショット 2020-07-11 15.00.29.png

Recommended Posts

Spezifische Implementierungsmethode zum Hinzufügen früherer Leistungsdaten von Pferden, um die Menge des maschinellen Lernens zu bestimmen
Sammeln von Daten zum maschinellen Lernen
Maschinelles Lernen #k Nachbarschaftsmethode und deren Implementierung und verschiedene
Einführung in das maschinelle Lernen
Versuchen Sie, die Leistung des Modells für maschinelles Lernen / Regression zu bewerten
Einführung in das maschinelle Lernen mit scikit-learn-Von der Datenerfassung bis zur Parameteroptimierung
Leistungsüberprüfung der Datenvorverarbeitung für maschinelles Lernen (numerische Daten) (Teil 2)
Die Verwendung von icrawler zum Sammeln von Daten zum maschinellen Lernen wurde vereinfacht
Versuchen Sie, die Leistung des Modells für maschinelles Lernen / Klassifizierung zu bewerten
Anfänger des maschinellen Lernens versuchen, Naive Bayes zu erreichen (2) - Implementierung
Leistungsüberprüfung der Datenvorverarbeitung für maschinelles Lernen (numerische Daten) (Teil 1)
Datensatz für maschinelles Lernen
Eine Einführung in das maschinelle Lernen
Super Einführung in das maschinelle Lernen
[Maschinelles Lernen] Überprüfen Sie die Leistung des Klassifikators anhand handgeschriebener Zeichendaten
Newton-Methode für maschinelles Lernen (von 1 Variablen zu mehreren Variablen)