[机器学习]adaboost(介绍)

364 阅读15分钟

总结

adaboost, 自适应增强算法。
用很多个弱学习器(基学习器),最终组成一个强学习器。

树桩stump,只有一个根节点和2个孩子节点,单层决策树。

每个stump的权重不同,weight = 1/2 * log((1-e)/e)
每个样本的权重,和所在树桩的权重是有关系的。
调整样本数据的权重,e的-weight次方  e的+weight次方
权重归一化,重新有放回随机抽取,构成新的数据分布的训练样本数据。

adaboost提供的是一个框架,其中可以是各种弱学习器,可以是cart决策树,当然也可以是别的弱学习器。

如果是cart决策树,那么原则上是既可以分类,也可以回归。
分类,又分为2分类和多分类。

每个树桩给出的预测结果是投票(分类),或者均值(回归)
最后采用加权投票的机制。

from sklearn.ensemble impot Adaboostclasiffier
from sklearn.ensemble import Adaboostregresision

对于每个树桩的每个叶子节点(一共就2个叶子节点,因为是二叉树),如何判断某条样本数据是分对了还是分错了呢?
首先对于每个叶子节点,我们先根据投票机制给出这个节点的预测结果,
然后那些与预测结果不同的样本数据就是分错了。
然后根据分错的样本的个数,计算该树桩的权重weight(每个树桩都有自己的权重,代表这个弱分类器的效果)
有了权重之后,就可以调整每条样本的权重了,
分对的样本降低权重,分错的样本增加权重(e-weight,e+weight)
调整完权重之后,对权重进行归一化,
然后[0,1]之间的随机数,有放回的抽样。
权重大的样本数据,被抽中的概率就大,因为是有放回的抽样,所以权重大的数据可能会被抽中多次。
这样数据的分布就发生了变化(这一点类似于随机森林,每棵决策树的训练数据都是不一样的,有放回的抽样,数据可能会重复),用这份不同数据分布的训练数据去训练下一棵树桩。

0/参考网址

haokan.baidu.com/v?pd=wisena… www.cnblogs.com/pinard/p/61…

用一句户来说就是:前人栽树,后人乘凉。
前辈为后辈创造条件,后辈在前辈的基础上继续改进。

image.png

1/前言

AdaBoost:Adaptive Boosting",自适应增强。
由Yoav Freund和Robert Schapire在1995年提出。
它的自适应在于:
    前一个弱学习器分错的样本的权重会在原来权重的基础上加强,
    前一个弱学习器分对的样本的权重会在原来权重的基础上减弱,
    权重调整后的训练数据,进行数据抽样构成新的数据分布,被用来训练下一个弱学习器。
    
adaboost是由多棵树桩stump(并不是一棵完整的树)构成的强学习器模型。
之所以称之为树桩,是因为该决策树只有一个根节点和2个叶子节点。
adaboost只是一个框架,所以其中可以是各种各样的弱学习器,可以是决策树,也可以是神经网络。
一般来说,选用的弱学习器是cart决策树。
既可以处理连续型数据,也可以处理离散型数据。
既可以用于分类,也可以回归。

在解决分类问题的时候,用的是度量指标是gini系数,gini系数越小越好,gini越小,代表的纯度越高。
每棵stump都有自己的一个总误差 total_error,根据这个误差,可以计算出该stump的权重weight,
公式为: weight = 1/2 * log(1-total_error)/total_error
从公式可以看出来:total error和weight 成反比。及误差越大,话语权越小,这也符合我们的认知。

样本权重的调整,也是根据weight来改变的。
分类正确的样本:e的-weight次方
分类错误的样本:e的weight次方
  
因为在sklearn扩展包中,有AdaBoostClassifier和AdaBoostRegressor两个类,
从名字就可以看出AdaBoostClassifier用于分类,AdaBoostRegressor用于回归。
所用的学习器,理论上是什么学习器都行,但是一般来讲,用的是cart决策树和神经网络。

adaboost整个强学习器构建完毕之后,每棵弱学习器都有自己的权重weight,这个weight跟准确率有关系。
最后,加权求和,weight最大的类别就是最终的预测类别。

adaboost的核心思想:
   Adaboost是一种迭代算法,针对同一份训练集合,训练不同的弱学习器(树桩stump),
   然后把这些弱学习器聚合起来,构成一个强大的强学习器。
   
 Adaboost算法本身是通过改变样本数据分布来实现的,它根据每次训练集之中每个样本的分类是否正确,以及上次的总体分类的准确率,来确定每个样本的权值。将修改过的新数据集送给下层弱学习器进行训练,最后将每次得到的分类器最后融合起来,作为最后的决策分类器。
 
是boosting集成学习思想的典型代表算法。

2/adaboost算法的迭代步骤

Adaboost 迭代算法就3步:
 <1>初始化训练数据的权值分布。
    一份训练数据,
    如果有N个样本(正负样本的总和),则每一个训练样本最开始时都被赋予相同的权值:1/N。
 
 <2>迭代训练弱分类器。
    
    具体训练过程中,对于分类错误的样本,加大其对应的权重(原来的权重*e的weight次方);
    而对于分类正确的样本,降低其权重(原来的权重*e的负weight次方)。
    这样分错的样本就会被突显出来(因为权重大,被抽样出来的次数就多),从而得到一个新的样本分布。
    拿着新的样本分布,去训练下一颗树桩stump,得到一个新的弱学习器。
    依次类推,经过T次循环,得到T个弱学习器。
    注意:每次迭代改变的是训练样本数据的分布。
    
 <3>将各个训练得到的弱学习器组合成强分类器。
    把这T个弱学习器按一定的权重叠加(boost)起来,得到最终想要的强分类器。

3/adaboost算法具体步骤

我们先训练一个模型(弱学习器),然后对这个弱学习器进行评估(计算准确率),
对做对的问题,减少注意力(及减少它的困难度),对做错的问题,增加注意力(增加它的困难度)。

image.png

在第一次训练模型的时候,每个样本的权重都是一样的,都是1/N。
然后在训练的过程中,对于分类正确的样本,较低它的权重(及降低它的曝光度)
对于分类错误的样本,增加它的权重(及增加它的曝光度)。
这样,在下一次的训练中,原本困难的就可能被做对,这样对于更加困难的,会再次增加困难度(及权重,或者会说是注意力)

image.png

adaboost的优缺点: 

image.png

4/AdaBoost的特点

adaboost是一种更高级的「森林」类型的决策树模型,和随机森林RF比起来,它有以下三个特点

<1>AdaBoos的每棵树都只有一个根节点和两个叶子节点,实际上叫树桩(stump)可能会更合适。
    也就是说,adaboost从根节点开始,只根据特征的gini系数进行一次分裂。
    
<2>AdaBoost的每个树桩(弱学习器)的权重是不同的,而随机森林中的每棵树的权重是相同的
    adaboost每棵弱学习器的准确率都是不同的的,所以它们的话语权是不一样的,虽然最后也是采用投票的方式,但是先经过加权求和,然后再投票选出一个weight大的。
    而随机森林,每棵弱学习器都是一个臭皮匠,每个臭皮匠的话语权是相同的,最后采用投票的机制,少数服从多数

<3>前一个树桩的错误数据会影响后一个树桩的生成,意味着后面的树桩是前面树桩的补足。
   这种思想也被称为Boost, AdaBoost外,GBDT和XGBoost也是这样的思想

5/adaboost的具体生成步骤

<1>假设我们有以下的训练数据,我们想通过胸口疼痛、血管堵塞和体重这三个特征来训练一个心脏病预测模型:

image.png

<2>首先,我们需要为每一条样本数据赋予一个相同的权重,
   因为只有8条数据,所以每一条样本的权重都是1/8

image.png

<3>接下来,我们利用gini系数(不纯度的一种度量指标,另一种度量指标是熵)在这3个特征中找到一个最合适的特征作为树根。
经过计算,当体重>176时,基尼不纯度最小(及纯度最大,及gini系数最小),则第一个树桩的节点为体重 >176,如下图所示:
   胸口疼痛的gini系数是0.47,
   血管堵塞的gini系数是0.5,
   体重的gini系数是0.2

image.png

<4>产生出一个树桩之后,我们找到错误分类的样本数据,计算这棵树桩的总误差total_error,
   从而计算出该树桩的权重weight
   从上图我们可以知道,根据体重>176分割之后,只有一条样本数据是判断错误的,如下所示:

image.png

  所以,该树桩的总误差(total error)即这条样本的权重0.125。
  通过该树桩的总误差,我们可以计算出该树桩的权重weight.
  权重weight的计算公式如下所示:

image.png

  该公式的曲线如下图所示,可以看到,随着误差越大,树桩的Weight越小.
  上例中,我们的误差为0.125,所对应的Weight为0.973,也就是图中蓝色点所处的位置:

image.png

<5>调整样本数据的权重,随机抽样,作为第二棵树桩stump的训练数据。
   前面说了,后一棵树桩stump的生成依赖于前一棵stump的误差。
   具体的,我们会根据这个误差total errer来调整每个样本的权重。
   这样后面的stump就可以根据样本的新权重来训练了。
   更近一步,前一棵树桩中判断错误的样本,我们希望增加权重,同时降低判断正确的样本。
   这样下一棵树桩会更加倾向于把判断错误的样本处理好,起到了对前面树桩的补足作用。
   
   错误样本权重和正确样本权重的调整分别如下面左图和右图所示:
   对于分类错误的样本,增加其权重:e的weight次方
   对于分类正确的样本,降低其权重:e的-weight次方

image.png

对于本例来说,第一个树桩的 Weight 为 0.973,
则错误样本的权重根据左图公式,将调整为 0.125 × 2.646 = 0.33 ,
同理,正确样本的权重根据右图公式,将调整为 0.125 × 0.378 = 0.05,
归一化后,最终所有样本的权重调整如下:

image.png

为什么要进行归一化?
   因为我们需要进行随机抽样,进行数据分布,组成下一棵树的训练数据。

<6>接下来,我们需要根据新的特征来训练树桩.
   其中的一种办法是根据权重来抽样,即在每抽一条数据之前,产生一个0-1的随机数,根据随机数来决定抽取哪条样本数据。
   以上面的数据为例,当随机数落在[0,0.07]之间的时候,则抽出第一条样本数据(序号1),
   当随机数落在[0.07,0.14]之间的时候,则抽出第二条样本数据(序号2),
   当随机数落在[0.14,0.21]之间的时候,则抽出第三条样本数据(序号3),
   当随机数落在[0.21,0.7]之间的时候,则抽出第四条样本数据(序号4),因为范围大,所以随机数落在这个区间的概率也大,所以序号4这条数据可能会被多次抽中。这样在新的数据分布中,这条数据的曝光度也大。
   
   抽样完毕之后,我们重新对这些数据赋予相等的权重,如下所示:
   可见,第4条数据被重复抽出来多次(因为它的权重大),使用这些数据训练后,新的树桩会更加倾向于把这条数据(第4条)分类正确,因为在训练时,重复的样本会受到更大的惩罚。

image.png

接下来的步骤和之前的一样。

6/adaboost的预测

在构建完adabost模型之后,我们该如何预测呢?
预测过程和随机森林类似,都是用每棵树的结果来投票vote,

每棵树桩的预测结果是采用投票vote,
因为每个树桩只有一个根节点和2个孩子节点。
节点中采用投票(分类),均值(回归)的方式给出预测值。

最后在得到最终的预测值的时候,是采用加权投票。

差别在于:这里是采用的加权投票。
假设我们有一条真实的数据,放在这个模型中来预测, 每棵树对该条数据的预测结果如下所示:

image.png

集合之后,把相同预测结果的weight加起来,如下:    

image.png

取weight较大者,所示该条数据最终的预测结果是1

7/adaboost如何处理连续型特征和离散型特征

因为adaboost的弱学习器的类型是cart决策树,
所以其处理连续或者离散特征的方式和cart是一样的。
对于离散特征,就是不断进行二分类,然后计算gini。
对于连续特征,先排序,针对每相邻的2个特征值,计算均值,然后分割,计算mse。

8/adaboost的优缺点

AdaBoost算法优点
    1、精度高
    
    2、adaboost算法提供的是框架,可以使用各种类型的弱学习器。
       弱学习器的类型不是一成不变的,不仅仅支持cart决策树,还支持别的。
       因为adaboost模型中的弱学习器是一个树桩,主要作用就是根据某个特征值把数据集D分成2部分。
       所以,弱学习器的类型不是一成不变的,只要可以进行分类,可以处理离散特征和连续特征就可以。
       
    3、简单,不用做特征的筛选
    
    4、样本数据可以赋予权重,每棵弱学习器也赋予了权重,该优点可以提高模型的精度。
       这一点和RF不同,每棵决策树的权重都是一样的。
       
    5、不用担心过拟合

Adaboost算法缺点
    1、AdaBoost迭代次数也就是弱分类器数目不太好设定,可以使用交叉验证来进行确定。
    2、数据不平衡导致分类精度下降。
    3、训练比较耗时
    4、对异常点敏感

9/adaboost为啥不容易过拟合

通常,过拟合现象指的是下图描述的这种现象,
即随着模型的不断训练,训练误差在不断下降,
实际上,模型的泛化误差(测试误差)在上升。
横轴表示迭代的次数,纵轴表示训练误差的值。

image.png

而实际上,并没有观察到adaboost算法出现这样的情况,即当训练误差小到一定程度以后,继续训练,泛化误差仍然不会增加。
通过引入margin的概念,我们可以观察到下图所出现的现象:
从下图左边的子图可以看到,随着训练次数的增加,test的误差率并没有升高,
同时对应着右边的子图可以看到,随着训练次数的增加,margin一直在增加。
这就是说,在训练train误差下降到一定程度以后,更多的训练,会增加分类器的分类margin,这个过程也能够防止测试误差的上升。

image.png

10/adaboost的二分类和多分类

原则上,adaboost既可以进行二分类,也可以多分类。
因为adaboost提供的是一个框架,它支持多种弱学习器。
比如当选择cart为弱学习器的时候,因为cart是二叉树,所以此时适合解决二分类问题。
如果选择一个多分类的学习器作为adaboost的弱分类器,则可以解决多分类问题。

11/adaboost总结

1.每棵树只有一个根节点和两个叶子节点,是一个树桩(单层决策树)
2.后一棵树桩的训练数据和前一棵树桩的误差决定,
   具体来说是根据前一棵树桩的误差error,计算权重weight,
   然后调整样本数据的权重,对权重进行归一化,然后有放回的进行抽样,权重大的样本可能会被抽取多次。
   这样新的数据分布就构成了,作为下一棵树桩的训练数据。
   
3.每棵树都有不同的权重weight,预测时会根据权重来聚合预测结果.
4.理论上任何学习器都可以用于Adaboost.
  但一般来说,使用最广泛的Adaboost弱学习器是决策树和神经网络。
  对于决策树,Adaboost分类用了CART分类树,而Adaboost回归用了CART回归树。

5/adaboost的性能起点低,但是性能天花板高。
   也就是说:你可以把模型训练得很好,当然也可能训练得很差。

6/每棵树桩的每个叶子节点的预测结果,是采用投票机制得到的(vote,分类问题)