Es scheint, dass XGBoost standardmäßig Regressionsbäume als Basislerner verwendet . XGBoost (oder Gradient Boosting im Allgemeinen) funktioniert, indem mehrere dieser Basislerner kombiniert werden. Regressionsbäume können die Muster in den Trainingsdaten nicht extrapolieren, sodass Eingaben über 3 oder unter 1 in Ihrem Fall nicht korrekt vorhergesagt werden. Ihr Modell ist darauf trainiert, Ausgaben für Eingaben im Intervall vorherzusagen. [1,3]
Eine Eingabe über 3 erhält dieselbe Ausgabe wie 3 und eine Eingabe unter 1 erhält dieselbe Ausgabe wie 1.
Darüber hinaus sehen Regressionsbäume Ihre Daten nicht wirklich als gerade Linie, da es sich um nicht parametrische Modelle handelt. Dies bedeutet, dass sie theoretisch an jede Form angepasst werden können, die komplizierter als eine gerade Linie ist. In etwa funktioniert ein Regressionsbaum, indem Sie Ihre neuen Eingabedaten einigen der Trainingsdatenpunkte zuweisen, die er während des Trainings gesehen hat, und die Ausgabe basierend darauf erstellen.
Dies steht im Gegensatz zu parametrischen Regressoren (wie der linearen Regression ), die tatsächlich nach den besten Parametern einer Hyperebene (in Ihrem Fall gerade Linie) suchen, um Ihren Daten zu entsprechen. Die lineare Regression tut Ihre Daten als eine gerade Linie mit einer Steigung und einem Schnitt sehen.
Sie können den Basislerner Ihres XGBoost-Modells in ein GLM (Generalized Linear Model) ändern, indem Sie "booster":"gblinear"
Ihrem Modell Folgendes hinzufügen params
:
import pandas as pd
import xgboost as xgb
df = pd.DataFrame({'x':[1,2,3], 'y':[10,20,30]})
X_train = df.drop('y',axis=1)
Y_train = df['y']
T_train_xgb = xgb.DMatrix(X_train, Y_train)
params = {"objective": "reg:linear", "booster":"gblinear"}
gbm = xgb.train(dtrain=T_train_xgb,params=params)
Y_pred = gbm.predict(xgb.DMatrix(pd.DataFrame({'x':[4,5]})))
print Y_pred
Um zu debuggen, warum sich Ihr XGBoost-Modell auf bestimmte Weise verhält, lesen Sie im Allgemeinen die Modellparameter:
gbm.get_dump()
Wenn Ihr Basislerner ein lineares Modell ist, lautet die Ausgabe von get_dump:
['bias:\n4.49469\nweight:\n7.85942\n']
In Ihrem obigen Code lautet die Ausgabe, da Sie Lernende auf Baumbasis sind:
['0:[x<3] yes=1,no=2,missing=1\n\t1:[x<2] yes=3,no=4,missing=3\n\t\t3:leaf=2.85\n\t\t4:leaf=5.85\n\t2:leaf=8.85\n',
'0:[x<3] yes=1,no=2,missing=1\n\t1:[x<2] yes=3,no=4,missing=3\n\t\t3:leaf=1.995\n\t\t4:leaf=4.095\n\t2:leaf=6.195\n',
'0:[x<3] yes=1,no=2,missing=1\n\t1:[x<2] yes=3,no=4,missing=3\n\t\t3:leaf=1.3965\n\t\t4:leaf=2.8665\n\t2:leaf=4.3365\n',
'0:[x<3] yes=1,no=2,missing=1\n\t1:[x<2] yes=3,no=4,missing=3\n\t\t3:leaf=0.97755\n\t\t4:leaf=2.00655\n\t2:leaf=3.03555\n',
'0:[x<3] yes=1,no=2,missing=1\n\t1:[x<2] yes=3,no=4,missing=3\n\t\t3:leaf=0.684285\n\t\t4:leaf=1.40458\n\t2:leaf=2.12489\n',
'0:[x<3] yes=1,no=2,missing=1\n\t1:[x<2] yes=3,no=4,missing=3\n\t\t3:leaf=0.478999\n\t\t4:leaf=0.983209\n\t2:leaf=1.48742\n',
'0:[x<3] yes=1,no=2,missing=1\n\t1:[x<2] yes=3,no=4,missing=3\n\t\t3:leaf=0.3353\n\t\t4:leaf=0.688247\n\t2:leaf=1.04119\n',
'0:[x<3] yes=1,no=2,missing=1\n\t1:[x<2] yes=3,no=4,missing=3\n\t\t3:leaf=0.23471\n\t\t4:leaf=0.481773\n\t2:leaf=0.728836\n',
'0:[x<3] yes=1,no=2,missing=1\n\t1:[x<2] yes=3,no=4,missing=3\n\t\t3:leaf=0.164297\n\t\t4:leaf=0.337241\n\t2:leaf=0.510185\n',
'0:[x<2] yes=1,no=2,missing=1\n\t1:leaf=0.115008\n\t2:[x<3] yes=3,no=4,missing=3\n\t\t3:leaf=0.236069\n\t\t4:leaf=0.357129\n']
Tipp: Ich bevorzuge eigentlich die Klassen xgb.XGBRegressor oder xgb.XGBClassifier, da sie der Sci-Kit- Lern - API folgen . Und da Sci-Kit Learn so viele Implementierungen von Algorithmen für maschinelles Lernen enthält, stört die Verwendung von XGB als zusätzliche Bibliothek meinen Workflow nicht nur, wenn ich die Sci-Kit-Oberfläche von XGBoost verwende.