XGBoost线性回归输出不正确


10

我是XGBoost的新手,请原谅我的无知。这是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

输出为:

[ 24.126194  24.126194]

如您所见,输入数据只是一条直线。所以我期望的输出是[40,50]。我在这里做错了什么?


1
请不要交叉发布
Dawny33

2
@ Dawny33已从SO中删除。
simplfuzz 2015年

Answers:


21

似乎XGBoost默认使用回归树作为基础学习者。XGBoost(或通常称为Gradient boosting)通过将这些基础学习器中的多个组合在一起来工作。回归树无法推断训练数据中的模式,因此在您的情况下,任何高于3或低于1的输入都将无法正确预测。您的模型经过训练,可以预测间隔内输入的输出,[1,3]大于3的输入将与3给出相同的输出,小于1的输入将得到与1相同的输出。

此外,回归树实际上是非参数模型,因此它们并不会真正将您的数据视为直线,这意味着它们在理论上可以拟合比直线更复杂的任何形状。粗略地讲,回归树的工作原理是将新的输入数据分配给它在训练过程中看到的一些训练数据点,并基于此生成输出。

这与参数回归(例如线性回归)相反,后者实际上会寻找超平面的最佳参数(在您的情况下为直线)以适合您的数据。线性回归确实会将您的数据视为具有斜率和截距的直线。

您可以通过将XGBoost模型的基础学习者添加"booster":"gblinear"到模型中,将其更改为GLM(通用​​线性模型)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

通常,要调试XGBoost模型为何以特定方式运行,请参阅模型参数:

gbm.get_dump()

如果您的基础学习者是线性模型,则get_dump输出为:

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

在上面的代码中,由于您是树型学习者,因此输出为:

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

提示:实际上,我实际上更喜欢使用xgb.XGBRegressor或xgb.XGBClassifier类,因为它们遵循sci-kit学习 API。而且由于sci-kit learning具有许多机器学习算法实现,因此仅当我使用XGBoost的sci-kit接口时,将XGB用作附加库不会干扰我的工作流程。


如何设置"booster":"gblinear"通过xgb.XGBRegressor
yosemite_k

使用gblinearbooster 时运行功能规范化更好吗?
胡椒
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.