XGBoost的质量如何计算?

14

请问有人可以解释一下xgboost R包中xgb.model.dt.tree函数中的Quality列是如何计算的吗?根据文档,Quality是“与此特定节点拆分相关的增益”。

当你运行以下代码时(该代码在xgboost文档中提供),树0的节点0的Quality为4000.53,但我计算的Gain为2002.848。

data(agaricus.train, package='xgboost')

train <- agarics.train

X = train$data
y = train$label

bst <- xgboost(data = train$data, label = train$label, max.depth = 2,
               eta = 1, nthread = 2, nround = 2,objective = "binary:logistic")

xgb.model.dt.tree(agaricus.train$data@Dimnames[[2]], model = bst)

p = rep(0.5,nrow(X))

L = which(X[,'odor=none']==0)
R = which(X[,'odor=none']==1)

pL = p[L]
pR = p[R]

yL = y[L]
yR = y[R]

GL = sum(pL-yL)
GR = sum(pR-yR)
G = sum(p-y)

HL = sum(pL*(1-pL))
HR = sum(pR*(1-pR))
H = sum(p*(1-p))

gain = 0.5 * (GL^2/HL+GR^2/HR-G^2/H)

gain

我了解到增益是由以下公式给出的:

gain formula

由于我们使用对数损失,因此G是p-y的总和,H是p(1-p)的总和 - 在这种情况下,gamma和lambda都为零。

有人能找出我哪里错了吗?

1个回答

10

好的,我想我已经弄清楚了。在文档中给出的默认情况下,reg_lambda 的值不是0,而是1(来自param.h)。

输入图像描述

此外,在计算增益时似乎没有应用一半的因素,因此Quality列是您预期的两倍。最后,我也认为此计算并未应用gamma(也称为min_split_loss)(来自update_hitmaker-inl.hpp)。

输入图像描述

相反,gamma用于确定是否调用修剪,但不反映在增益计算本身中,正如文档所示。

输入图像描述

如果您应用这些更改,您确实会得到4000.53作为树0节点0的Quality,就像原始问题中一样。我将将此作为问题提出给xgboost团队,以便相应更改文档。


这个问题一直困扰着我,但我会继续努力解决它。你应该看看这个问题,因为你似乎正在深入学习xgboost。这个问题已经困扰我一段时间了。https://dev59.com/f1wY5IYBdhLWcg3wJk8q - T. Scharf
我看到1/2因子没有被应用,但应该查看源代码中的默认值。干得好! - T. Scharf
我知道我来晚了,但你能解释一下为什么 p 是一个由0.5组成的向量,并且为什么要将其与 Y 进行比较吗?这是对 Y 的初始、不知情的猜测吗? - Lil' Pete

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