XGBoost est une méthode de GBDT et peut être implémentée en python. Cependant, lorsque j'ai examiné les exemples d'implémentation, j'étais confus car il y avait plusieurs façons de les décrire même s'ils utilisaient la même bibliothèque. Par conséquent, le but de cet article est d'essayer la même chose dans chaque notation avec la signification mémorable de l'auteur. (Veuillez noter que l'explication détaillée de XGBoost sera omise.)
pip install xgboost
import_boston_datasets.py
#Importez d'abord la bibliothèque à utiliser cette fois
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)
#Attachez la variable objectif à la fin de la trame de données en tant que prix pour les afficher tous ensemble.
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
#Divisez les données en fonction x et variable objectif y
x = df_boston.loc[:,'CRIM':'LSTAT']
y = df_boston['PRICE']
#7:Divisé en données de train et données de test à 3
trainX, testX, trainY, testY = train_test_split(x, y, test_size=0.3)
#Essayez de sortir chaque forme
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,)
La méthode 1 est une méthode utilisant une interface avec ** l'API compatible scikit-learn **. Je vais le décrire à partir d'ici, que vous connaissez peut-être. Tout d'abord, de l'implémentation la plus simple sans spécifier de paramètres.
regression1-1.py
#Utilisez XGB Regressor car il s'agit d'une régression
reg = xgb.XGBRegressor()
#eval_Définir les données de vérification dans l'ensemble
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
#réduction
#[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
#Exécution prédictive
predY = reg.predict(testX)
#Affichage de MSE
print(mean_squared_error(testY, predY))
#7.4163707577050655
Si vous spécifiez les paramètres un peu plus correctement, ce sera comme suit.
regression1-2.py
reg = xgb.XGBRegressor(#Spécification de la fonction objectif La valeur initiale est également l'erreur carrée
objective='reg:squarederror',
#Nombre de cycles d'apprentissage tôt_Puisque l'arrêt est utilisé, spécifiez plus
n_estimators=50000,
#Quoi utiliser pour booster La valeur initiale est également gbtree
booster='gbtree',
#Taux d'apprentissage
learning_rate=0.01,
#Profondeur maximale de l'arbre
max_depth=6,
#Valeur de la graine
random_state=2525)
#Préparer des variables pour afficher le processus d'apprentissage
evals_result = {}
reg.fit(trainX, trainY,
eval_set=[(trainX, trainY),(testX, testY)],
#Index d'évaluation utilisé pour l'apprentissage
eval_metric='rmse',
#Spécifiez le nombre de tours pour arrêter l'apprentissage lorsque la fonction objectif ne s'améliore pas
early_stopping_rounds=15,
#Utilisez l'API de rappel pour enregistrer le processus d'apprentissage et spécifier les variables ci-dessus
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
#réduction
#[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
La perte s'est un peu améliorée par rapport au moment où rien n'était précisé. Il existe d'autres paramètres qui peuvent être spécifiés, mais pour plus de détails Référence de l'API Python XGBoost Voir ** API Scikit-Learn ** dans.
Cependant, il existe des paramètres qui ne sont pas écrits dans cette API, ce qui est souvent déroutant. Par exemple, si vous sortez le modèle alors que rien n'est spécifié
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)
Vous pouvez vérifier la valeur initiale du modèle comme ceci. Mais au fond
silent=None
Même si vous vérifiez avec l'API, un tel paramètre n'existe pas en premier lieu. Certains sites le décrivent comme un paramètre de présence ou d'absence de sortie lors de la formation, mais même s'il a été spécifié, rien n'a changé.
Vient ensuite la deuxième méthode. Il s'agit de l '** API d'origine ** de la bibliothèque xgboost. Par conséquent, il existe une légère différence dans la gestion des ensembles de données.
regression2-1.py
#xgb.Rendez-le utilisable dans l'API d'origine de DMatrix
#feature_Vous n'êtes pas obligé de spécifier des noms, mais vous pouvez les ajouter en toute sécurité car cela sera pratique plus tard.
dtrain = xgb.DMatrix(trainX, label=trainY, feature_names = x.columns)
dtest = xgb.DMatrix(testX, label=testY, feature_names = x.columns)
reg = xgb.train(#Spécifiez une liste vide car l'entraînement est effectué avec la valeur initiale sans spécifier intentionnellement de paramètres
params=[],
dtrain=dtrain,
#Définir les données de vérification dans eval
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
Vous pouvez voir que le nombre de cycles d'apprentissage est défini pour être assez petit par défaut. Ce n'est pas un meilleur résultat que la méthode 1. Définissons les paramètres de la même manière et exécutons-le.
regression2-2.py
#xgb.Rendez-le utilisable dans l'API d'origine de DMatrix
dtrain = xgb.DMatrix(trainX, label=trainY, feature_names = x.columns)
dtest = xgb.DMatrix(testX, label=testY, feature_names = x.columns)
#XGB d'abord_Définissez les paramètres en tant que paramètres
xgb_params = {#Fonction objective
'objective': 'reg:squarederror',
#Index d'évaluation utilisé pour l'apprentissage
'eval_metric': 'rmse',
#Quoi utiliser pour booster
'booster': 'gbtree',
#learning_Synonyme de taux
'eta': 0.1,
#Profondeur maximale de l'arbre
'max_depth': 6,
#random_Synonyme d'état
'seed': 2525}
#Préparez des variables pour obtenir le processus d'apprentissage
evals_result = {}
reg = xgb.train(#Utilisez les paramètres d'apprentissage définis ci-dessus
params=xgb_params,
dtrain=dtrain,
#Nombre de cycles d'apprentissage
num_boost_round=50000,
#Nombre de tours d'arrêt anticipé u
early_stopping_rounds=15,
#Données de vérification
evals=[(dtrain, 'train'), (dtest, 'eval')],
#Définissez les variables préparées ci-dessus
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
#réduction
#[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
La perte affichée pendant le processus d'apprentissage est exactement la même que dans la méthode 1. Cependant, si vous prédisez et sortez MSE après cela, la valeur sera différente ... Je ne connais pas la cause, donc je vais la transmettre. Comme vous pouvez le voir en comparant les codes, les noms des paramètres et les endroits où ils sont écrits sont légèrement différents, alors soyez prudent. Par exemple, si le taux d'apprentissage eta est défini comme learning_rate comme dans la méthode 1, il peut être exécuté mais la valeur n'est pas reflétée. À propos de ce paramètre XGBoost Parameters Quand Référence de l'API Python XGBoost Découvrez l '** API d'apprentissage **.
Puisque la valeur est stockée dans ** evals_result ** préparé au moment de l'apprentissage, la transition est représentée graphiquement en l'utilisant.
plot_validation1.py
#tracer la transition de perte pour les données de train
plt.plot(evals_result['validation_0']['rmse'], label='train rmse')
#tracer la transition de perte pour les données de test
plt.plot(evals_result['validation_1']['rmse'], label='eval rmse')
plt.grid()
plt.legend()
plt.xlabel('rounds')
plt.ylabel('rmse')
plt.show()
Pour une raison quelconque, le nom stocké dans evals_result est différent de celui de la méthode 1.
plot_validation2.py
#tracer la transition de perte pour les données de train
plt.plot(evals_result['train']['rmse'], label='train rmse')
#tracer la transition de perte pour les données de test
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 a une méthode appelée ** xgb.plot_importance () ** qui trace FeatureImportance, qui peut être utilisée dans les deux méthodes 1 et 2.
plot_importance.py
xgb.plot_importance(reg)
Vous pouvez également spécifier importance_type comme argument. API description et importance_type Si vous vous référez à cet article
Vous pouvez en utiliser trois (il semble que vous puissiez également utiliser la valeur totale du gain et de la couverture au lieu de la valeur moyenne pour lire l'API) La valeur initiale semble être le poids, par exemple, si vous spécifiez le gain et le sortez, ce sera comme suit.
plot_importance.py
xgb.plot_importance(reg,importance_type='gain')
Il existe également une méthode appelée ** xgb.get_score () **, qui vous permet d'obtenir les valeurs utilisées dans le graphique sous forme de dictionnaire. Cependant, cette méthode n'est disponible que dans la méthode 2 **, et je ne suis pas sûr qu'il existe un moyen de faire quelque chose de similaire dans la méthode 1 ... Je m'inquiète des incohérences ici.
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}
Je pense que feature_names a été spécifié lors de la création de DMatrix, mais si vous ne le spécifiez pas, le nom du montant de la fonctionnalité ne sera pas affiché sur le graphique etc., donc ce sera très difficile à comprendre. Il est bon de le définir.
Je pense que le point le plus pratique de la méthode 1 est que la recherche de paramètres est possible en utilisant GridSerchCV de sklearn. Autant que j'ai vérifié, la méthode 1 a été utilisée dans tous les articles utilisant XGBoost pour la recherche de paramètres. Le code du CV de recherche aléatoire est affiché pour référence.
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 a un nombre de recherche aléatoire
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'}
Pour être honnête, je pense que l'API d'origine n'est pas familière et que vous n'avez pas à vous soucier de l'utiliser. Cependant, il peut y avoir d'autres exemples de ce type, car certaines méthodes ne peuvent être utilisées qu'avec la méthode ci-dessus. Le basique est-il implémenté par la méthode 1? Je pense qu'il serait préférable de mettre en œuvre celui-ci ici si vous ne pouvez pas le faire.
Cette fois, en étudiant XGBoost, j'ai résumé aussi facilement que possible les points peu clairs dus au mélange de méthodes. J'espère que quelqu'un dans une situation similaire arrivera ici et résoudra le problème. Il existe de nombreuses autres méthodes utiles dans la bibliothèque xgboost, comme une méthode qui peut afficher l'arborescence générée sous forme de diagramme, il est donc recommandé de jeter un coup d'œil rapide à l'API et de l'implémenter de différentes manières. C'est le premier article de Qiita de ma vie, et je pense que ce n'est pas suffisant, mais merci d'avoir lu jusqu'ici.
Python: essayez d'utiliser XGBoost Comment utiliser xgboost: classification multi-classes par données d'iris Utilisation de XGBoost avec Python Xgboost: Comment calculer importance_type de feature_importance xgboost: modèle d'apprentissage automatique efficace pour les données de table
Recommended Posts