0

我很难理解 XGBoost 如何计算多类分类中的叶子权重。

我生成了一个包含两个特性和 3 个类的简单示例。训练数据如下所示:

功能 0 特色一 标签 y
x1 1 1 0
x2 2 3 1
x3 3 1 2

从我目前所读到的内容来看,XGBoost 使用“一对多”的原则。因此,XGBoost 为每个类创建单独的树。XGBoost 设置为 2 轮增强,创建 6 棵树。第一棵树对应第 0 类,第二棵对应第 1 类,第三棵对应第 2 类,第四棵对应第 0 类,依此类推……

我使用以下 python 代码绘制了第一棵树。

from xgboost import XGBClassifier, plot_tree
import numpy as np

X_train = np.array([[1,1],[2,3],[3,1]])
y_train = np.array([0,1,2])

param = {
    'max_depth': 2,
    'eta': 0.3,
    'objective': 'multi:softprob', 
    'num_class': 3, 
    'min_child_weight': 0,
    'n_estimators' : 2,
    'base_score': 0.5
}

clf = XGBClassifier(**param)
clf.fit(X_train, y_train)

plot_tree(clf, num_trees=0)
plot_tree(clf, num_trees=1)
plot_tree(clf, num_trees=2)

结果如下所示:第一个树助推器

问题是如何计算叶子的权重?

到目前为止我的想法:
据我了解,XGBoost 使用对数损失函数进行二进制分类。
L(p,y) = −( ylog(p) + (1−y)log(1−p) )
(其中 p= 1/(1+exp(-x))))
y 是真实标签,p是样本属于第1类的模型的概率预测。
这个损失函数的梯度和hessian为:
梯度:p - y
hessian:p(1-p)

对于如何为固定树结构计算理想权重有一个很好的解释(XGBoost Docs)。因此,理想权重的计算公式为:
w_t = - G_t / (H_t + lambda)
其中 G_t 是属于叶子的所有样本的梯度统计的总和。类似地,H_t 是属于叶子的所有样本的二阶统计量(hessian)之和。

现在我想计算第一棵树的权重。所有实例的初始预测分数关闭为 0.5。由于这棵树对应于 0 类,因此真正的标签关闭为 y1=1、y2=0、y3=0(因为只有样本 1 具有 0 类)。梯度和 hessian 统计为:
g1 = 0.5 - 1 = -0.5
g2 = 0.5 - 0 = 0.5
g3 = 0.5 - 0 = 0.5

h1 = 0.5(1-0.5) = 0.25
h2 = 0.5(1-0.5) = 0.25
h3 = 0.5(1-0.5) = 0.25

第一棵树只有一个分割标准 f0 < 1.5。因此,样本 1 分配给左叶,样本 2 和 3 分配给右叶。

权重通过以下方式计算:
w1 = - g1 / (h1 + lambda) * eta = 0.5 / (0.25 + 1) * 0.3 = 0.12
w2 = - (g2 + g3) / (h2 + h3 + lambda) * eta = -(0.5 +0.5) / (0.25 + 0.25 + 1) * 0.3 = - 0.1998
与 eta 学习率

我的结果与 XGBoost 的结果不匹配,因为 w1 和 w2 应该大约为 0.1384 和 -0.106。

我究竟做错了什么?

我认为我真正的问题是我不了解日志损失以及 sigmoid 函数如何影响结果。

如果有人可以帮助我,我将不胜感激。

4

1 回答 1

0

我发现我的错误,实际上,有两个错误:

  1. 粗麻布错误:2*p(1-p)
  2. 预测分数由 softmax 函数归一化 ->exp(0.5) / (3 * exp(0.5) = 0.33

g1 = 0.33 - 1 = -0.67
g2 = g3 = 0.33 - 0 = 0.33
h1 = h2 = h3 = 2 * 0.33 (1 - 0.33) = 0.4422

w1 = - (-0.67) / (0.4422 + 1) * 0.3 = 0.139
w2 = -(0.33 + 0.33) / (0.4422 + 0.4422 + 1) * 0.3 = -0.105

于 2022-01-28T15:31:03.287 回答