Sembra che XGBoost utilizzi gli alberi di regressione come apprendenti di base per impostazione predefinita. XGBoost (o incremento gradiente in generale) funziona combinando più di questi studenti di base. Gli alberi di regressione non possono estrapolare i modelli nei dati di allenamento, quindi qualsiasi input superiore a 3 o inferiore a 1 non verrà previsto correttamente nel tuo caso. Il modello è stato addestrato per prevedere le uscite per gli ingressi nell'intervallo [1,3]
, a un ingresso superiore a 3 verrà assegnato lo stesso output di 3 e a un input inferiore a 1 verrà assegnato lo stesso output di 1.
Inoltre, gli alberi di regressione non vedono realmente i tuoi dati come una linea retta in quanto sono modelli non parametrici, il che significa che possono teoricamente adattarsi a qualsiasi forma che sia più complicata di una linea retta. All'incirca, un albero di regressione funziona assegnando i nuovi dati di input ad alcuni dei punti di dati di allenamento che ha visto durante l'allenamento e produce l'output in base a quello.
Questo è in contrasto con i regressori parametrici (come la regressione lineare ) che in realtà cercano i migliori parametri di un iperpiano (linea retta nel tuo caso) per adattarsi ai tuoi dati. La regressione lineare fa vedere i dati come una linea retta con una pendenza e un'intercettazione.
Puoi cambiare lo studente di base del tuo modello XGBoost in un GLM (modello lineare generalizzato) aggiungendo "booster":"gblinear"
al tuo modello 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
In generale, per eseguire il debug del motivo per cui il tuo modello XGBoost si sta comportando in un modo particolare, vedi i parametri del modello:
gbm.get_dump()
Se lo studente di base è un modello lineare, l'output get_dump è:
['bias:\n4.49469\nweight:\n7.85942\n']
Nel tuo codice sopra, dal momento che gli studenti della base degli alberi, l'output sarà:
['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']
Suggerimento: in realtà preferisco usare le classi xgb.XGBRegressor o xgb.XGBClassifier, poiché seguono l' API di apprendimento sci-kit . E poiché sci-kit learn ha così tante implementazioni di algoritmi di machine learning, l'uso di XGB come libreria aggiuntiva non disturba il mio flusso di lavoro solo quando utilizzo l'interfaccia di sci-kit di XGBoost.