我很难理解 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 函数如何影响结果。
如果有人可以帮助我,我将不胜感激。