Pregunta

Soy un novato para xgboost, así que perdón mi ignorancia. Aquí está el código de 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

La salida es:

[ 24.126194  24.126194]

Como puede ver, los datos de entrada son simplemente una línea recta. Entonces la salida que espero es [40,50]. ¿Qué estoy haciendo mal aquí?

¿Fue útil?

Solución

Parece que xgboost usa árboles de regresión como aprendices base por defecto. El trabajo XGBOOST (o el impulso de gradiente en general) combinando múltiples de estos alumnos de base. Los árboles de regresión no pueden extrapolar los patrones en los datos de entrenamiento, por lo que cualquier entrada superior a 3 o inferior a 1 no se predecirá correctamente en su caso. Su modelo está entrenado para predecir salidas para entradas en el intervalo [1,3], una entrada superior a 3 tendrá la misma salida que 3, y una entrada inferior a 1 tendrá la misma salida que 1.

Además, los árboles de regresión realmente no ven sus datos como un línea recta Como son modelos no paramétricos, lo que significa que teóricamente pueden ajustar cualquier forma que sea más complicada que una línea recta. Aproximadamente, un árbol de regresión funciona asignando sus nuevos datos de entrada a algunos de los puntos de datos de entrenamiento que ha visto durante el entrenamiento y produce la salida en función de eso.

Esto contrasta con los regresores paramétricos (como regresión lineal) que realmente buscan los mejores parámetros de un hiperplano (línea recta en su caso) para adaptarse a sus datos. Regresión lineal lo hace Vea sus datos como una línea recta con una pendiente y una intersección.

Puede cambiar el alumno base de su modelo xgboost a un GLM (modelo lineal generalizado) agregando "booster":"gblinear" a tu modelo 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

En general, para depurar por qué su modelo XGBOost se está comportando de una manera particular, consulte los parámetros del modelo:

gbm.get_dump()

Si su alumno base es un modelo lineal, la salida get_dump es:

['bias:\n4.49469\nweight:\n7.85942\n']

En su código anterior, desde los alumnos de la base de árboles, la salida será:

['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']

Consejo: en realidad prefiero usar clases xgb.xgbregresor o xgb.xgbcclassifier, ya que siguen el Sci-kit Learn API. Y debido a que Sci-kit Learn tiene tantas implementaciones de algoritmo de aprendizaje automático, usar XGB como biblioteca adicional no perturbe mi flujo de trabajo solo cuando uso la interfaz Sci-kit de XGBOOST.

Licenciado bajo: CC-BY-SA con atribución
scroll top