我是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]. 。我在这里做错了什么?

有帮助吗?

解决方案

XGBoost似乎使用 回归树 作为基础学习者默认情况下。 XGBoost(或一般梯度提高)通过组合这些基础学习者的多个来工作。回归树不能推断训练数据中的模式,因此在您的情况下,将无法正确预测3或以下1的任何输入。您的模型经过训练以预测间隔的输入的输出 [1,3], ,高于3的输入将获得与3相同的输出,而输入小于1的输入将获得与1相同的输出。

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

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

您可以通过添加XGBoost模型的基础学习者将其更改为GLM(广义线性模型) "booster":"gblinear" 到您的模型 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.xgb.xgbclassifier类,因为它们遵循 Sci-kit学习 API。而且,由于Sci-kit Learn具有如此多的机器学习算法实现,因此使用XGB作为附加库仅在使用XGBOOST的SCI-KIT接口时不会干扰我的工作流程。

许可以下: CC-BY-SA归因
scroll top