码迷,mamicode.com
首页 > 其他好文 > 详细

从提升树到 XGBoost, 原理简介

时间:2019-06-16 00:35:56      阅读:190      评论:0      收藏:0      [点我收藏+]

标签:trie   hat   xgboost   rip   训练   rod   disco   nts   cimage   

提升树 (Boosting Trees)

提升树是以分类树或回归树为基本分类器的提升方法, 模型表示为决策树的加法模型:

\[ F_M(x) = \sum_{m=0}^M f(x;\Theta_m), \]

其中 \(M\) 为树的个数, \(f(x;\Theta_m)\) 表示决策树, \(\Theta_m\) 为其参数.

1. 提升树算法

提升树算法采用向前分步 (forward stagewise) 算法 (本质上是一种贪心算法). 对于训练数据集 \(D = \{(x_i, y_i) \}_{i=1}^N?\), 首先确定初始提升树 \(F_0(x)=0?\), 然后第 \(m?\) 步的模型是

\[ F_m(x) = F_{m-1}(x) + f(x;\Theta_m), \]

其中 \(F_{m-1}\) 为当前模型, 通过经验风险最小化确定下一颗决策树的参数,

\[ \hat\Theta_m = \operatorname*{argmin}_{\Theta_m}\sum_{i=1}^N l(y_i, F_{m-1}(x_i) + f(x_i;\Theta_m)), \]

其中 \(l\) 为损失函数.

回归问题的提升树可以表示为简单函数

\[ f(x;\Theta) = \sum_{j=1}^T c_j 1_{R_j}(x), \]

其中 \(R_j\) 互不相交, \(1_{R_j}(x)\) 为示性函数, \(c_j\) 为常数, 参数 \(\Theta=\{(R_j,c_j)\}_{j=1}^T\), \(T\) 为叶节点个数.

综上,

回归问题的提升树算法

  1. 初始化 \(F_0(x) = 0\).
  2. \(m = 1,\dots,M\): (a) 通过经验风险最小化学习一个回归树 \(f(x;\Theta_m)\). (b) 更新 \(F_m(x) = F_{m-1}(x) + f(x;\Theta_m)\).
  3. 输出回归问题提升树 \(F_M(x) = \sum_{m=1}^M f(x;\Theta_m)\).

2. 梯度提升树 (Gradient Boosting Decision Trees)

对于一般的损失函数, 每一步经验风险最小化都不容易. GBDT 是为了便于计算而提出的方法, 它的主要想法来自于梯度下降法.

记损失函数的梯度在当前模型的值为

\[ g_{im} = \left(\frac{\partial l(y_i,F(x_i))}{\partial F(x_i)}\right)_{F = F_{m-1}}. \]

则由梯度下降法,

\[ F_m(x_i) = F_{m-1}(x_i) -\rho_m g_{im}, \]

其中步长 \(\rho_m\) 可以通过线搜索获得, 即

\[ \rho_m = \operatorname*{argmin}_{\rho} \sum_{i=1}^Nl(y_i, F_{m-1}(x_i)-\rho g_{im}). \]

梯度下降法是一个很贪心的算法, 即在当前点取函数下降最快的方向. 但如上这样做的话我们只获得了在训练数据点上的预测, 为了得到可以预测新数据的决策树, 一种可行的做法是, 用 \(f\) 逼近负梯度方向, ESL [2] p. 321 使用了平方误差来度量 \(f\) 与负梯度的距离, 即

\[ \tilde\Theta_m = \operatorname*{argmin}_{\Theta}\sum_{i=1}^N (-g_{im} - f(x_i;\Theta))^2. \]

注意到对于 \(l(x,y) = \frac12(x-y)^2\) 的情形, \(\tilde\Theta_m\)\(\hat\Theta_m\) 相等.

其余操作同提升树算法, 从略.

3. XGBoost

3.1. 总体框架

XGBoost 的主要想法是, 除了原有的损失函数, 在目标函数中加入正则项, 利用二阶 Taylor 近似代替目标函数再求极值 (回忆之前的梯度提升树只用了一阶导数), 其余操作同提升树算法.

\(F_m(x_i) = \hat y_i^{(m)}\),
\(\hat y_i^{(0)}=0\),
\(\hat y_i^{(m)} = \hat y_i^{(m-1)} + f_m(x_i)\), \(m=1,\dots,M\).

\(f_m\) 表示第 \(m\) 轮时所得的树, 是由最小化目标函数而得; \(\hat y_i^{(m)}\) 表示第 \(m\) 轮时 \(y_i\) 的预测值.

\(m\) 轮目标函数为

\[ \mathrm{Obj}^{(m)} = \sum_{i=1}^N l\left(y_i, \hat y_i^{(m-1)} + f_m(x_i)\right) + \Omega(f_m), \]

其中 \(l\) 为损失函数; \(\Omega\) 为正则项, 是人为定义的复杂度, 可以降低模型复杂度, 减小过拟合的风险, 在原论文 [3] 中定义为

\[ \Omega(f) = \gamma T + \frac12 \lambda\sum_{j=1}^T w_j^2, \]

其中 \(\gamma\), \(\lambda\) 为参数, \(T\)\(f\) 表示的数的叶节点数, \(w_j\) 为第 \(j\) 个叶节点的预测值 (权重).

除了加入正则项外, 还可以通过 shrinkage 来降低过拟合风险, 即 \(F_m = F_{m-1} + \nu f_m\), 其中 \(0<\nu<1\), 可以看为学习率, 原来的做法相当于取 \(\nu=1\). 这么做主要的理由是减少每颗树对总模型的影响, 防止前几颗树拟合地太好 (过拟合) 以至于后面的树没有了学习空间.

3.2. 寻找分裂点

对目标函数做二阶 Taylor 展开, 略去更高阶的无穷小量. 记

\[ g_i = \frac{\partial l(y_i, \hat y_i^{(m-1)})}{\partial{\hat y^{(m-1)}}},\quad h_i = \frac{\partial^2 l(y_i, \hat y_i^{(m-1)})}{\partial{\left(\hat y^{(m-1)}\right)^2}}. \]

例如对于平方损失函数 \((y_i - \hat y_i^{(m-1)})^2\) 来说, \(g_i = 2(\hat y_i^{(m-1)} - y_i)\), \(h_i = 2\).

经过简单的推导可得最优权重为

\[ w_j^* = -\frac{\sum_{i\in I_j}g_i}{\sum_{i\in I_j} h_i + \lambda}, \]

其中 \(I_j\) 表示被归到第 \(j\) 个叶节点的全体实例 (的脚标) 集合.

一般而言, 穷举所有可能的树结构是不可能的, 作为代替, 我们考虑贪心算法. 从一个叶节点开始二分, 假设 \(I_L\)\(I_R\) 分别表示分裂后归为左节点和右节点的实例集合, 记 \(I = I_L \cup I_R\), 则易得分裂后的目标函数减少值 (loss reduction) 为

\[ \frac12\left[\frac{(\sum_{i\in I_L}g_i)^2}{\sum_{i\in I_L} h_i + \lambda} + \frac{(\sum_{i\in I_R}g_i)^2}{\sum_{i\in I_R} h_i + \lambda} - \frac{(\sum_{i\in I}g_i)^2}{\sum_{i\in I} h_i + \lambda}\right] - \gamma \]

把上式第一项视为 gain, 则 \(\gamma\) 相当于设置了分裂所需的最小的 gain, 起到了剪枝的作用.

寻找分裂点的精确贪心算法 (原文 [3] 中本段有一些 typo)
输入: \(I\), 当前节点的实例集; \(d\), 特征维数 (个数).
初始化 \(\mathrm{gain} \leftarrow 0\)
\(G \leftarrow \sum_{i\in I}g_i\), \(H \leftarrow \sum_{i\in I}h_i\)
for \(k=1\) to \(d\) do
???? \(G_L \leftarrow 0\), \(H_L \leftarrow 0\)
???? for \(j\) in sorted (\(I\), by \(x_{jk}\)) do
???????? \(G_L\leftarrow G_L + g_j\), \(H_L\leftarrow H_L + h_j\)
???????? \(G_R \leftarrow G-G_L\), \(H_R \leftarrow H- H_L\)
???????? \(\mathrm{gain} \leftarrow \max(\mathrm{gain}, \frac{G_L^2}{H_L + \lambda} + \frac{G_R^2}{H_R + \lambda} - \frac{G^2}{H + \lambda})\)
输出: 最大 gain 的分裂

精确贪心法是在所有特征上, 对所有可能的分裂点都进行遍历, 在数据量大的时候是不现实的. 一个简单的近似方法是, 排序后 (for \(j\) in sorted (\(I\), by \(x_{jk}\)) 那步), 取适当的分位数作为分裂候选点进行贪心算法.

3.3. 稀疏数据的分裂点寻找 (sparsity-aware)

主要分为两种情况:

  1. 若数据有缺失值, 则把缺失值都归到同一个节点. 这是处理缺失值的常用方法之一 (另一种常用方法是用适当的方法填补缺失值), 这使得 XGB 可以直接训练和预测带有缺失值的数据.
  2. 若数据稀疏 (比如 one-hot 编码, 使得数据包含大量的 0), 则把 0 当做缺失值处理. 这个做法的关键点在于遍历时只对非缺失 (非零) 数据遍历, 在稀疏数据的情况下会大大提高训练速率.

注: 按照原论文 [3] 的说法, 作者似乎把缺失和稀疏时的 0 都统称为 "稀疏/缺失", 用同样的方式处理, [5] 也证实了这一点.

技术图片

图中 \(m\) 应该为 \(d\), score 应该为 gain.

3.4. XGB 的优点

XGB 把决策树的许多启发式的想法通过最小化目标函数统一起来处理. 除了使用近似算法, 在系统设计上, 通过并行处理, 优化缓存等工程层面上的优化大幅提高了运行速度, 减小了内存使用.

References

[1] 李航. (2012). 统计学习方法 (pp. 55-74, 137-153). 北京: 清华大学出版社.
[2] Friedman, J., Hastie, T., & Tibshirani, R. (2001). The elements of statistical learning (pp. 299-344). New York: Springer series in statistics.
[3] Chen, T., & Guestrin, C. (2016). Xgboost: A scalable tree boosting system. Proceedings of the 22nd acm sigkdd international conference on knowledge discovery and data mining (pp. 785-794). ACM.
[4] Introduction to Boosted Trees. (n.d.). Retrieved from https://xgboost.readthedocs.io/en/latest/tutorials/model.html#
[5] Kodi Arfer. XGBoost, missing values, and sparsity. (2018). Retrieved from http://arfer.net/w/xgboost-sparsity

从提升树到 XGBoost, 原理简介

标签:trie   hat   xgboost   rip   训练   rod   disco   nts   cimage   

原文地址:https://www.cnblogs.com/shiina922/p/11029340.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!