随机森林(Random Forest)

来源:互联网 发布:java 短网址生成 编辑:程序博客网 时间:2024/04/28 20:20

       前言:因为有接触过随机森林的基础知识,学习机器学习课程的时候也遇到过,最近又深入学习一次,以此mark一下。

一. 什么是随机森林?

      作为新兴起的、高度灵活的一种机器学习算法,随机森林(Random Forest,简称RF)拥有广泛的应用前景,从市场营销到医疗保健保险,既可以用来做市场营销模拟的建模,统计客户来源,保留和流失,也可用来预测疾病的风险和病患者的易感性。最初,我是在师兄组会报告上接触随机森林算法的。最近几年的国内外大赛,包括2013年百度校园电影推荐系统大赛、2014年阿里巴巴天池大数据竞赛以及Kaggle数据科学竞赛,参赛者对随机森林的使用占有相当高的比例。此外,据我的个人了解来看,一大部分成功进入答辩的队伍也都选择了Random Forest 或者 GBDT 算法。所以可以看出,Random Forest在准确率方面还是相当有优势的。

        那说了这么多,那随机森林到底是怎样的一种算法呢?

  如果读者接触过决策树(Decision Tree)的话,那么会很容易理解什么是随机森林。随机森林就是通过集成学习的思想将多棵树集成的一种算法,它的基本单元是决策树,而它的本质属于机器学习的一大分支——集成学习(Ensemble Learning)方法。随机森林的名称中有两个关键词,一个是“随机”,一个就是“森林”。“森林”我们很好理解,一棵叫做树,那么成百上千棵就可以叫做森林了,这样的比喻还是很贴切的,其实这也是随机森林的主要思想--集成思想的体现。“随机”的含义我们会在下边部分讲到。

  其实从直观角度来解释,每棵决策树都是一个分类器(假设现在针对的是分类问题),那么对于一个输入样本,N棵树会有N个分类结果。而随机森林集成了所有的分类投票结果,将投票次数最多的类别指定为最终的输出,这就是一种最简单的 Bagging 思想。

二. 随机森林的优点与缺点

优点:

1.正如上文所述,随机森林算法能解决分类与回归两种类型的问题,并在这两个方面都有相当好的估计表现;

2.随机森林对于高维数据集的处理能力令人兴奋,它可以处理成千上万的输入变量,并确定最重要的变量,因此被认为是一个不错的降维方法。此外,该模型

能够输出变量的重要性程度,这是一个非常便利的功能。下图展示了随机森林对于变量重要性程度的输出形式:


3.在对缺失数据进行估计时,随机森林是一个十分有效的方法。就算存在大量的数据缺失,随机森林也能较好地保持精确性;

4.当存在分类不平衡的情况时,随机森林能够提供平衡数据集误差的有效方法;

5.模型的上述性能可以被扩展运用到未标记的数据集中,用于引导无监督聚类、数据透视和异常检测;

6.随机森林算法中包含了对输入数据的重复自抽样过程,即所谓的bootstrap抽样。这样一来,数据集中大约三分之一将没有用于模型的训练而是用于测试,这样的数据被称为out of bag samples,通过这些样本估计的误差被称为out of bag error。研究表明,这种out of bag方法的与测试集规模同训练集一致的估计方法有着相同的精确程度,因此在随机森林中我们无需再对测试集进行另外的设置。

实际上,随机森林的特点不只有这六点,它就相当于机器学习领域的Leatherman(多面手),你几乎可以把任何东西扔进去,它基本上都是可供使用的。在估计推断映射方面特别好用,以致都不需要像SVM那样做很多参数的调试。具体的随机森林介绍可以参见随机森林主页:Random Forest

缺点:

1.随机森林在解决回归问题时并没有像它在分类中表现的那么好,这是因为它并不能给出一个连续型的输出。当进行回归时,随机森林不能够作出超越训练集数据范围的预测,这可能导致在对某些还有特定噪声的数据进行建模时出现过度拟合。

2.对于许多统计建模者来说,随机森林给人的感觉像是一个黑盒子——你几乎无法控制模型内部的运行,只能在不同的参数和随机种子之间进行尝试。

三. 随机森林的基础知识

        随机森林看起来是很好理解,但是要完全搞明白它的工作原理,需要很多机器学习方面相关的基础知识。在本文中,我们简单谈一下,而不逐一进行赘述,如果有同学不太了解相关的知识,可以参阅其他博友的一些相关博文或者文献。

  1)信息、熵以及信息增益的概念

  这三个基本概念是决策树的根本,是决策树利用特征来分类时,确定特征选取顺序的依据。理解了它们,决策树你也就了解了大概。

  引用香农的话来说,信息是用来消除随机不确定性的东西。当然这句话虽然经典,但是还是很难去搞明白这种东西到底是个什么样,可能在不同的地方来说,指的东西又不一样。对于机器学习中的决策树而言,如果带分类的事物集合可以划分为多个类别当中,则某个类(xi)的信息可以定义如下:

                             

  I(x)用来表示随机变量的信息,p(xi)指是当xi发生时的概率。

  熵是用来度量不确定性的,当熵越大,X=xi的不确定性越大,反之越小。对于机器学习中的分类问题而言,熵越大即这个类别的不确定性更大,反之越小。

  信息增益在决策树算法中是用来选择特征的指标,信息增益越大,则这个特征的选择性越好。

  这方面的内容不再细述,感兴趣的同学可以看 信息&熵&信息增益 这篇博文。

  2)决策树

  决策树是一种树形结构,其中每个内部节点表示一个属性上的测试,每个分支代表一个测试输出,每个叶节点代表一种类别。常见的决策树算法有C4.5、ID3和CART。

  3)集成学习 

  集成学习通过建立几个模型组合的来解决单一预测问题。它的工作原理是生成多个分类器/模型,各自独立地学习和作出预测。这些预测最后结合成单预测,因此优于任何一个单分类的做出预测。

  随机森林是集成学习的一个子类,它依靠于决策树的投票选择来决定最后的分类结果。你可以在这找到用python实现集成学习的文档:Scikit 学习文档。

四. 随机森林训练过程

        随机森林属于非传统式的机器学习算法,由多颗决策树组成,每棵决策树处理的是一个训练样本子集。训练阶段,通过决策树的节点分裂来筛选特征,层层对样本进行细分,直至将每个训练样本子集分类正确,测试阶段,直接基于训练出的特征进行样本分类,所以测试速度较快(但训练速度较慢)。属于“傻瓜式”的策略(这点和adaboost很像很像),以下部分是标准随机森林训练阶段的大致流程。

  1)如果训练集大小为N,对于每棵树而言,随机且有放回地从训练集中的抽取N个训练样本(这种采样方式称为bootstrap sample方法),作为该树的训练集;

  从这里我们可以知道:每棵树的训练集都是不同的,而且里面包含重复的训练样本(理解这点很重要)。

  为什么要随机抽样训练集?

  如果不进行随机抽样,每棵树的训练集都一样,那么最终训练出的树分类结果也是完全一样的,这样的话完全没有bagging的必要;

  为什么要有放回地抽样?

  我理解的是这样的:如果不是有放回的抽样,那么每棵树的训练样本都是不同的,都是没有交集的,这样每棵树都是"有偏的",都是绝对"片面的"(当然这样说可能不对),也就是说每棵树训练出来都是有很大的差异的;而随机森林最后分类取决于多棵树(弱分类器)的投票表决,这种表决应该是"求同",因此使用完全不同的训练集来训练每棵树这样对最终分类结果是没有帮助的,这样无异于是"盲人摸象"。

  2)如果每个样本的特征维度为M,指定一个常数m<<M,随机地从M个特征中选取m个特征子集,每次树进行分裂时,从这m个特征中选择最优的;

  3)每棵树都尽最大程度的生长,并且没有剪枝过程。

  一开始我们提到的随机森林中的“随机”就是指的这里的两个随机性。两个随机性的引入对随机森林的分类性能至关重要。由于它们的引入,使得随机森林不容易陷入过拟合,并且具有很好得抗噪能力(比如:对缺省值不敏感)。

      从上面的步骤可以看出,随机森林的随机性体现在每颗数的训练样本是随机的,树中每个节点的分类属性也是随机选择的。有了这2个随机的保证,随机森林就不会产生过拟合的现象了。

     值得注意的是,随机森林的基本思想都一样,但是在细节上却有所不同,尤其是在节点分裂所采用规则,叶子节点确定那里,有着很多种变种,也就具有不同的效果。说一个我自己遇到的,在确定叶子节点那块,它不是采用属性和父节点一致来确定,而是属性为空来确定,因为它在每一个节点选择一个属性之后,都会将该属性从候选属性集中删除,这样就会造成叶子节点候选属性集为空的情况。

五. 袋外错误率(oob error:out of bag error)

       上面我们提到,构建随机森林的关键问题就是如何选择最优的m,要解决这个问题主要依据计算袋外错误率。

  随机森林有一个重要的优点就是,没有必要对它进行交叉验证或者用一个独立的测试集来获得误差的一个无偏估计。它可以在内部进行评估,也就是说在生成的过程中就可以对误差建立一个无偏估计。

  我们知道,在构建每棵树时,我们对训练集使用了不同的bootstrap sample(随机且有放回地抽取)。所以对于每棵树而言(假设对于第k棵树),大约有1/3的训练实例没有参与第k棵树的生成,它们称为第k棵树的oob样本。

  而这样的采样特点就允许我们进行oob估计,它的计算方式如下:

  (note:以样本为单位)

  1)对每个样本,计算它作为oob样本的树对它的分类情况(约1/3的树);

  2)然后以简单多数投票作为该样本的分类结果;

  3)最后用误分个数占样本总数的比率作为随机森林的oob误分率。

  (文献原文:Put each case left out in the construction of the kth tree down the kth tree to get a classification. In this way, a test set classification is obtained for each case in about one-third of the trees. At the end of the run, take j to be the class that got most of the votes every time case n was oob. The proportion of times that j is not equal to the true class of n averaged over all cases is the oob error estimate. This has proven to be unbiased in many tests.)

  oob误分率是随机森林泛化误差的一个无偏估计,它的结果近似于需要大量计算的k折交叉验证。

六. 随机森林的一个简单例子例子

描述:根据已有的训练集已经生成了对应的随机森林,随机森林如何利用某一个人的年龄(Age)、性别(Gender)、教育情况(Highest Educational Qualification)、工作领域(Industry)以及住宅地(Residence)共5个字段来预测他的收入层次。

  收入层次 :

    Band 1 : Below $40,000

    Band 2: $40,000 – 150,000

    Band 3: More than $150,000

  随机森林中每一棵树都可以看做是一棵CART(分类回归树),这里假设森林中有5棵CART树,总特征个数N=5,我们取m=1(这里假设每个CART树对应一个不同的特征)。

  CART 1 : Variable Age

  

  CART 2 : Variable Gender

  

  CART 3 : Variable Education

  

  CART 4 : Variable Residence

  

  CART 5 : Variable Industry

  

  我们要预测的某个人的信息如下:

  1. Age : 35 years ; 2. Gender : Male ; 3. Highest Educational Qualification : Diploma holder; 4. Industry : Manufacturing; 5. Residence : Metro.

  根据这五棵CART树的分类结果,我们可以针对这个人的信息建立收入层次的分布情况:

  

最后,我们得出结论,这个人的收入层次70%是一等,大约24%为二等,6%为三等,所以最终认定该人属于一等收入层次(小于$40,000)。

七.相关实现代码

  1)Fortran版本

  2)OpenCV版本

  3)Matlab版本

  4)R版本










1 0