Boosting发展综述

Boosting思想起源于PAC(Probably Approximately Correct)学习模型,   Kearns 和  Valiant  于1989年提出弱学习器与强学习器学习能力等价的猜想[1],1990年Schapire通过构造多项式的方法证实了这一猜想,这也是最初的Boosting算法。一年后,Schapire提出了一种更为高效的Boosting算法,但这两种算法都需要知道弱学习器的学习正确率的下限,难以应用实际问题。
Adaptive Boosting
1997年,Schapire提出了AdaBoost(Adaptive Boosting)算法,能够更好地利用弱学习器的优势,同时也摆脱了对弱学习器先验知识的依赖。AdaBoost的主题思想是减弱上一轮预测正确的样本的权重,增大预测错误的样本权重。同时,给预测错误率低的学习器更大权重。 AdaBoost的损失函数是指数损失函数 ,从而可以推导出分类器的权重。
其伪代码如下[2]:
Boosting发展综述_第1张图片
AdaBoost方法有着很强的抗过拟合能力 ,Freund 和Schapire 使用可最初给出的AdaBoost的误差上界为:
泛化错误(泛化错误可理解为测试错误) < 训练错误 + 学习算法容量相关项
实验表明,AdaBoost通常不会发生过拟合,也就是说在训练误差降为0以后,泛化集的误差常常随着训练继续下降,甚至可以继续新增1000个学习器左右。1998年,Schapire引入margin-based理论解释,基于margin的概念, AdaBoost的误差上界为:
泛化错误 < 训练Margin项 + 学习算法容量相关项 (2)

Gradient Boosting
在AdaBoost发表后不久,Breiman等人发表了 Formulate AdaBoost as gradient descent with a special loss function 2001年,Freund 在 Greedy function approximation: A gradient boosting machine 中,将梯度下降的思想引入 Boosting 算法,提出了Gradient Boosting 思想。Gradient Boosting 是一个 Boosting 框架,能处理不同的损失函数,较为实用。
Gradient Boosting思想在函数空间以负的梯度方向优化cost function,可以认为是AdaBoost的推广。
经典的GBDT算法一般选取CART回归树模型作为弱学习器,square loss作为cost function,从而GBDT在迭代过程是学习上一轮的残差。 square loss对异常值不鲁邦 ,也可以采用其他的cost function,如absolute loss 或 huber loss。[3]
Boosting发展综述_第2张图片
对于分类问题,很多是获得一个概率分布来逼近真实的概率分布。所以很多时候基于log loss来构建目标函数,如 KL-divergence或cross entropy,如果用指数损失函数,GBDT则等价为退化成AdaBoost。
Boosting发展综述_第3张图片
XGBoost
XGBoost的目标函数形式[4]:

Boosting发展综述_第4张图片

对Training loss项进行泰勒二阶展开:

定义树的复杂度:
Boosting发展综述_第5张图片
去除loss function中的常数项:
Boosting发展综述_第6张图片
问题变成了一个一元二次方程的极值求解问题:

Boosting发展综述_第7张图片

然后,贪心算法计算
Boosting发展综述_第8张图片

GBDT与XGBoost比较[5]:
  • 传统GBDT以CART作为基分类器,xgboost还支持线性分类器,这个时候xgboost相当于带L1和L2正则化项的逻辑斯蒂回归(分类问题)或者线性回归(回归问题)。
  • 传统GBDT在优化时只用到一阶导数信息,xgboost则对代价函数进行了二阶泰勒展开,同时用到了一阶和二阶导数。顺便提一下,xgboost工具支持自定义代价函数,只要函数可一阶和二阶求导。
  • xgboost在代价函数里加入了正则项,用于控制模型的复杂度。正则项里包含了树的叶子节点个数、每个叶子节点上输出的score的L2模的平方和。从Bias-variance tradeoff角度来讲,正则项降低了模型的variance,使学习出来的模型更加简单,防止过拟合,这也是xgboost优于传统GBDT的一个特性。
  • Shrinkage(缩减),相当于学习速率(xgboost中的eta)。xgboost在进行完一次迭代后,会将叶子节点的权重乘上该系数,主要是为了削弱每棵树的影响,让后面有更大的学习空间。实际应用中,一般把eta设置得小一点,然后迭代次数设置得大一点。(补充:传统GBDT的实现也有学习速率)
  • 列抽样(column subsampling)。xgboost借鉴了随机森林的做法,支持列抽样,不仅能降低过拟合,还能减少计算,这也是xgboost异于传统gbdt的一个特性。
  • 对缺失值的处理。对于特征的值有缺失的样本,xgboost可以自动学习出它的分裂方向。
  • xgboost工具支持并行。boosting不是一种串行的结构吗?怎么并行的?注意xgboost的并行不是tree粒度的并行,xgboost也是一次迭代完才能进行下一次迭代的(第t次迭代的代价函数里包含了前面t-1次迭代的预测值)。xgboost的并行是在特征粒度上的。我们知道,决策树的学习最耗时的一个步骤就是对特征的值进行排序(因为要确定最佳分割点),xgboost在训练之前,预先对数据进行了排序,然后保存为block结构,后面的迭代中重复地使用这个结构,大大减小计算量。这个block结构也使得并行成为了可能,在进行节点的分裂时,需要计算每个特征的增益,最终选增益最大的那个特征去做分裂,那么各个特征的增益计算就可以开多线程进行。

LightGBM

LightGBM是微软16年开源的Boosting算法,最典型的有时就是计算非常快,github地址:https://github.com/Microsoft/LightGBM。[6]

Boosting发展综述_第9张图片

Histogram算法
直方图算法的基本思想是先把连续的浮点特征值离散化成k个整数,同时构造一个宽度为k的直方图。在遍历数据的时候,根据离散化后的值作为索引在直方图中累积统计量,当遍历一次数据后,直方图累积了需要的统计量,然后根据直方图的离散值,遍历寻找最优的分割点。

Boosting发展综述_第10张图片
带深度限制的Leaf-wise的叶子生长策略
Level-wise过一次数据可以同时分裂同一层的叶子,容易进行多线程优化,也好控制模型复杂度,不容易过拟合。但实际上Level-wise是一种低效的算法,因为它不加区分的对待同一层的叶子,带来了很多没必要的开销,因为实际上很多叶子的分裂增益较低,没必要进行搜索和分裂。
Leaf-wise则是一种更为高效的策略,每次从当前所有叶子中,找到分裂增益最大的一个叶子,然后分裂,如此循环。因此同Level-wise相比,在分裂次数相同的情况下,Leaf-wise可以降低更多的误差,得到更好的精度。Leaf-wise的缺点是可能会长出比较深的决策树,产生过拟合。因此LightGBM在Leaf-wise之上增加了一个最大深度的限制,在保证高效率的同时防止过拟合。
Boosting发展综述_第11张图片
Boosting发展综述_第12张图片
参考资料:
[1]Kearns M, Valiant L G. Learning Boolean formulae or finite automata is as hard as factoring[J]. 1988.
[2] Zhi-Hua Zhou. Ensemble Methods Foundations and Algorithms .2012.
[3]https://www.jianshu.com/p/005a4e6ac775
[4]Tianqi Chen.Introduction to Boosted Trees.2014.
[5]https://www.zhihu.com/question/41354392
[6]https://www.zhihu.com/question/51644470






你可能感兴趣的:(Boosting发展综述)