XGBoost ist eine GBDT-Methode und kann in Python implementiert werden. Als ich jedoch die Implementierungsbeispiele untersuchte, war ich verwirrt, weil es mehrere Möglichkeiten gab, sie zu beschreiben, obwohl sie dieselbe Bibliothek verwendeten. Daher besteht der Zweck dieses Artikels darin, in jeder Notation dasselbe mit der einprägsamen Bedeutung des Autors zu versuchen. (Bitte beachten Sie, dass eine ausführliche Erläuterung von XGBoost weggelassen wird.)
pip install xgboost
import_boston_datasets.py
#Importieren Sie zuerst die Bibliothek, die dieses Mal verwendet werden soll
import pandas as pd
import numpy as np
import xgboost
import matplotlib.pyplot as plt
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
boston = load_boston()
df_boston = pd.DataFrame(boston.data, columns=boston.feature_names)
#Fügen Sie die Zielvariable als Preis an das Ende des Datenrahmens an, um sie alle zusammen anzuzeigen.
df_boston['PRICE'] = boston.target
print(df_boston.head())
CRIM | ZN | INDUS | CHAS | NOX | RM | AGE | DIS | RAD | TAX | PTRATIO | B | LSTAT | PRICE | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0.00632 | 18.0 | 2.31 | 0.0 | 0.538 | 6.575 | 65.2 | 4.0900 | 1.0 | 296.0 | 15.3 | 396.90 | 4.98 | 24.0 |
1 | 0.02731 | 0.0 | 7.07 | 0.0 | 0.469 | 6.421 | 78.9 | 4.9671 | 2.0 | 242.0 | 17.8 | 396.90 | 9.14 | 21.6 |
2 | 0.02729 | 0.0 | 7.07 | 0.0 | 0.469 | 7.185 | 61.1 | 4.9671 | 2.0 | 242.0 | 17.8 | 392.83 | 4.03 | 34.7 |
3 | 0.03237 | 0.0 | 2.18 | 0.0 | 0.458 | 6.998 | 45.8 | 6.0622 | 3.0 | 222.0 | 18.7 | 394.63 | 2.94 | 33.4 |
4 | 0.06905 | 0.0 | 2.18 | 0.0 | 0.458 | 7.147 | 54.2 | 6.0622 | 3.0 | 222.0 | 18.7 | 396.90 | 5.33 | 36.2 |
make_train_test.py
#Teilen Sie die Daten in Merkmal x und Zielvariable y
x = df_boston.loc[:,'CRIM':'LSTAT']
y = df_boston['PRICE']
#7:Unterteilt in Zugdaten und Testdaten bei 3
trainX, testX, trainY, testY = train_test_split(x, y, test_size=0.3)
#Versuchen Sie, jede Form auszugeben
print('x.shape = {}'.format(x.shape))
print('y.shape = {}'.format(y.shape))
print('trainX.shape = {}'.format(trainX.shape))
print('trainY.shape = {}'.format(trainY.shape))
print('testX.shape = {}'.format(testX.shape))
print('testY.shape = {}'.format(testY.shape))
# x.shape = (506, 13)
# y.shape = (506,)
# trainX.shape = (354, 13)
# trainY.shape = (354,)
# testX.shape = (152, 13)
# testY.shape = (152,)
Methode 1 ist eine Methode, die eine Schnittstelle mit ** scikit-learn-kompatibler API ** verwendet. Ich werde es von hier aus beschreiben, mit dem Sie vielleicht vertraut sind. Zunächst von der einfachsten Implementierung ohne Angabe von Parametern.
regression1-1.py
#Verwenden Sie XGB Regressor, da es sich um eine Regression handelt
reg = xgb.XGBRegressor()
#eval_Stellen Sie die Verifizierungsdaten im Set ein
reg.fit(trainX, trainY,
eval_set=[(trainX, trainY),(testX, testY)])
#[0] validation_0-rmse:21.5867 validation_1-rmse:21.7497
#[1] validation_0-rmse:19.5683 validation_1-rmse:19.7109
#[2] validation_0-rmse:17.7456 validation_1-rmse:17.8998
#Kürzung
#[97] validation_0-rmse:1.45198 validation_1-rmse:2.7243
#[98] validation_0-rmse:1.44249 validation_1-rmse:2.72238
#[99] validation_0-rmse:1.43333 validation_1-rmse:2.7233
#Vorausschauende Ausführung
predY = reg.predict(testX)
#Anzeige von MSE
print(mean_squared_error(testY, predY))
#7.4163707577050655
Wenn Sie die Parameter etwas genauer angeben, ist dies wie folgt.
regression1-2.py
reg = xgb.XGBRegressor(#Festlegen der Zielfunktion Der Anfangswert ist auch der quadratische Fehler
objective='reg:squarederror',
#Anzahl der frühen Lernrunden_Geben Sie mehr an, da das Stoppen verwendet wird
n_estimators=50000,
#Was für Booster zu verwenden ist Der Anfangswert ist auch gbtree
booster='gbtree',
#Lernrate
learning_rate=0.01,
#Maximale Tiefe des Baumes
max_depth=6,
#Startwert
random_state=2525)
#Bereiten Sie Variablen vor, um den Lernprozess anzuzeigen
evals_result = {}
reg.fit(trainX, trainY,
eval_set=[(trainX, trainY),(testX, testY)],
#Bewertungsindex zum Lernen
eval_metric='rmse',
#Geben Sie die Anzahl der Runden an, um das Lernen zu beenden, wenn sich die Zielfunktion nicht verbessert
early_stopping_rounds=15,
#Verwenden Sie die Rückruf-API, um den Lernprozess aufzuzeichnen und die oben genannten Variablen anzugeben
callbacks=[xgb.callback.record_evaluation(evals_result)])
#[1] validation_0-rmse:19.5646 validation_1-rmse:19.7128
#[2] validation_0-rmse:17.7365 validation_1-rmse:17.9048
#[3] validation_0-rmse:16.0894 validation_1-rmse:16.2733
#Kürzung
#[93] validation_0-rmse:0.368592 validation_1-rmse:2.47429
#[94] validation_0-rmse:0.3632 validation_1-rmse:2.47945
#[95] validation_0-rmse:0.356932 validation_1-rmse:2.48028
#Stopping. Best iteration:
#[80] validation_0-rmse:0.474086 validation_1-rmse:2.46597
predY = reg.predict(testX)
print(mean_squared_error(testY, predY))
#6.080995445035289
Der Verlust hat sich ein wenig verbessert, als wenn nichts angegeben wurde. Es gibt andere Parameter, die angegeben werden können, jedoch für Details XGBoost Python API-Referenz Siehe ** Scikit-Learn API ** in.
Es gibt jedoch Parameter, die nicht in diese API geschrieben sind, was häufig verwirrend ist. Zum Beispiel, wenn Sie das Modell ausgeben, wenn nichts angegeben ist
ex.py
reg = xgb.XGBRegressor()
print(reg)
#XGBRegressor(base_score=0.5, booster='gbtree', colsample_bylevel=1,
# colsample_bynode=1, colsample_bytree=1, gamma=0,
# importance_type='gain', learning_rate=0.1, max_delta_step=0,
# max_depth=3, min_child_weight=1, missing=None, n_estimators=100,
# n_jobs=1, nthread=None, objective='reg:linear', random_state=0,
# reg_alpha=0, reg_lambda=1, scale_pos_weight=1, seed=None,
# silent=None, subsample=1, verbosity=1)
Sie können den Anfangswert des Modells folgendermaßen überprüfen. Aber ganz unten
silent=None
Selbst wenn Sie dies mit der API überprüfen, ist ein solcher Parameter überhaupt nicht vorhanden. Einige Websites beschreiben es als Parameter für das Vorhandensein oder Nichtvorhandensein von Ausgaben während des Trainings, aber selbst wenn es angegeben wurde, hat sich nichts geändert.
Als nächstes folgt die zweite Methode: Dies ist die ** ursprüngliche API ** der xgboost-Bibliothek. Daher gibt es einen kleinen Unterschied im Umgang mit Datensätzen.
regression2-1.py
#xgb.Machen Sie es in der ursprünglichen API von DMatrix verwendbar
#feature_Sie müssen keine Namen angeben, aber es ist sicher, sie hinzuzufügen, da dies später bequem sein wird.
dtrain = xgb.DMatrix(trainX, label=trainY, feature_names = x.columns)
dtest = xgb.DMatrix(testX, label=testY, feature_names = x.columns)
reg = xgb.train(#Geben Sie eine leere Liste an, da das Training mit dem Anfangswert durchgeführt wird, ohne absichtlich Parameter anzugeben
params=[],
dtrain=dtrain,
#Stellen Sie die Verifizierungsdaten in eval ein
evals=[(dtrain, 'train'), (dtest, 'eval')])
#[0] train-rmse:17.1273 eval-rmse:17.3433
#[1] train-rmse:12.3964 eval-rmse:12.7432
#[2] train-rmse:9.07831 eval-rmse:9.44546
#[3] train-rmse:6.6861 eval-rmse:7.16429
#[4] train-rmse:5.03358 eval-rmse:5.70227
#[5] train-rmse:3.88521 eval-rmse:4.7088
#[6] train-rmse:3.03311 eval-rmse:4.09655
#[7] train-rmse:2.44077 eval-rmse:3.6657
#[8] train-rmse:2.0368 eval-rmse:3.40768
#[9] train-rmse:1.72258 eval-rmse:3.29363
predY = reg.predict(dtest)
print(mean_squared_error(testY, predY))
#10.847961069710934
Sie können sehen, dass die Anzahl der Lernrunden standardmäßig sehr gering eingestellt ist. Das ist kein besseres Ergebnis als Methode 1. Lassen Sie uns die Parameter auf die gleiche Weise einstellen und ausführen.
regression2-2.py
#xgb.Machen Sie es in der ursprünglichen API von DMatrix verwendbar
dtrain = xgb.DMatrix(trainX, label=trainY, feature_names = x.columns)
dtest = xgb.DMatrix(testX, label=testY, feature_names = x.columns)
#Xgb zuerst_Stellen Sie die Parameter als Parameter ein
xgb_params = {#Zielfunktion
'objective': 'reg:squarederror',
#Bewertungsindex zum Lernen
'eval_metric': 'rmse',
#Was für Booster zu verwenden
'booster': 'gbtree',
#learning_Synonym für Rate
'eta': 0.1,
#Maximale Tiefe des Baumes
'max_depth': 6,
#random_Synonym für Staat
'seed': 2525}
#Bereiten Sie Variablen vor, um den Lernprozess zu erhalten
evals_result = {}
reg = xgb.train(#Verwenden Sie die oben festgelegten Lernparameter
params=xgb_params,
dtrain=dtrain,
#Anzahl der Lernrunden
num_boost_round=50000,
#Anzahl der Runden des frühen Stopps u
early_stopping_rounds=15,
#Überprüfungsdaten
evals=[(dtrain, 'train'), (dtest, 'eval')],
#Stellen Sie die oben vorbereiteten Variablen ein
evals_result=evals_result)
#[1] train-rmse:19.5646 eval-rmse:19.7128
#[2] train-rmse:17.7365 eval-rmse:17.9048
#[3] train-rmse:16.0894 eval-rmse:16.2733
#Kürzung
#[93] train-rmse:0.368592 eval-rmse:2.47429
#[94] train-rmse:0.3632 eval-rmse:2.47945
#[95] train-rmse:0.356932 eval-rmse:2.48028
#Stopping. Best iteration:
#[80] train-rmse:0.474086 eval-rmse:2.46597
predY = reg.predict(dtest)
print(mean_squared_error(testY, predY))
#6.151798278561384
Der während des Lernprozesses angezeigte Verlust ist genau der gleiche wie in Methode 1. Wenn Sie jedoch danach MSE vorhersagen und ausgeben, ist der Wert anders ... Ich kenne die Ursache nicht, daher werde ich sie weitergeben. Wie Sie beim Vergleich der Codes sehen können, unterscheiden sich die Namen der Parameter und die Stellen, an denen sie geschrieben sind, geringfügig. Seien Sie also vorsichtig. Wenn beispielsweise die Lernrate eta wie in Methode 1 als Lernrate festgelegt ist, kann sie ausgeführt werden, der Wert wird jedoch nicht wiedergegeben. Über diesen Parameter XGBoost Parameters Wann XGBoost Python API-Referenz Schauen Sie sich die ** Lern-API ** an.
Da der Wert in ** evals_result ** gespeichert ist, das zum Zeitpunkt des Lernens erstellt wurde, wird der Übergang damit grafisch dargestellt.
plot_validation1.py
#Zeichnen Sie den Verlustübergang für Zugdaten
plt.plot(evals_result['validation_0']['rmse'], label='train rmse')
#Plotverlustübergang für Testdaten
plt.plot(evals_result['validation_1']['rmse'], label='eval rmse')
plt.grid()
plt.legend()
plt.xlabel('rounds')
plt.ylabel('rmse')
plt.show()
Aus irgendeinem Grund unterscheidet sich der Name in evals_result von dem in Methode 1.
plot_validation2.py
#Zeichnen Sie den Verlustübergang für Zugdaten
plt.plot(evals_result['train']['rmse'], label='train rmse')
#Plotverlustübergang für Testdaten
plt.plot(evals_result['eval']['rmse'], label='eval rmse')
plt.grid()
plt.legend()
plt.xlabel('rounds')
plt.ylabel('rmse')
plt.savefig("img.png ", bbox_inches='tight')
plt.show()
xgboost verfügt über eine Methode namens ** xgb.plot_importance () **, die FeatureImportance darstellt, die in beiden Methoden 1 und 2 verwendet werden kann.
plot_importance.py
xgb.plot_importance(reg)
Sie können auch important_type als Argument angeben. API Beschreibung und Wichtigkeitstyp Wenn Sie auf [diesen Artikel] verweisen (https://qiita.com/hand10ryo/items/ed1e511b5236f7bfe606)
Sie können drei davon verwenden. (Es scheint, dass Sie anstelle des Durchschnittswerts zum Lesen der API auch den Gesamtwert für Gewinn und Deckung verwenden können.) Der Anfangswert scheint Gewicht zu sein. Wenn Sie beispielsweise die Verstärkung angeben und ausgeben, sieht dies wie folgt aus.
plot_importance.py
xgb.plot_importance(reg,importance_type='gain')
Es gibt auch eine Methode namens ** xgb.get_score () **, mit der Sie die im Diagramm verwendeten Werte als Wörterbuch abrufen können. Diese Methode ist jedoch nur in Methode 2 ** verfügbar, und ich bin mir nicht sicher, ob es in Methode 1 eine Möglichkeit gibt, etwas Ähnliches zu tun ... Ich mache mir Sorgen über die Inkonsistenzen hier.
print_importance.py
print(reg.get_score(importance_type='weight'))
#{'LSTAT': 251,
# 'RM': 363,
# 'CRIM': 555,
# 'DIS': 295,
# 'B': 204,
# 'INDUS': 81,
# 'NOX': 153,
# 'AGE': 290,
# 'PTRATIO': 91,
# 'RAD': 41,
# 'ZN': 36,
# 'TAX': 91,
# 'CHAS': 13}
print(reg.get_score(importance_type='gain'))
#{'LSTAT': 345.9503342748026,
# 'RM': 67.2338906183525,
# 'CRIM': 9.066383988597524,
# 'DIS': 20.52948739887609,
# 'B': 5.704856272869067,
# 'INDUS': 6.271976581219753,
# 'NOX': 17.48982672038596,
# 'AGE': 3.396609941187381,
# 'PTRATIO': 15.018738197646142,
# 'RAD': 5.182013825021951,
# 'ZN': 2.7426182845938896,
# 'TAX': 12.025571026275834,
# 'CHAS': 1.172155851074923}
Ich denke, dass feature_names beim Erstellen der DMatrix angegeben wurde, aber wenn Sie es nicht angeben, wird der Name des Feature-Betrags nicht in der Grafik usw. angezeigt, so dass es sehr schwer zu verstehen ist. Es ist gut, ihn festzulegen.
Ich denke, der bequemste Punkt von Methode 1 ist, dass die Parametersuche mit GridSerchCV von sklearn möglich ist. Soweit ich dies überprüft habe, wurde Methode 1 in allen Artikeln verwendet, die XGBoost für die Parametersuche verwendeten. Der Code des Lebenslaufs für die zufällige Suche wird als Referenz angegeben.
randomized_search.py
from sklearn.model_selection import RandomizedSearchCV
params = {
'n_estimators':[50000],
'objective':['reg:squarederror'],
'eval_metric': ['rmse'],
'booster': ['gbtree'],
'learning_rate':[0.1,0.05,0.01],
'max_depth':[5,7,10,15],
'random_state':[2525]
}
mod = xgb.XGBRegressor()
#n_Iter hat eine zufällige Suchanzahl
rds = RandomizedSearchCV(mod,params,random_state=2525,scoring='r2',n_jobs=1,n_iter=50)
rds.fit(trainX,
trainY,
eval_metric='rmse',
early_stopping_rounds=15,
eval_set=[(testX, testY)])
print(rds.best_params_)
#{'seed': 2525,
# 'objective': 'reg:squarederror',
# 'n_estimators': 50000,
# 'max_depth': 5,
# 'learning_rate': 0.1,
# 'eval_metric': 'rmse',
# 'booster': 'gbtree'}
Um ehrlich zu sein, bin ich der Meinung, dass die ursprüngliche API nicht bekannt ist und Sie sich nicht die Mühe machen müssen, sie zu verwenden. Es kann jedoch auch andere solche Beispiele geben, da einige Methoden nur mit dieser Methode oben verwendet werden können. Wird das Basic nach Methode 1 implementiert? Ich denke, es wäre besser, dieses hier zu implementieren, wenn Sie dies nicht tun können.
Dieses Mal habe ich bei der Untersuchung von XGBoost die unklaren Punkte aufgrund der Methodenmischung so einfach wie möglich zusammengefasst. Ich hoffe, dass jemand in einer ähnlichen Situation hierher kommt und das Problem löst. Es gibt viele andere nützliche Methoden in der xgboost-Bibliothek, z. B. eine Methode, mit der der generierte Baum als Diagramm angezeigt werden kann. Es wird daher empfohlen, einen kurzen Blick auf die API zu werfen und sie auf verschiedene Arten zu implementieren. Dies ist der erste Qiita-Artikel in meinem Leben, und ich denke, es ist nicht genug, aber danke, dass Sie so weit gelesen haben.
Python: Versuchen Sie es mit XGBoost Verwendung von xgboost: Klassifizierung mehrerer Klassen nach Irisdaten Verwenden von XGBoost mit Python Xgboost: Berechnen des Wichtigkeitstyps von feature_importance xgboost: Effektives Modell für maschinelles Lernen für Tabellendaten
Recommended Posts