机器学习--决策树、随机森林、GBDT、XGBoost

参考

机器学习的熵:机器学习各种熵:从入门到全面掌握 - 知乎 (zhihu.com)

交叉熵:交叉熵背后的直觉

相对熵(KL散度):相对熵(KL散度)

为什么交叉熵(cross-entropy)可以用于计算代价? - 知乎 (zhihu.com)

信息熵、条件熵、交叉熵、相对熵

互信息

什么是「互信息」 - 知乎 (zhihu.com)

信息增益

信息增益表示得知特征X的信息而使得类Y的信息不确定性减少的程度。

信息增益是决策树ID3算法在进行特征切割时使用的划分准则,其物理意义和互信息完全相同,并且公式也是完全相同。其公式如下:

g(D, A) = H(D) - H(D | A)

其中D表示数据集,A表示特征,信息增益表示得到A的信息而使得类X的不确定度下降的程度,在ID3中,需要选择一个A使得信息增益最大,这样可以使得分类系统进行快速决策。
需要注意的是:在数值上,信息增益和互信息完全相同,但意义不一样,需要区分,当我们说互信息时候,两个随机变量的地位是相同的,可以认为是纯数学工具,不考虑物理意义,当我们说信息增益时候,是把一个变量看成是减少另一个变量不确定度的手段。

信息增益比

特征A对训练数据集D的信息增益比g_{R}(D, A)定义为其信息增益g(D, A)与训练数据集D关于特征A的值的熵H_{A}(D)之比, 即

g_{R}(D, A) = \frac{g(D, A)}{H_{A}(D)}

基尼指数

基尼指数是另一种衡量不确定性的指标。

假设数据集DK个类,样本属于第K类的概率为 p_{k} ,则D的基尼指数定义为:Gini(p) = \sum_{k = 1}^{K}p_{k}(1 - p_{k}) = 1 - \sum_{k = 1}^{K}p_{k}^{2}

其中 p_{k} = \frac{\left | C_{k} \right | }{\left | D \right |} ,  是D中属于第k类的样本子集。

如果数据集D根据特征A是否取某一可能值a被分割成D_{1} 和D_{2}两部分,则在给定特征A的条件下,D的基尼指数为:Gini(D, A) = \frac{\left | D_{1} \right |}{\left | D \right |}Gini(D_{1}) + \frac{\left | D_{2} \right |}{\left | D \right |}Gini(D_{2})

容易证明基尼指数越大,样本的不确定性也越大,特征A的区分度越差。

我们优先选择基尼指数最小的特征,由此生成决策树,称为CART算法

决策树

决策树是一种基本的分类与回归方法, 决策树表示给定特征条件下类的条件概率分布

步骤:特征选择、决策树的生成、决策树的修剪

决策树学习思想:

  • ID3算法
  • C4.5算法
  • CART算法

决策树的结点:内部节点(Internal node)表示一个特征或属性、叶节点(leaf node)表示一个类

特征选择

特征选择在于选取对训练数据具有分类能力的特征。通常特征选择的准则是信息增益信息增益比

一般地,熵H(X)与条件熵H(Y|X)之差称为互信息(mutual information)。决策树学习中的信息增益等价于训练数据集中类与特征的互信息。

ID3算法

训练数据集D, 特征集阈值, 信息增益算法

C4.5算法

训练数据集D, 特征集阈值, 信息增益比算法

剪枝算法

  • 预剪枝:在树的生成过程中剪枝。基于贪心策略,可能造成局部最优
  • 后剪枝:等树全部生成后剪枝。运算量较大,但是比较精准

决策树的剪枝往往通过极小化决策树整体的损失函数或代价函数来实现

参考:认真的聊一聊决策树和随机森林 - 知乎 (zhihu.com)

机器学习--决策树、随机森林、GBDT、XGBoost_第1张图片

C_{\alpha} (T) = C(T) + \alpha\left | T \right |, 其中C(T)表示模型对训练数据的预测误差,即模型与训练数据的拟合程度, \left | T \right |表示模型复杂度, 参数控制两者之间的影响。

剪枝就是当参数确定时, 选择损失函数最小的模型,即损失函数最小的子树

步骤:

  • 计算每个结点的经验熵
  • 递归地从树的叶结点向上回缩, 比较回缩前后两棵树的损失函数值(判断是否剪枝)
  • 直至剪枝不能继续为止,得到损失函数最小的子树

CART算法

是一种典型的二叉决策树

  • 决策树生成:基于训练数据集生成决策树,生成的决策树尽量大
  • 决策树剪枝:用验证数据集对已生成的树进行剪枝并选择最优子树,用损失函数最小作为剪枝的标准

对回归树用平方误差最小化准则,对分类树用基尼指数最小化准则, 生成二叉树

作为分类决策树时,待预测样本落至某一叶子节点,则输出该叶子节点中所有样本所属类别最多的那一类(即叶子节点中的样本可能不是属于同一个类别,则多数为主);作为回归决策树时,待预测样本落至某一叶子节点,则输出该叶子节点中所有样本的均值。

回归树的生成, 一棵回归树对应着输入空间(即特征空间)的一个划分以及在划分的单元上的输出值。假设已经将输入空间划分为M个单元R_{1}, R_{2}, ... , R_{M}, 并且在每个单元R_{m}上有一个固定的输出值c_{m}(单元R_{m}上的c_{m}的最优值\hat{c_{m}}R_{m}上的所有输入实例x_{i}对应的输出y_{i}的均值, 即\hat{c_{m}} = ave(y_{i} | x_{i} \in R_{m})), 回归模型树模型可表示为:f(x) = \sum_{m = 1}^{M}c_{m}I(x \in R_{m})

当输入空间的划分确定时, 可以用平方误差\sum_{x_{i} \in R_{m}}(y_{i} - f(x_{i}))^{2}来表示回归树对于训练数据的预测误差, 用平方误差最小的准则求解每个单元上的最优输出值。

遍历第j个变量,以及其取值寻找最优切分变量和切分点,作为切分变量和切分点

分类树的生成,使用基尼指数, 同时决定特征的最优二值切分点 -> 决定最优特征以及最优切分点

CART剪枝, 从"完全生长"的决策树的底端剪去一些子树,使决策树变小(模型变简单), 从生成算法产生的决策树T_{0}底端开始不断剪枝,直到T_{0}的根节点,形成一个子树序列\left \{ T_{0}, T_{1}, ..., T_{n}\right \}, 然后通过交叉验证在独立的验证数据集上对子树序列进行测试,从而选择最优子树。

随机森林

bagging是一种在原始数据集上,通过有放回抽样分别选出k个新数据集,来训练分类器的集成算法。分类器之间没有依赖关系。

随机森林属于bagging集成算法。通过组合多个弱分类器,集思广益,使得整体模型具有较高的精确度和泛化性能。

我们将使用CART决策树作为弱学习器的bagging方法称为随机森林。

参考:随机森林(Random Forest) - 知乎 (zhihu.com)

  • 如果训练集大小为N,对于每棵树而言,随机且有放回地从训练集中的抽取N个训练样本(就是bootstrap sample方法, 拔靴法采样)作为该树的训练集;从这里我们可以知道:每棵树的训练集都是不同的,而且里面包含重复的训练样本。
  • 如果存在M个特征,则在每个节点分裂的时候,从M中随机选择m个特征维度(m << M),使用这些m个特征维度中最佳特征(最大化信息增益)来分割节点。在森林生长期间,m的值保持不变。

随机森林中的“随机”就是指的这里的两个随机性。两个随机性的引入对随机森林的分类性能至关重要。由于它们的引入,使得随机森林不容易陷入过拟合,并且具有很好得抗噪能力。随机森林对于降低模型方差效果显著。故随机森林一般不需要额外剪枝,就能取得较好的泛化性能。

构建随机森林的关键问题就是如何选择最优的特征数m这个参数,要解决这个问题主要依据计算袋外错误率OOB error(out-of-bag error)。

优点:

  • 采用了集成算法,精度优于大多数单模型算法
  • 在测试集上表现良好,两个随机性的引入降低了过拟合风险​
  • 树的组合可以让随机森林处理非线性数据
  • 训练过程中能检测特征重要性,是常见的特征筛选方法​
  • 每棵树可以同时生成,并行效率高,训练速度快
  • 可以自动处理缺省值

随机森林与GBDT树的对比

  • 集成学习: 都是集成学习方法, GBDT是Boosting思想, RF是Bagging思想
  • 树的类型:都是由多棵树组成, GBDT是CART回归树, RF分类树、回归树都可以
  • 并行化: GBDT的树只能顺序生成, RF的树可以并行生成
  • 优化指标: GBDT是偏差优化, RF是方差优化
  • 训练样本: GBDT是每次全样本训练, RF是有放回抽样训练
  • 最终结果: GBDT是多棵树累加之和, RF是多棵树进行投票表决

GBDT

GBDT是一种集成模型,采用的基础模型是CART回归树。(Gradient Boosting Decision Tree)

预测值与真实值之间的残差主要考虑两个方面:

  • 偏差,即与真实值分布的偏差大小
  • 方差,体现模型预测能力的稳定性,或者说鲁棒性

GBDT采用了多模型集成的策略,针对残差进行拟合,进而降低模型的偏差和方差。

Gradient Boosting: 拟合负梯度

当损失函数是平方损失和指数损失函数时,梯度提升树每一步优化是很简单的,但是对于一般损失函数而言,往往每一步优化起来不那么容易,针对这一问题,Friedman提出了梯度提升树算法,这是利用最速下降的近似方法,其关键是利用损失函数的负梯度作为提升树算法中的残差的近似值。

GBDT算法:

(1)初始化弱学习器f_{0}(x) = argmin_{c} \sum_{i = 1}^{N} L(y_{i}, c), 求得平均值c

(2)对于每一个样本,每一轮学习器, 计算负梯度,即残差r_{im} = -\left [ \frac{\partial L(y_{i}, f(x_{i}))}{\partial f(x_{i})} \right ]_{f(x) = f_{m - 1}(x)}

将数据(x_{i}, r_{im}), i = 1, 2, ... N作为下一棵树的训练数据, 得到一颗新的回归树f_{m}(x), 同时对叶子区域j = 1, 2, ... J计算最佳拟合值

\gamma_{jm} = \underbrace{argmin} \sum_{x_{i} \in R_{jm}} L(y_{i}, f_{m - 1}(x_{i}) + \gamma)

(3)更新强学习器

f_{m}(x) = f_{m - 1}(x) + \sum_{j = 1}^{J} \gamma_{jm} I(x \in R_{jm})

(4)得到最终学习器

f(x) = f_{M}(x) = f_{0}(x) = \sum_{m = 1}^{M} \sum_{j = 1}^{J} \gamma_{jm} I (x \in R_{jm})

GBDT参考:

GBDT算法原理以及实例理解

梯度提升树(GBDT)原理小结

(1) 在预测阶段,每个CART是独立的,因此可以并行计算。另外,得益于决策树的高效率,GBDT在预测阶段的计算速度是非常快的。

(2) 在训练阶段,GBDT里的CART之间存在依赖,无法并行,所以GBDT的训练速度是比较慢的。人们提出了一些方法,用来提升这个阶段的并行度,以提升学习速度。

(3) 使用了残差平方和作为损失函数,实际上还可以使用绝对值损失函数、huber损失函数等,从而让GBDT在鲁棒性等方面得到提升。

(4) GBDT的学习能力非常强,容易过拟合。大部分时候,我们都会给目标函数添加针对模型复杂度的惩罚项,从而控制模型复杂度。

XGBoost

参考:XGBoost算法原理小结

XGBoost(eXtreme Gradient Boosting)极致梯度提升,是GBDT的算法库,是GBDT的一种高效实现, 但是加入很多独有的思路和方法。

对比原算法GBDT, XGBoost优化:

        一是算法本身的优化:在算法的弱学习器模型选择上,对比GBDT只支持决策树,还可以选择很多其他的弱学习器。在算法的损失函数上,除了本身的损失,还加上了正则化部分。在算法的优化方式上,GBDT的损失函数只对误差部分做负梯度(一阶泰勒)展开,而XGBoost损失函数对误差部分做二阶泰勒展开,更加准确。算法本身的优化是我们后面讨论的重点。(重点

        二是算法运行效率的优化:对每个弱学习器,比如决策树建立的过程做并行选择,找到合适的子树分裂特征和特征值。在并行选择之前,先对所有的特征的值进行排序分组,方便前面说的并行选择。对分组的特征,选择合适的分组大小,使用CPU缓存进行读取加速。将各个分组保存到多个硬盘以提高IO速度。

        三是算法健壮性的优化:对于缺失值的特征,通过枚举所有缺失值在当前节点是进入左子树还是右子树来决定缺失值的处理方式。算法本身加入了L1和L2正则化项,可以防止过拟合,泛化能力更强。

XGBoost在GBDT损失函数L(y, f_{t - 1}(x) + h_{t}(x))的基础上, 加入正则化项\Omega(h_{t}) = \gamma J + \frac{\gamma}{2} \sum_{j = 1}^{J}w_{tj}^{2}, 其中J是叶子节点的个数, 而w_{tj}是第j个叶子节点的最优值。

XGBoost的损失函数为:L_{t} = \sum_{i = 1}^{m} L(y_{i}, f_{t - 1}(x_{i}) + h_{t}(x_{i})) + \gamma J + \frac{\gamma}{2} \sum_{j = 1}^{J}w_{tj}^{2}, 期望直接基于损失函数的二阶泰勒展开式来求解。

最终XGBoost损失函数可以表示为L_{t} = \sum_{j = 1}^{J}\left [ G_{tj}w_{tj} + \frac{1}{2}(H_{tj} + \lambda)w_{tj}^{2} \right ] + \lambda J

其中G_{tj} = \sum_{x_{i} \in R_{tj} } g_{ti}, H_{tj} = \sum_{x_{i} \in R_{tj} } h_{ti}g_{ti} = \frac{\partial L(y_{i}, f_{t-1}(x_{i}))}{\partial f_{t-1}(x_{i})}h_{ti} = \frac{\partial^2 L(y_{i}, f_{t - 1}(x_{i}))}{\partial f_{t-1}^{2}(x_{i})}

 损失函数优化求解

(1)已求出第t个决策树的J个最优的叶子节点区域, 如何求出每个叶子节点区域的最优解w_{tj}?

         基于损失函数对w_{tj}求导并令导数为0即可。得到叶子节点区域的最优解w_{tj}表达式为:

        w_{tj} = - \frac{G_{tj}}{H_{tj} + \lambda}

(2)对当前决策树做子树分裂决策时,应当如何选择特征和特征值,使得损失函数L_{t}最小 ?

        在GBDT中,直接拟合CART回归树, 故树节点分裂使用的是均方误差。XGBoost中不使用均方误差,而是使用贪心法,即每次分裂都期望最小化我们损失函数的误差。

        在我们w_{tj}取得最优解的时候,原损失函数对应的表达式为:L_{t} = - \frac{1}{2} \sum_{j = 1}^{J} \frac{G_{tj}^{2}}{H_{tj} + \lambda} + \gamma J 

如果我们每次做左右子树分裂时,可以最大程度的减少损失函数的损失就最好了。 

假设当前节点左右子树的一阶二阶导数和为G_{L}, H_{L}, G_{R}, H_{L}, 则我们期望最大化下式:

- \frac{1}{2} \frac{(G_{L} + G_{R})^{2}}{H_{L} + H_{R} + \lambda} + \gamma J - (- \frac{1}{2} \frac{G_{L}^{2} }{H_{L} + \lambda} - \frac{1}{2} \frac{G_{R}^{2}}{H_{R} + \lambda} + \gamma(J + 1))

故我们希望最大化max \frac{1}{2} \frac{G_{L}^{2}}{H_{L} + \lambda} + \frac{1}{2} \frac{G_{R}^{2}}{H_{R} + \lambda} - \frac{1}{2} \frac{(G_{L} + G_{R})^{2}}{H_{L} + H_{R} + \lambda} - \gamma

参考:XGBoost算法原理小结

           XGBoost类库使用小结

XGBoost算法运行效率的优化

        Boosting算法的弱学习器是没法并行迭代的,但是单个弱学习器里面最耗时的是决策树的分裂过程,XGBoost针对这个分裂做了比较大的并行优化。对于不同的特征的特征划分点,XGBoost分别在不同的线程中并行选择分裂的最大增益。

        对训练的每个特征排序并且以块的的结构存储在内存中,方便后面迭代重复使用,减少计算量。首先默认所有的样本都在右子树,然后从小到大迭代,依次放入左子树,并寻找最优的分裂点。这样做可以减少很多不必要的比较。

Adaboost

Boosting集成算法存在的问题

  • 如何计算学习误差率e
  • 如何得到弱学习器权重系数\alpha
  • 如何更新样本权重D
  • 使用何种结合策略

算法基本思路:

(1)第k个弱学习器的输出权重初始为平均, 计算第k个弱分类器在训练集上的加权误差率e_{k}

(2)第k个弱学习器的权重系数为\alpha_{k} = \frac{1}{2}log\frac{1 - e_{k}}{e_{k}},误差率越大, 权重系数越小

(3)更新样本权重D, 若分类错误, 则样本权重在第k+1个分类器中增大, 若分类正确, 则样本权重在第k+1个分类器中减少。

w_{k+1, i} = \frac{w_{ki}}{Z_{k}}exp(-\alpha_{k}y_{i}G_{k}(x_{i}))Z_{k} = \sum_{i = 1}^{m}w_{ki}exp(-\alpha_{k}y_{i}G_{k}(x_{i}))

(4)集合策略, Adaboost分类采用的是加权表决法, 最终的强分类器为f(x) = sign(\sum_{k = 1}^{K}\alpha_{k}G_{k}(x))

AdaBoost分类问题的损失函数优化

参考:集成学习之Adaboost算法原理小结

理论上任何学习器都可以用于Adaboost.但一般来说,使用最广泛的Adaboost弱学习器是决策树和神经网络。对于决策树,Adaboost分类用了CART分类树,而Adaboost回归用了CART回归树。

Adaboost的主要优点有:

  • Adaboost作为分类器时,分类精度很高
  • 在Adaboost的框架下,可以使用各种回归分类模型来构建弱学习器,非常灵活。
  • 作为简单的二元分类器时,构造简单,结果可理解。
  • 不容易发生过拟合

Adaboost的主要缺点有:

  • 对异常样本敏感,异常样本在迭代中可能会获得较高的权重,影响最终的强学习器的预测准确性。

集成学习总结:

  • boosting
  • bagging
  • stacking

你可能感兴趣的:(机器学习,机器学习)