分类算法 - 随机森林

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了分类算法 - 随机森林相关的知识,希望对你有一定的参考价值。

参考技术A

上次我写了决策树算法,决策树可以解决分类问题,也有CART算法可以解决回归问题,而随机森林也和决策树非常类似,采用了CART算法来生成决策树,因此既可以解决分类问题,也可以解决回归问题。从名字中可以看出,随机森林是用随机的方式构建的一个森林,而这个森林是由很多的相互不关联的决策树组成。实时上随机森林从本质上属于机器学习的一个很重要的分支叫做集成学习。集成学习通过建立几个模型组合的来解决单一预测问题。它的工作原理是生成多个分类器/模型,各自独立地学习和作出预测。这些预测最后结合成单预测,因此优于任何一个单分类的做出预测。
所以理论上,随机森林的表现一般要优于单一的决策树,因为随机森林的结果是通过多个决策树结果投票来决定最后的结果。简单来说,随机森林中每个决策树都有一个自己的结果,随机森林通过统计每个决策树的结果,选择投票数最多的结果作为其最终结果。我觉得中国一句谚语很形象的表达了随机森林的运作模式,就是“三个臭皮匠,顶个诸葛亮”。

我有一批100条的数据,通过颜色、长度、甜度、生长地方和水果类别,那么我要预测在某种颜色、长度、甜度和生长地方的水果究竟是什么水果,随机森林要怎么做呢?

这里的抽样是指的在这批水果中,有放回地抽样,比如我要生成3个决策树来预测水果种类,那么每棵树要抽样50条数据来生成,每棵树抽取数据后数据要放回,下一棵树抽取数据仍然要从100条数据里面抽取。这种方法就叫做 bootstrap重采样技术

每棵树利用抽取的样本生成一棵树,值得注意的是,由于采用的是CART算法,因此生成的是二叉树,并且可以处理连续性数据。如果每个样本的特征维度为M,像以上提到的数据,样本特征维度5,指定一个常数m<<M,随机地从5个特征中选取m个特征子集 (这一点非常重要,这也是随机森林的随机这个名字的来源,因此这样才能保证生成的决策树不同) ,每次树进行分裂时,从这m个特征中选择最优的,并且每棵决策树都最大可能地进行生长而不进行剪枝。
此时,一颗茂盛的决策树就生成了。

根据3颗决策树的结果,如果是连续型的数据最终需要求均值获得结果,如果是分类型的数据最后求众数获得结果。

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

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

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

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

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

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

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

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

随机森林算法

随机森林

1.1定义

  • 随机森林是一种有监督学习算法,是以决策树为基学习器的集成学习算法。
  • 随机森林非常简单,易于实现,计算开销也很小,在分类和回归表现出非常惊人的性能,因此,随机森林被誉为"代表集成学习技术水平的方法"

1.2随机森林的随机性体现的方面

  • 数据集的随机选择
    • 从原始数据集中采取《有放回的抽样bagging》,构造子数据集,子数据集的数据量和原始数据集相同,不同子数据集的元素可以重复,同一子数据集中的元素也可以重复
  • 待选特征的随机选取
    • 随机森林中的子树的每一个分裂过程并未用到所有的待选特征,而是从所有的待选特征中随机选取一定的特征,之后再随机选取的特征中选取最优的特征

1.3 随机森林的重要作用

  • 可用于分类问题和回归问题
  • 可以解决模型过拟合的问题,如果随机森林中的树足够多,那么分类器就不会出现过拟合
  • 可以检测出特征的重要性,从而选取好的特征

1.4 随机森林的构建过程

  • 1.从原始数据集中随机有放回采样取出m个样本生成m个训练集
  • 2.对m个训练集,分别训练m个决策树模型
  • 3.对于单个决策树模型,假设训练样本特征的个数为n,每次分裂时根据信息增益/信息增益比/基尼系数,选择最好的特征进行分裂
  • 4.将生成的多棵决策树组成随机森林,对于分类问题,按照多棵树分类器投票决定最终分类的结果;对于回归问题,由多棵树预测值的均值决定最终预测结果

1.5 随机森林的优缺点

  • 优点
    • 采用了集成算法,本身精度比大多数单个算法要好,即准确性高
    • 两个随机性引入,使得随机森林不容易陷入过拟合(样本随机,特征随机)
    • 两个随机性引入,使得随机森林具有一定的抗噪声能力,对比其它算法具有一定的优势
    • 能够处理很高的维度(feature很多)的数据,并且不同做特征选择,对数据集的适应能力强:即能处理离散型数据,也能处理连续型数据
    • 在训练过程中,能够检测到feature间的互相影响,且可以得出feature的重要性,具有一定的参考意义
  • 缺点
    • 当随机森林中的决策树个数很多时,训练时需要的空间和时间会比较大

2. 随机森林参数描述

  • 分类参数
参数含义
n_estimators树的数量,即基评估器的数量。这个参数对随机森林模型的精确性影响是单调的,n_estimators越大,模型的效果越好。但是,任何一个模型都有决策边界,n_estimators达到一定的程度之后,随机森林的精确性往往不在上升或开始波动,并且,n_estimators越大,需要的计算量和内存也越大,训练的时间也会越来越长,对于这个参数,希望在训练难度和模型效果之间取得平衡;默认值在现有版本的sklearn中是10,但是在即将更新的0.22版本中,这个默认值会被修正为 100
random_state控制生成森林的模式,用来固定森林中树的随机性,当random_state固定时,随机森林中生成是一组固定的树
bootstrap控制抽样技术参数,boostrap默认为TRUE,代表采用有放回的随机抽样技术
oob_score被忽略或者一次都没被采集到的样本叫做obb袋外数据;即在使用随机森林时,可以不划分测试集和训练集,用袋外数据即可测试;将oob_score=True,训练完毕后,可以用obb_score_查看在袋外数据上的测试结果
cirterion不纯度衡量指标,有基尼系数和信息熵两种选择
max_depath树的最大深度,超过最大深度的树枝都会剪掉
min_samples_leaf一个节点在分枝后的每个子节点都必须包含至少min_samples_leaf个训练样本,否则分支都不会发生
min_samples_split一个节点必须包含至少min_samples_split个训练样本,这个节点才允许分枝,否则不允许分枝
max_features限制分枝时考虑的特征个数,超过限制个数的特征都会被舍弃,默认值为总特征个数开平方取整
min_impurity_decrease限制信息增益的大小,信息增益小于设定数值的分枝不会发生
  • 回归参数
    • from sklearn.ensemble import RandomForestRegression
  • 所有参数,属性,接口,全部和随机分类器一致,仅有不同的就是回归树与分类树的不同,不纯度指标,参数Criterion不一致
  • Criterion参数,回归树衡量分支质量的指标,支持的标准有三种
参数含义
mse使用均方误差(mean squared error(MSE),父节点与子节点之间的均方误差的差额将被用来作为特征选择的标准,这种方法通过使用叶子结点的均值来最小化L2损失
friedman_mse使用费尔德曼均方误差,这种指标使用费尔德曼针对潜在分支中的问题改进后的均方误差
mae使用绝对平均误差(mean absolute error),这种指标使用叶节点的中值来最小化L1损失

3. 分类随机森林的代码实现

  • 分类

    • from sklearn.ensemble import RandomForestClassifier
  • obb_score_重要参数

    from sklearn.ensemble import RandomForestClassifier
    from sklearn.datasets import load_wine
    wine=load_wine()
    rfc=RandomForestClassifier(n_estimators=25,oob_score=True)
    rfc=rfc.fit(wine.data,wine.target)
    rfc.oob_score_  #0.9606741573033708
    
  • 随机森林与决策树的效果对比

    from sklearn.tree import DecisionTreeClassifier
    from sklearn.ensemble import RandomForestClassifier
    from sklearn.datasets import load_wine
    from sklearn.model_selection import train_test_split
    wine=load_wine()
    #随机森林与决策树的对比
    x_train,x_test,y_train,y_test=train_test_split(wine.data,wine.target,test_size=0.3)
    clf=DecisionTreeClassifier(random_state=0)
    rfc=RandomForestClassifier(random_state=0)
    clf=clf.fit(x_train,y_train)
    rfc=rfc.fit(x_train,y_train)
    score_c=clf.score(x_test,y_test)
    score_r=rfc.score(x_test,y_test)
    print(score_c,score_r)  #0.8518518518518519 0.9629629629629629
    
  • 随机森林与决策树在一组交叉验证下的效果对比

    from sklearn.tree import DecisionTreeClassifier
    from sklearn.ensemble import RandomForestClassifier
    from sklearn.datasets import load_wine
    from sklearn.model_selection import cross_val_score
    import matplotlib.pyplot as plt
    %matplotlib inline
    wine=load_wine()
    rfc=RandomForestClassifier(n_estimators=25)
    rfc_s=cross_val_score(rfc,wine.data,wine.target,cv=10)
    clf=DecisionTreeClassifier()
    clf_s=cross_val_score(clf,wine.data,wine.target,cv=10)
    plt.plot(range(1,11),rfc_s,label='RandomForest')
    plt.plot(range(1,11),clf_s,label='DecisionTree')
    plt.legend()
    plt.show()
    

  • 随机森林与决策树在十组交叉验证下的效果对比

    from sklearn.tree import DecisionTreeClassifier
    from sklearn.ensemble import RandomForestClassifier
    from sklearn.datasets import load_wine
    from sklearn.model_selection import cross_val_score
    import matplotlib.pyplot as plt
    %matplotlib inline
    wine=load_wine()
    rfc_l=[]
    clf_l=[]
    for i in range(10):
        rfc=RandomForestClassifier(n_estimators=25)
        rfc_s=cross_val_score(rfc,wine.data,wine.target,cv=10).mean()
        rfc_l.append(rfc_s)
        clf=DecisionTreeClassifier()
        clf_s=cross_val_score(clf,wine.data,wine.target,cv=10).mean()
        clf_l.append(clf_s)
        
    plt.plot(range(1,11),rfc_l,label="RangeForest")
    plt.plot(range(1,11),clf_l,label='DecisionTree')
    plt.legend()
    plt.show()
    

以上是关于分类算法 - 随机森林的主要内容,如果未能解决你的问题,请参考以下文章

随机森林算法

随机森林原理

随机森林

决策树、随机森林

spark 随机森林算法案例实战

Spark Random Forest classifier 随机森林分类