XGBoost预测方法对所有行返回相同的预测值。

13
我已经在Python中创建了一个xgboost分类器:
train是一个带有100k行和50个列的pandas数据框,target是一个pandas系列。
xgb_classifier = xgb.XGBClassifier(nthread=-1, max_depth=3, silent=0, 
                                   objective='reg:linear', n_estimators=100)
xgb_classifier = xgb_classifier.fit(train, target)

predictions = xgb_classifier.predict(test)

然而,在训练后,当我使用这个分类器来预测值时,整个结果数组都是相同的数字。你有什么想法为什么会发生这种情况?

数据澄清: 大约50个数值特征和一个数值目标

我也尝试过使用sklearn中的RandomForestRegressor来处理相同的数据,它确实给出了真实的预测结果。也许这是xgboost实现中的一个合法bug?


你的数据是什么样子的?模型返回的“相同数字”是什么? - o-90
类似于 -0.1236788 的结果在预期范围内,但不同的行应该有不同的预测值,并且这个数字填满了整个预测数组,大约有1000行。 - mistakeNot
你能分享一下调用训练函数和填充训练矩阵的代码吗?训练集中有正面和负面的例子吗? - Andre Holzner
我已经添加了代码。是的,训练集中有正值和负值。 - mistakeNot
9个回答

6
这个问题得到了多个回答,包括这里以及这里这里
我在使用XGBoost和LGBM时遇到了类似的问题。对我来说,解决方法是增加训练数据集的大小。
我本地机器上的训练使用了一个大型稀疏数据集(200,000行和7000列)的随机样本(约0.5%),因为我的机器的内存不足以运行算法。结果证明,对于我而言,预测值数组只是目标变量平均值的数组。这表明模型可能欠拟合。解决欠拟合模型的一种方法是在更多数据上训练模型,所以我尝试在一台具有更大内存的机器上进行分析,问题得到了解决:我的预测数组不再是目标值的平均值数组。另一方面,问题也可能仅仅是我查看的切片的预测值是从训练数据中预测出来的,而这些数据很少(例如0和nan)。对于信息很少的训练数据,预测目标特征的平均值似乎是合理的。
我遇到的其他建议解决方案都没有帮助我。总结一些建议的解决方案包括: 1)检查gamma是否过高 2)确保您的目标标签未包含在训练数据集中 3)max_depth可能太小。

1
在我的情况下,变量y中有一个空值;我只是使用了.fillna(0),然后它就起作用了@Blane - Alessandro Ceccarelli

3

其中一个原因是您通过参数gamma提供了高惩罚。比较您的训练响应变量的平均值,并检查预测是否接近此值。如果是,则模型在预测上限制过多,以使train-rmse和val-rmse尽可能接近。当gamma值较高时,您的预测最简单。因此,您将获得最简单的模型预测,例如将训练集的平均值或naive预测作为预测。


1
尝试在XGBoost中显著增加min_child_weight或在LightGBM中增加min_data_in_leaf
min_data_in_leaf    oof_rmse
20000               0.052998
2000                0.053001
200                 0.053002
20                  0.053015
2                   0.054261

实际上,这可能是过度拟合伪装成欠拟合的情况。例如,在保险索赔频率模型的零膨胀目标的情况下会发生这种情况。一种解决方案是通过增加控制最小叶子大小的超参数来增加每个树叶中罕见目标级别(例如非零保险索赔)的表示/覆盖范围,将其增加到一些相当大的值,如上面的示例所指定的那样。

这是一个很好的线索;但事实上,对我来说,减少min_child_weight才能防止过拟合(类平均化?)... 实际上预测仍然糟糕,但至少现在它正在预测不同的值! - RichardBJ

0

您需要为任何真正的调查提供可重复的示例。很可能您的响应目标高度不平衡,您的训练数据并不是非常具有预测性,因此您总是(或几乎总是)得到一个类别的预测结果。您是否已经查看了预测概率以查看是否存在任何差异?这只是分类标签未使用正确截断的问题吗?

由于您说RF给出了合理的预测结果,因此查看该参数的培训参数将很有用。乍一看,您在xgboost调用中使用回归目标函数是值得注意的,这很可能是您看到如此糟糕的表现的原因。尝试将您的目标更改为:'binary:logistic'


0

max_depth=3太小了,试着把它调大一点,如果我没记错的话,默认值是7。将silent设置为1,这样你就可以监控每个时期的错误了。


0
你应该检查一下你的目标中是否存在inf值。

0

我刚遇到这个问题并成功解决了。问题是我在训练时使用了tree_method='gpu_hist',导致所有预测结果都相同。如果我将tree_method='auto'设置为正常工作,但运行时间更长。然后,如果我将tree_method='gpu_hist'base_score=0一起设置,它就可以正常工作了。我认为base_score应该是您预测变量的平均值左右。


-2

可能是您使用的超参数导致了错误。尝试使用默认值。在我的情况下,通过从参数中删除subsamplemin_child_weight超参数来解决了这个问题。


-2

我尝试了这个页面上的所有解决方案,但都没有起作用。

当我对时间序列进行分组时,某些频率会在数据中创建间隙。 我通过填充所有NaN来解决了这个问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接