常见的集成学习框架有三种:Bagging,Boosting 和 Stacking。
文章目录
- 一、bagging
- 1.1 bagging基本原理
- 1.2 决策树
- 二、boosting
- 2.1 Boosting算法原理
- 2.2 Adaboost算法原理
- 2.3 GBDT
- 2.4 XGBoost
- 2.4.1 目标函数
- 2.4.2 正则项
- 2.4.3 分割策略
- 2.5 XGBoost和GBDT主要区别
- 2.6.1 单边梯度抽样算法
- 2.6.2 直方图算法
一、bagging
1.1 bagging基本原理
- 自助采样(bootstrap):有放回的从数据集中进行采样。
- Bagging:通过Bootstrap 的方式对全样本数据集进行抽样得到抽样子集,对不同的子集使用同一种基本模型进行拟合,然后投票得出最终的预测。Bagging主要通过降低方差的方式减少预测误差
- Bagging的一个典型应用是随机森林。由许多“树”bagging组成的。每个决策树训练的样本和构建决策树的特征都是通过随机采样得到的,随机森林的预测结果是多个决策树输出的组合(投票)
1.2 决策树
- 决策树,它是一种树形结构,树的每个非叶子节点表示对样本在一个特征上的判断,节点下方的分支代表对样本的划分。
- 每次划分中,首先要选择用于划分的特征,之后要确定划分的方案(类别/阈值)。我们希望通过划分,决策树的分支节点所包含的样本“纯度”尽可能地高。节点划分过程中所用的指标主要是
max信息增益
或者min GINI系数
信息增益 IG=划分前的信息熵H(Y)-划分后的条件熵H(Y|X)
- 选择信息增益最大或者gini指数最小的划分方式,划分过程直到样本的类别被完全分开,所有特征都已使用,或达到树的最大深度为止。
二、boosting
2.1 Boosting算法原理
- Boosting:使用同一组数据集进行反复学习,得到一系列简单模型,然后组合这些模型构成一个预测性能十分强大的机器学习模型。
- Boosting通过不断减少偏差的形式提高最终的预测效果,与Bagging有着本质的不同。
Boosting方法关键点:
- 每一轮学习应该如何改变数据的概率分布
- 如何将各个弱分类器组合起来
2.2 Adaboost算法原理
Adaboost不改变训练数据,而是改变其权值分布,使每一轮的基学习器学习不同权重分布的样本集,最后加权组合表决组合。
Adaboost解决上述的两个问题的方式是:
- 提高那些被前一轮分类器错误分类的样本的权重,来改变数据的概率分布
- 各个弱分类器通过采取加权多数表决的方式组合。
- Adaboost算法是由基本分类器组成的加法模型,损失函数为指数损失函数。
- 加法模型:最终的强分类器是由若干个弱分类器加权平均得到的。
简单来说:训练M个基本分类器,计算每个分类器的错误率、模型权重及样本权重。
- 均匀初始化样本权重
- 对于轮次m,针对当前权重 学习分类器 ,并计算其分类错误率。
代表了在中分类错误的样本权重和,这点直接说明了权重分布与的分类错误率有直接关系。 - 计算分类器的权重系数。时,,并且随着的减少而增大,因此分类错误率越小的基本分类器在最终分类器的作用越大!
- 更新权重分布
这里的是规范化因子,使得成为概率分布。
一般来说。被基本分类器错误分类的样本的权重扩大,被正确分类的样本权重减少。减小,增大,增大。 - 基本分类器加权组合表决
线性组合实现了将M个基本分类器的加权表决,系数标志了基本分类器的重要性,值得注意的是:所有的之和不为1。的符号决定了样本x属于哪一类,其绝对值表示分类的确信度。
下面是用前向分布算法,从指数损失函数到分类错误率、分类器的权重系数、样本权重更新公式的推导:
这样就得到了样本权重更新公式。
2.3 GBDT
- GBDT 的全称是
Gradient Boosting Decision Tree
,梯度提升树。GBDT使用的决策树是CART回归树
。因为GBDT每次迭代要拟合的是梯度值,是连续值所以要用回归树
。 - CART假设决策树都是二叉树,内部节点特征取值为“是”和“否”,等价于递归二分每个特征。对回归树用平方误差最小化准则(回归树中的样本标签是连续数值,所以再使用熵之类的指标不再合适),对分类树用基尼系数最小化准则,进行特征选择生成二叉树
- 回归问题没有分类错误率可言,用每个样本的残差表示每次使用基函数预测时没有解决的那部分问题。
GBDT和Adaboost区别:
- 拟合思路
- Adaboost算法:使用了
分类错误率修正样本权重以及计算每个基本分类器的权重
。通过不断修改样本权重(增大分错样本权重,降低分对样本权重),不断加入弱分类器进行boosting。 - GBDT:拟合残差来学习基模型。残差定义为损失函数相对于前一轮组合树模型的负梯度方向的值作为残差的近似值(损失函数的负梯度在当前模型的值)希望最快速度地最小化预测值与真实值之间的差异。
- 除了均方差损失函数时,负梯度值等于残差。
- GBDT 的每一步残差计算其实变相地增大了被分错样本的权重,而
对与分对样本的权重趋于 0,这样后面的树就能专注于那些被分错的样本
。
- Adaboost是分类树,GBDT是回归树,但是也可以做分类。
- AdaBoost 是通过提升错分数据点的权重来定位模型的不足,而 Gradient Boosting 是通过算梯度(gradient)来定位模型的不足。因此相比 AdaBoost, Gradient Boosting 可以使用更多种类的目标函数(5种)AdaBoost 采用的是指数损失,GBDT 使用的是绝对损失或者 Huber 损失函数。
- 基于残差 GBDT 容易对异常值敏感:
很明显后续的模型会对第 4 个值关注过多,这不是一种好的现象,所以一般回归类的损失函数会用绝对损失或者 Huber 损失函数来代替平方损失函数
。
2.4 XGBoost
2.4.1 目标函数
XGBoost 是 Boosting 框架的一种实现结构, lightgbm 也是一种框架实现结构,而 GBDT 则是一种算法实现。XGBoost本质也是GBDT, 相比于 GBDT 的差别主要就是 XGBoost 做的优化。
- 构造目标函数为:
为loss function,为正则化项。 - 叠加式训练 其中, 为前K-1棵树的预测结果,
- 目标函数分解:
由于正则化项也可以分解为前K-1棵树的复杂度加第K棵树的复杂度,因此:
由于在模型构建到第K棵树的时候已经固定,无法改变,因此是一个已知的常数,可以在最优化的时候省去,故:
4. 使用泰勒级数近似目标函数:
其中,和
由于在模型构建到第K棵树的时候已经固定,无法改变,因此是一个已知的常数,可以在最优化的时候省去,故:
2.4.2 正则项
模型复杂度,它可以由叶子节点的个数以及节点函数值来构建
,则:
目标函数用以上符号替代后:
我们的目标就是最小化目标函数,根据二次函数求极值的公式:求极值有:
以及
分割节点的标准为,即:节点分裂标准是:目标函数的值在分裂前后的差值最大
2.4.3 分割策略
为了找到找到最优特征及最优切分点,有三种策略:
- 精确贪心分裂算法:首先找到所有的候 选特征及所有的候选切分点, 求其 , 然后 选择使
- 精确贪心算法优点:它计算了所有特征、所有切分点的收益, 并从中选择了最优的, 从而保证模型能比较好地拟合了训练数据。
- 精确贪心算法缺点:当数据不能完全加载到内存时非常低效。算法在计算过程中需要不断在内存与磁盘之间进行数据交换,非常耗时, 并且在分布式环境中面临同样的问题
- 基于直方图的近似算法:更高效地选 择最优特征及切分点
- 对某一特征寻找最优切分点时,首先对该特征的所有切分点按分位数 (如百分位) 分桶, 得到一个候选切分点集。
- 特征的每一个切分点都可以分到对应的分桶,对每个桶计算特征统计G和H得到直方图, G为该桶内所有样本一阶特征统计g之和, H为该桶内所有样本二阶特征统计h之和
- 选择所有候选特征及候选切分点中对应桶的特征统计收益最大的作为最优特征及最优切分点
- 近似算法实现了两种候选切分点的构建策略:全局策略和本地策略。
Global全局策略:学习每棵树前就提出候选切分点,并在每次分裂时都采用这种分割,整个过程候选切分点集合不改变
Local本地策略:每次分裂前将重新提出候选切分点
。
- 全局策略是在树构建的初始阶段对每一个特征确定一个候选切分点的集合, 并在该树每一层的节点分裂中均采用此集合计算收益, 整个过程候选切分点集合不改变。 Global 策略因为节点没有划分所以需要更多的候选点,即需要更细的分桶才能达到本地策略的精确度。
- 本地策略则是在每一次节点分裂时均重新确定候选切分点。
- 在XGBoost系统中, 用户可以根据需求自由选择使用精确贪心算法、近似算法全局策略、近似算法本地策略, 算法均可通过参数进行配置。
2.5 XGBoost和GBDT主要区别
XGBoost优点:
-
灵活性更强
:传统GBDT以CART作为基分类器,xgboost还支持线性分类器
。xgboost相当于带L1和L2正则化项的逻辑斯蒂回归(分类问题)或者线性回归(回归问题)。 -
用到二阶导数和正则项,精度更高
。 GBDT在优化时只用到一阶导数信息,xgboost则对代价函数进行了二阶泰勒展开,同时用到了一阶和二阶导数。并在代价函数里加入了正则项,用于控制模型的复杂度,使学习出来的模型更加简单,防止过拟合。并且拟合方向更准、速度更快。(模型复杂度由叶子节点的个数以及节点函数值来构建) - xgboost支持
特征粒度上的并行
,而不是tree粒度的并行。决策树的学习最耗时的一个步骤就是对特征的值进行排序(因为要确定最佳分割点),xgboost在训练之前,预先对数据进行了排序,然后保存为block结构,后面的迭代中重复地使用这个结构,大大减小计算量。这个block结构也使得并行成为了可能,在进行节点的分裂时,需要计算每个特征的增益,最终选增益最大的那个特征去做分裂,那么`各个特征的增益计算就可以开多线程进行。 -
近似直方图算法
。树节点在进行分裂时,贪心算法枚举所有可能的分割点,计算了所有特征、所有切分点的收益。当数据无法一次载入内存或者在分布式情况下,计算时需要不断在内存与磁盘之间进行数据交换,非常耗时、效率很低。近似直方图算法,用于高效地生成候选的分割点。(就是 XGBoost 论文中介绍的加权直方图,这里权值是特征的二阶梯度,因为其目标函数可以化简为二次项系数为 H 的二次多项式) - Shrinkage(缩减):相当于学习速率。XGBoost 在进行完一次迭代后,会将叶子节点的权重乘上该系数,主要是为了削弱每棵树的影响,让后面有更大的学习空间;
- 支持列抽样和缺失值处理。x列抽样,不仅能降低过拟合,还能减少计算,这也是xgboost异于传统gbdt的一个特性。对于特征的值有缺失的样本,xgboost可以自动学习出它的分裂方向(稀疏感知算法)。
- XGBoost, GBDT 均支持自定义损失函数,但 XGBoost 进行基分类器拟合的时候需要一阶、二阶梯度信息,故而需要自定义损失函数提供一阶、二阶梯度信息,而 GBDT 只需提供自定义损失函数的一阶梯度信息。
XGBoost缺点:
- 虽然利用预排序和近似算法可以降低寻找最佳分裂点的计算量,但在节点分裂过程中仍需要遍历数据集;
- 预排序过程的空间复杂度过高,不仅需要存储特征值,还需要存储特征对应样本的梯度统计值的索引,相当于消耗了两倍的内存
2.6 LightGBM
轻量级(Light)的梯度提升机(GBM),主要用于解决 GDBT 在海量数据中遇到的问题。其相对 XGBoost 具有训练速度快、内存占用低的特点。
下图分别显示了 XGBoost、XGBoost_hist(利用梯度直方图的 XGBoost) 和 LightGBM 三者之间针对不同数据集情况下的内存和训练时间的对比:
LightGBM 为了解决XGBoost的问题提出了以下几点解决方案:
- 单边梯度抽样算法;
- 直方图算法;
- 互斥特征捆绑算法;
- 基于最大深度的 Leaf-wise 的垂直生长算法;
- 类别特征最优分割;
- 特征并行和数据并行;
- 缓存优化。
2.6.1 单边梯度抽样算法
- 梯度大小可以反应样本的权重,梯度越小说明模型拟合的越好。单边梯度抽样算法(Gradient-based One-Side Sampling, GOSS)
保留了梯度大的样本,并对梯度小的样本进行随机抽样,减少了大量梯度小的样本
,极大的减少了计算量。(在接下来的计算锅中只需关注梯度高的样本) - 为了不改变样本的数据分布,在计算增益时为梯度小的样本引入一个常数进行平衡。
GOSS 事先基于梯度的绝对值对样本进行排序(无需保存排序后结果),然后拿到前 a% 的梯度大的样本,和总体样本的 b%,在计算增益时,通过乘上来放大梯度小的样本的权重。一方面算法将更多的注意力放在训练不足的样本上,另一方面通过乘上权重来防止采样对原始数据分布造成太大的影响。
2.6.2 直方图算法
- 直方图算法的基本思想是将连续的特征离散化为 k 个离散特征,同时构造一个宽度为 k 的直方图用于统计信息(含有 k 个 bin)。利用
直方图算法我们无需遍历数据,只需要遍历 k 个 bin 即可找到最佳分裂点
。 - 直方图算法存储方便、内存占用更小、运算更快、鲁棒性强、模型更加稳定
- 虽然将特征离散化后无法找到精确的分割点,可能会对模型的精度产生一定的影响,但较粗的分割也起到了正则化的效果,一定程度上降低了模型的方差。
- 直方图加速。在构建叶节点的直方图时,可以通过父节点的直方图与相邻叶节点的直方图相减的方式构建,从而减少了一半的计算量。
- 只用非零特征构建直方图。(XGBoost也一样)
其它见帖子《决策树(下)——XGBoost、LightGBM(非常详细)》。