Uscita della regressione lineare XGBoost errata


10

Sono un principiante di XGBoost, quindi scusate la mia ignoranza. Ecco il codice Python:

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"}
gbm = xgb.train(dtrain=T_train_xgb,params=params)
Y_pred = gbm.predict(xgb.DMatrix(pd.DataFrame({'x':[4,5]})))
print Y_pred

L'output è:

[ 24.126194  24.126194]

Come puoi vedere, i dati di input sono semplicemente una linea retta. Quindi l'output che mi aspetto è [40,50]. Cosa sto facendo di sbagliato qui?


1
Per favore, non fare il cross-post
Dawny33

2
@ Dawny33 cancellato da SO.
simplfuzz,

Risposte:


21

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.


Come si imposta "booster":"gblinear"tramitexgb.XGBRegressor
yosemite_k il

È meglio eseguire la normalizzazione delle funzioni quando si utilizza gblinearBooster?
Pepato il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.