[PYTHON] Sazaes Janken-Vorhersage von LightGBM

Einführung

Als Praxis der Vorhersage von Zeitreihendaten durch maschinelles Lernen habe ich Sazaes Janken-Vorhersage mit LightGBM ausprobiert.

Was ist LightGBM?

Es ist einer der Algorithmen für maschinelles Lernen und verwendet eine Gradientenverstärkung basierend auf dem Entscheidungsbaum. Es ist eine hochkarätige Methode des maschinellen Lernens, die von vielen der Top-Spieler der letzten Kaggle-Wettbewerbe verwendet wird.

Eine gründliche Einführung in LightGBM https://www.codexa.net/lightgbm-beginner/

Datensatz

Wir haben Daten vom "Sazae-san Janken Institute" ausgeliehen, das alle Janken vom Beginn von Janken 1991 bis heute aufzeichnet. Ich bin überrascht, dass ich seit dem Zeitalter der PC-Kommunikation vor dem Internet aufgenommen habe. Zusätzlich zu den Aufzeichnungen analysieren wir aus verschiedenen Blickwinkeln, welche Bewegung als nächstes kommen wird.

Offizielle Website des Sazae-san Janken Institute http://park11.wakwak.com/~hkn/

Auswahl der Merkmalsmenge

Laut der Analyse des "Sazae-san Janken Institute" gab es eine Methode zur Vorhersage des nächsten Zuges aus den letzten beiden Zügen und eine Methode zur Vorhersage, dass der Zug, der seit langem nicht mehr ausgeführt wurde, der nächste Zug ist. Darüber hinaus ist es leicht, während der ersten Sendung der Saison (Januar, April, Juli, Oktober) und der Sonderfolge erstickt zu werden.

Zuerst haben wir ein Basismodell erstellt, das diese als Merkmalsmengen verwendet, und überprüft, welche Merkmalsmenge wirksam war, während die Merkmalsmenge erhöht oder verringert wurde.

Infolgedessen sind die endgültig ausgewählten Merkmale wie folgt. ・ Ergebnisse der letzten drei Male (Wenn Sie die letzten vier oder mehr Male einbeziehen, verringert sich die Genauigkeit) ・ Ob es die erste Staffel ist ・ Ob es eine besondere Zeit ist ・ Gibt an, ob das letzte Mal das erste Mal in der Saison ist (dies gilt nur für das letzte Mal. Wenn Sie bis zu zwei Mal einschließen, verringert sich die Genauigkeit.) ・ Ob das letzte Mal eine besondere Zeit war (dies ist nur das letzte Mal. Wenn Sie bis zu 2 Mal einschließen, verringert sich die Genauigkeit)

Laut "Sazae-san Janken Institute" entscheidet der Verantwortliche der Produktionsfirma die Hand nach der Stimmung. Zu diesem Zeitpunkt ist es sehr wahrscheinlich, dass der nächste Schritt unternommen wird, um ihn nicht in Bezug auf die Vergangenheit von Janken mehrmals zu tragen. Daher halte ich es für sinnvoll, die Ergebnisse von höchstens dreimal so vielen Verzögerungsmerkmalen wie die Merkmalsmenge zu verwenden. Darüber hinaus gab es im Labor eine Methode, um vorherzusagen, dass die Bewegung, die am längsten nicht auftrat, die nächste Bewegung war. Als ich dies jedoch als Merkmalsgröße betrachtete, änderte sich die Genauigkeit nicht so sehr, sodass ich sie ausschloss.

Lernen und Testen

Wir haben das endgültige Lernen und Testen mit LightGBM als diese Funktionen durchgeführt. ・ Lerndaten: 1196 Mal vom 1. Dezember 1991 bis 9. August 2015 ・ Überprüfungsdaten: 194 Mal vom 16. August 2015 bis 14. Juli 2019 ・ Testdaten: 50 Mal vom 21. Juli 2019 bis 5. Juli 2020

Infolgedessen betrug die ** Genauigkeitsrate (Genauigkeit) in den Testdaten 65,3% **. Wenn die Gewinnrate unter Verwendung des gleichen Index wie die Website berechnet wurde (Gewinnen / (Gewinnen + Verlieren)), wobei die Strategie gewählt wurde, den Zug mit der höchsten Wahrscheinlichkeit unter den Vorhersagen zu gewinnen, betrug die Gewinnrate 84,2% **. Ich tat.

Code

Zum Schluss werde ich den Code einfügen.

Lernen / Testen

import pandas as pd
import lightgbm as lgb

import numpy as np

from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

#Janken2.Zum Zeitpunkt von csv ist eine gewisse Verarbeitung abgeschlossen.
sazae = pd.read_csv('Janken2.csv')

sazae.drop(labels=['cnt','date'], axis=1, inplace=True)
sazae.year = sazae.year - 1990
sazae.season = sazae.season.fillna(0)
sazae.special = sazae.special.fillna(0)
sazae['janken_lag_1'] = sazae['janken'].shift(1)
sazae['janken_lag_2'] = sazae['janken'].shift(2)
sazae['janken_lag_3'] = sazae['janken'].shift(3)
sazae['season_lag'] = sazae['season'].shift(1)
sazae['special_lag'] = sazae['special'].shift(1)

sazae = sazae[3:]
sazae = sazae.astype({'special_lag':int,'season_lag':int,'janken': int, 'special': int, 'season': int, 'janken_lag_1':int, 'janken_lag_2':int, 'janken_lag_3':int})
sazae[(sazae['janken_lag_1']==0) & (sazae['janken_lag_2']==1)& (sazae['janken_lag_3']==0)]

X, y = sazae[['special','season','janken_lag_1','janken_lag_2','janken_lag_3','season_lag','special_lag']], sazae[['janken']]
cat = ['season','janken_lag_1','janken_lag_2','janken_lag_3','season_lag','special_lag', 'special']

X_train, y_train = X[(X.index >= 0) & (X.index < 1200)], y[(y.index >= 0) & (y.index < 1200)]
X_valid, y_valid = X[(X.index >= 1200) & (X.index < 1394)], y[(y.index >= 1200) & (y.index < 1394)]
X_test, y_test = X[(X.index >= 1394)], y[(y.index >= 1394)]

#Stellen Sie die zum Lernen verwendeten Daten ein
lgb_train = lgb.Dataset(X_train, y_train, categorical_feature=cat)
lgb_eval = lgb.Dataset(X_valid, y_valid, reference=lgb_train, categorical_feature=cat)

# LightGBM parameters
params = {
        'task': 'train',
        'boosting_type': 'gbdt',
        'objective': 'multiclass', #Zweck:Klassifizierung mehrerer Klassen
        'num_class': 3, #Anzahl der Klassen: 3
        'metric': {'multi_error'}, #Bewertungsindex:Fehlerrate(= 1-Richtige Antwortrate) 
}

#Modelllernen
model = lgb.train(params,
train_set=lgb_train, #Bezeichnung der Trainingsdaten
valid_sets=lgb_eval, #Angeben von Verifizierungsdaten
#Lerne bis zu 1000 Runden
num_boost_round=2000,
#Hören Sie auf zu lernen, wenn sich die Leistung nach 10 Runden nicht verbessert
early_stopping_rounds=100              
)

#Vorhersage von Testdaten((Vorhersagewahrscheinlichkeit jeder Klasse[Schmiere(0)Vorhersagewahrscheinlichkeit,Choki(1)のVorhersagewahrscheinlichkeit,Par(2)のVorhersagewahrscheinlichkeit]Gib es zurück))
y_pred_prob = model.predict(X_test)
y_pred = np.argmax(y_pred_prob, axis=1) 

accuracy = accuracy_score(y_test, y_pred)
print(accuracy)

Gewinnratenberechnung

win = 0
lose = 0
draw = 0
janken = (y_pred + 2) % 3
print(janken)
for (test, j) in zip(y_test.values, janken):
    if test == j:
        draw += 1
    elif (test+2)%3 == j:
        win += 1
    elif (test+1)%3 == j:
        lose += 1
print(win,draw,lose)
print(win/(win+lose))

Vorhersage der nächsten Sendung

test2 = pd.DataFrame(index=[], columns=X_test.columns)
print(test2)

#[Besondere Zeiten,Zum ersten Mal in der Saison,Letzte Hand,Hände zweimal vorher,Hand vor dreimal,Ob das letzte Mal das erste Mal der Saison ist,前回がBesondere Zeitenかどうか]Angeben
test2.loc[0] = [0,0,1,0,2,1,0] #2020/7/12

test2 = test2.astype({'special_lag':int,'season_lag':int, 'special': int, 'season': int, 'janken_lag_1':int, 'janken_lag_2':int, 'janken_lag_3':int})

result = model.predict(test2)

#[Goo-Wahrscheinlichkeit, Choki-Wahrscheinlichkeit, Par-Wahrscheinlichkeit]
print(result)

Was ich in Zukunft machen möchte

・ Der Code ist etwas chaotisch, deshalb werde ich ihn organisieren. ・ Lebenslauf (Kreuzvalidierung) ・ Parametereinstellung

Referenzseite

Maschinelles Lernen mit Sazae-san (Neuronales Netzwerk)

Recommended Posts

Sazaes Janken-Vorhersage von LightGBM
Sprachvorhersagemodell von TensorFlow
Denken Sie an Transformation Janken durch Optimierung