GBDT算法用于分类问题

GBDT算法用于分类问题

GBDT算法概述

GBDT是boosting算法的一种,按照boosting的思想,在GBDT算法的每一步,用一棵决策树去拟合当前学习器的残差,获得一个新的弱学习器。将这每一步的决策树组合起来,就得到了一个强学习器。

具体来说,假设有训练样本 \{x_i, y_i\}, i=1...n ,第m-1步获得的集成学习器为 F_{m-1}(x) ,那么GBDT通过下面的递推式,获得一个新的弱学习器 h(x)

F_m(x) = F_{m-1}(x) + \mathop{\mathrm{argmin}}_{h \in H} \sum_{i=1}^{n} Loss(y_i, F_{m-1}(x_i) + h(x_i))\\

其中 h(x) 是在函数空间 H 上最小化损失函数,一般来说这是比较难以做到的。但是,如果我们只考虑精确地拟合训练数据的话,可以将损失函数 \sum_{i=1}^{n} Loss(y_i, F_{m-1}(x_i) + h(x_i)) 看作向量 (F(x_1), F(x_2), ..., F(x_n)) 上的函数。这样在第m-1轮迭代之后,向量位于 (F_{m-1}(x_1), F_{m-1}(x_2), ..., F_{m-1}(x_n)) ,如果我们想进一步减小损失函数,则根据梯度下降法,向量移动的方向应为损失函数的负梯度方向,即:

\textbf{v} = - \left( \frac{\partial loss(y_1, F_{m-1}(x_1))}{\partial F_{m-1}(x_1)}, \frac{\partial loss(y_2, F_{m-1}(x_2))}{\partial F_{m-1}(x_2)}, ..., \frac{\partial loss(y_n, F_{m-1}(x_n))}{\partial F_{m-1}(x_n)} \right)\\

这样如果使用训练集: \left\{ x_i, -\frac{\partial loss(y_i, F_{m-1}(x_i))}{\partial F_{m-1}(x_i)} \right\}_{i=1}^n 去训练一棵树的话,就相当于朝着损失函数减小的方向又走了一步(当然在实际应用中需要shrinkage,也就是考虑学习率)。由此可见,GBDT在本质上还是梯度下降法,每一步通过学习一棵拟合负梯度(也就是所谓“残差”)的树,来使损失函数逐渐减小。

GBDT用于分类问题

将GBDT应用于回归问题,相对来说比较容易理解。因为回归问题的损失函数一般为平方差损失函数,这时的残差,恰好等于预测值与实际值之间的差值。每次拿一棵决策树去拟合这个差值,使得残差越来越小,这个过程还是比较intuitive的。而将GBDT用于分类问题,则显得不那么显而易见。下面我们就通过一个简单的二分类问题,去看看GBDT究竟是如何学习到一棵树的。

类似于逻辑回归、FM模型用于分类问题,其实是在用一个线性模型或者包含交叉项的非线性模型,去拟合所谓的对数几率 \ln \frac{p}{1-p} 。而GBDT也是一样,只是用一系列的梯度提升树去拟合这个对数几率,实际上最终得到的是一系列CART回归树。其分类模型可以表达为:

P(y=1|x) = \frac{1}{1+e^{- \sum_{m=0}^M h_m(x)}}\\

其中h_m(x) 就是学习到的决策树。

清楚了这一点之后,我们便可以参考逻辑回归,单样本 (x_i, y_i) 的损失函数可以表达为交叉熵:

loss(x_i, y_i) = -y_i \log \hat{y_i} - (1-y_i) \log(1-\hat{y_i})\\

假设第k步迭代之后当前学习器为 F(x) = \sum_{m=0}^k h_m(x) ,将 \hat{y_i} 的表达式带入之后, 可将损失函数写为:

loss(x_i, y_i|F(x)) = y_i \log \left( 1+e^{-F(x_i)} \right) + (1-y_i) \left[ F(x_i) + \log \left( 1+e^{-F(x_i)} \right) \right]\\

可以求得损失函数相对于当前学习器的负梯度为:

-\frac{\partial loss}{\partial F(x)}|_{x_i,y_i} = y_i - \frac{1}{1+e^{-F(x_i)}}= y_i - \hat{y_i}\\

可以看到,同回归问题很类似,下一棵决策树的训练样本为: \{ x_i, y_i - \hat{y_i} \}_{i=1}^n ,其所需要拟合的残差为真实标签与预测概率之差。于是便有下面GBDT应用于二分类的算法:

  • F_0(x) = h_0(x) = \log \frac{p_1}{1-p_1} ,其中 p_1 是训练样本中y=1的比例,利用先验信息来初始化学习器
  • For m = 1,2,...,M
    • 计算 g_i = \hat{y_i} - y_i ,并使用训练集 \{(x_i, -g_i)\}_{i=1}^n 训练一棵回归树 t_m(x) ,其中 \hat{y_i} = \frac{1}{1+e^{-F_{m-1}(x)}}
    • 通过一维最小化损失函数找到树的最优权重: \rho_m = \mathop{\mathrm{argmin}}\limits_{\rho} \sum_i loss(x_i, y_i|F_{m-1}(x)+\rho t_m(x))
    • 考虑shrinkage,可得这一轮迭代之后的学习器 F_m(x) = F_{m-1}(x) + \alpha \rho_m t_m(x)\alpha 为学习率
  • 得到最终学习器为: F_M(x)

以上就是将GBDT应用于二分类问题的算法流程。类似地,对于多分类问题,则需要考虑以下softmax模型:

P(y=1|x) = \frac{e^{F_1(x)}}{\sum_{i=1}^k e^{F_i(x)}}\\

P(y=2|x) = \frac{e^{F_2(x)}}{\sum_{i=1}^k e^{F_i(x)}}\\

... ...\\

P(y=k|x) = \frac{e^{F_k(x)}}{\sum_{i=1}^k e^{F_i(x)}}\\

其中 F_1 F_kk 个不同的tree ensemble。每一轮的训练实际上是训练了 k 棵树去拟合softmax的每一个分支模型的负梯度。softmax模型的单样本损失函数为:

loss = -\sum_{i=1}^k y_i \log P(y_i|x) = -\sum_{i=1}^k y_i \log \frac{e^{F_i(x)}}{\sum_{j=1}^k e^{F_j(x)}}\\

这里的 y_i\ (i=1...k) 是样本label在k个类别上作one-hot编码之后的取值,只有一维为1,其余都是0。由以上表达式不难推导:

-\frac{\partial loss}{\partial F_q} = y_q - \frac{e^{F_q(x)}}{\sum_{j=1}^k e^{F_j(x)}} = y_q - \hat{y_q}\\

可见,这k棵树同样是拟合了样本的真实标签与预测概率之差,与二分类的过程非常类似。

编辑于 2018-10-11