zoukankan      html  css  js  c++  java
  • 第七章——集成学习和随机森林(Ensemble Learning and Random Forests)

    俗话说,三个臭皮匠顶个诸葛亮。类似的,如果集成一系列分类器的预测结果,也将会得到由于单个预测期的预测结果。一组预测期称为一个集合(ensemble),因此这一技术被称为集成学习(Ensemble Learning)。集成学习算法称作集成方法(Ensemble method)。

    例如,可以基于训练集的不同随机子集,训练一组决策树分类器。做预测是,首先拿到每一个决策树的预测结果,得票数最多的一个类别作为最终结果,这就是随机森林。

    此外,通常还可以在项目的最后使用集成方法。比如已经创建了几个不错的分类器,可以将其集成为一个更优秀的分类器。

    本章介绍了最手欢迎的分类器,包括bagging,boosting,stacking。

    7.1 投票分类器(Voting Classifiers)

    假如训练了一些分类器,如图7-1所示,

    7-1. 训练不同的分离器

    根据每一分类器的预测结果,我们选择得票最多的分类器作为最终预测结果,如图7-2所示。这种多数票决分类器被称作硬投票(hard voting)分类器。

    7-2. 硬投票分类器

    一般情况下,投票分类器会优于它所集成的每一个分类器。即使每一个单独的分类器都很弱(预测结果仅仅略高于随机猜测),集成分类器也可以很强,只要弱分类器是多种多样不同的分类器。

     为什么会这么神奇呢?假设一枚硬币有缺陷,会导致51%的概率正面朝上,49%的概率反面朝上。如果投掷1000次,大约会有510次正面朝上,490次反面朝上,大多是是朝上的。通过数学计算可知,投掷1000次,大部分正面朝上的概率是75%(可以根据林德贝格-勒维中心极限定理求得)。投掷的次数越多,这一概率越高(投掷10000次,这一概率是97%)。这是由于大数定律:在重复试验中,随着试验次数的增加,事件发生的频率趋于其期望。

    类似的,假设有1000个分类器,其单独的正确率仅有51%,通过多数票决预测分类,其正确率可达75%。不过,这需要分类器完全独立,错误不相关。但由于是在同样的数据集训练的,错误的类型可能相同,从而降低了正确率。

    如果分类器可以给出类别的概率(也就是具有predict_proba()方法),那么可以使Scikit-Learn的最终预测结果为平均概率最高的那一类别。这被称作软投票(soft voting)。软投票的性能一般优于硬投票。

    7.2 Bagging and Pasting

    另一种获得不同分类器的方法是,训练算法虽然是相同的,但训练数据确是从训练集中随机选取的不同子集。如果子集的选取是有放回采样(sampling with replacement。replace在这里是复位、归还的意思,不是代替的意思。),这一方法称为bagging(bootstrap aggregating的简称。在统计学上,有放回采样称为bootstrapping)。如果是无放回采样(sampling without replacement),则称之为pasting

    7.2.1 Bagging and Pasting in Scikit-Learn

    介绍了如何使用BaggingRegressor

    如图7-5所示,集成树和单个子树有大致相当的bias,但是前者的variance更小。(二者在训练集上的误差大致相当,但是集成树边界更规则,更容易一般化。)

    图7-5. 一棵决策树 Vs 500棵决策树bagging集成

    有放回抽样(Bootstrapping)生成的子集之间更具多样性,因此bagging比pasting具有稍高的bias,但是预测期之间的相关性也较小从而集成后的variance会减小。总体来说,bagging更优一些。

    7.2.2 Out-of-Bag评估

    使用bagging时,对于某一个预测器,某些样本可能被抽样多次,也有些样本可能从没被抽样到。事实上,对于每一个预测期,平均有63%的样本会被抽样到,剩下的从没有被抽到的37%样本称为out-of-bag (oob)样本。注意,对每个预测器,这是不同的37%样本。

    可以证明为什么平均37%的样本不会被抽到。假设样本总数是$m$,在$m$次有放回抽样中,一个样本始终没有被抽中的概率为$P(oob)= (1 - frac{1}{m})^m$,当$m$足够大时,

    egin{align*}
    lim_{m ightarrow +infty}(1 - frac{1}{m})^m &= lim_{m ightarrow +infty}(frac{m - 1}{m})^m \
    &= lim_{m ightarrow +infty}(frac{1}{frac{m}{m-1}})^m \
    &= lim_{m ightarrow +infty}(frac{1}{1 + frac{1}{m-1}})^m \
    &= lim_{m ightarrow +infty}frac{1}{(1 + frac{1}{m-1})(1 + frac{1}{m-1})^{m-1}} \
    &= lim_{m ightarrow +infty}frac{1}{(1 + frac{1}{m-1})e} \
    &= frac{1}{e} \
    &approx 0.37
    end{align*}

    对于某一个预测器来说,它并没有使用oob样本,因此该预测器可以使用oob样本进行评估,而不用专门划分出校验集。

    7.3 Random Patches and Random Subspaces

    BaggingClassifier也支持特征抽样,这通过超参数max_features和bootstrap_features控制。工作原理与max_samples和bootstrap类似,只不过把样本抽样替换成了特征抽样。

    这一方法在高维度输入(比如图像)是很有用。样本和特征均抽样称为Random Patches method,只对特征抽样称为Random Subspaces method

    7.4 随机森林(Random Forests) 

    随机森林是一系列决策树的集成,一般使用bagging方法。 

    7.4.1 Extra-Trees 

    在随机森林中生成一棵决策树时,会使用随机选择的特征子集,来切分数据集。还可以通过使用随机的阈值来增加随机性。这种更为随机的森林被称作Extremely Randomized Tree sensemble(简称Extra-Trees)。

    7.4.2 特征重要性(Feature Importance)

    如果观察一棵决策树,会发现越靠近根节点的特征越重要。可以通过计算一个特征在森林中的平均深度来评估其重要性。

    7.5 Boosting

    Boosting (最初被称作hypothesis boosting)是指所有可以联合一系类弱学习器使其成为强学习器的方法。其基本思想是循环地训练预测器,每一次都尝试更新其预测。现在有很多Boosting方法,最有名的是AdaBoost(Adaptive Boosting的简称)和Gradient Boosting

    7.5.1 AdaBoost

    这一技术技术在训练的时候,多关照一下预测错的实例 。例如,创建一个AdaBoost分类器。第一个分类器在训练集上训练并作出预测。然后误分类实例的权重就会增加。第二个分类器会在权重更新后的训练集上训练,然后预测、更新权重。重复这一过程,如图7-7所示。

    图7-7. AdaBoost更新实例权重并连续训练

    等所有预测器训练完成后,预测过程类似于bagging或者pasting,只不过每一个预测期根据其总体精度,会有不同的权重。

    AdaBoost算法存在一个劣势,那就是不能并行运算,因为后面预测器的训练,需要用到之前预测器的预测结果。

    AdaBoost详解:

    训练样本大小$m$,每一个实例权重$w^{(i)}$初始化设置为$frac{1}{m}$。第一个预测器进行训练,并计算训练集的加权误差率(weighted error rate)$r_1$。

    第$j$个预测器的加权误差率:

    egin{align*}
    r_j = frac{sum_{i=1,hat{y}_j^{(i)} eq y^{(i)}}^{m}w^{(i)}}{sum_{i=1}^{m}w^{(i)}}
    end{align*}

    其中,$hat{y}_j^{(i)}$ 是第$j$个预测器对第$i$个实例的预测值。

    预测器权重:

    egin{align*}
    alpha_j = eta \, log \, frac{1-r_j}{r_i}
    end{align*}

    其中,$eta$是学习率超参数(默认是1)。错误率越低,权重越大。错误率接近50%(也就是随机猜测),权重接近0。错误率低于50%,则权重是负的。可参考下图。

    实例的权重将按照如下方式更新:

    egin{align*}
    &for i = 1, 2, cdots ,m \
    &w_{(i)} leftarrow left{egin{matrix}
    w^{(i)} &if hat{y}_j^{(i)} = y_{(i)} \
    w^{(i)} exp(a_j) &if hat{y}_j^{(i)} eq y_{(i)}
    end{matrix} ight.
    end{align*}

    然后权重还要进行标准化。(也就是除以$sum_{i=1}^{m}w^{(i)}$)

    紧接着,一个新的预测试会使用更新后的权重,重复这一训练过程。如果预测器个数超过预定值,或者预测结果已经足够好,算法将会停止。

    AdaBoost算法的预测:

    egin{align*}
    mathop{argmax}limits_{k}mathop{sum_{j=1}^{N}}limits_{hat{y}_j(X)=k} a_j
    end{align*}

    其中,N是预测器个数。

    事实上,Scikit-Learn使用的是一用被称作SAMME(Stagewise Additive Modeling using a Multiclass Exponential loss function)的多分类版本 AdaBoost。如果仅仅是二分类,SAMME和AdaBoost是等价的。

    如果发现AdaBoost在训练集上过拟合,可以减少评估器的数量,或者增加更强的正则约束。

    7.5.2 Gradient Boosting

    与AdaBoost类似,Gradient Boosting也是不停地增加预测器。不同的是,Gradient Boosting新增加的预测器,回去拟合其前任的残差(residual errors)。该算法处理回归任务表现很好,被称作Gradient Tree Boosting或者Gradient Boosted Regression Trees (GBRT,梯度提升决策树)。

    与之类似的GBDT (Gradient Boosting Decision Tree)好像更出名一些。有空学习一下GBDT。

    7.6 Stacking

    stacking(stacked generalization的简称)是本章最后一个集成方法。该方法思想很简单:与其使用简陋的集成方法(比如硬投票),何不专门训练一个集成方法?图7-12展示了这一预测过程。底部的三个预测器给出了3个不同的结果(3.1、2.7、2.9),上面一个预测器(被称作混合器,blendor)根据这3个结果,给出了最终的预测(3.0)。

    图7-12. 通过混合预测器进行集成预测

    为了训练blender,常用的方法是使用一个hold-out数据集(hold-out set)。其工作方式如下:

    首先将训练集划分为两个子集,第一个子集用于训练第一层的预测器,如图7-13所示:

    图7-13. 训练第一层

    然后,使用第一层训练出的预测器对第二个子集(也成为hold-out集)进行预测。现在hold-out集有三个预测值。这三个预测值和hold-out集的目标值组成新的训练集,用于训练blender,如图7-14所示。

    图7-14. 训练blender

    此外,也可以再复杂一点,训练多个blender。把训练集分为3份。第一份训练第一层,第二份用于产生第二层的训练集,第三份用于产生第三次的训练集。其预测过程如图7-15所示。

    7-15. 多层stacking ensemble预测流程

     

     Scikit-Learn并不直接支持stacking,不过github有开源实现:https://github.com/viisar/brew

    参考文献:Spark随机深林扩展—OOB错误评估和变量权重

  • 相关阅读:
    part11-1 Python图形界面编程(Python GUI库介绍、Tkinter 组件介绍、布局管理器、事件处理)
    part10-3 Python常见模块(正则表达式)
    Cyclic Nacklace HDU
    模拟题 Right turn SCU
    状态DP Doing Homework HDU
    Dp Milking Time POJ
    区间DP Treats for the Cows POJ
    DP Help Jimmy POJ
    Dales and Hills Gym
    Kids and Prizes Gym
  • 原文地址:https://www.cnblogs.com/royhoo/p/Ensemble-Learning-and-Random-Forests.html
Copyright © 2011-2022 走看看