首页 > 代码库 > ML(4.3): R Random Forest

ML(4.3): R Random Forest

      随机森林模型是一种数据挖掘模型,常用于进行分类预测。随机森林模型包含多个树形分类器,预测结果由多个分类器投票得出。 决策树相当于一个大师,通过自己在数据集中学到的知识对于新的数据进行分类。俗话说得好,一个诸葛亮,玩不过三个臭皮匠。随机森林就是希望构建多个臭皮匠,希望最终的分类效果能够超过单个大师的一种算法。

     参考资料:

  • https://zhuanlan.zhihu.com/p/24416833
  • http://www.doc88.com/p-3436627023327.html
  • http://blog.csdn.net/f_yuqi/article/details/54095477

目录:

  • 相关概念
  • 预测效果影响因素
  • 估值过程
  • oob error
  • R实现

相关概念


  • 分类器:分类器就是给定一个样本的数据,判定这个样本属于哪个类别的算法。例如在股票涨跌预测中,我们认为前一天的交易量和收盘价对于第二天的涨跌是有影响的,那么分类器就是通过样本的交易量和收盘价预测第二天的涨跌情况的算法
  • 分裂:在决策树的训练过程中,需要一次次的将训练数据集分裂成两个子数据集,这个过程就叫做分裂。
  • 特征:在分类问题中,输入到分类器中的数据叫做特征。以上面的股票涨跌预测问题为例,特征就是前一天的交易量和收盘价。
  • 待选特征:在决策树的构建过程中,需要按照一定的次序从全部的特征中选取特征。待选特征就是在目前的步骤之前还没有被选择的特征的集合。例如,全部的特征是 ABCDE,第一步的时候,待选特征就是ABCDE,第一步选择了C,那么第二步的时候,待选特征就是ABDE。
  • 分裂特征:每一次选取的特征就是分裂特征,例如,在上面的例子中,第一步的分裂特征就是C。因为选出的这些特征将数据集分成了一个个不相交的部分,所以叫它们分裂特征。

预测效果影响因素


  • 随机森林的分类效果(即错误率)与以下两个因素有关
    1. 森林中任意两棵树的相关性:相关性越大,错误率越大
    2. 森林中每棵树的分类能力:每棵树的分类能力越强,整个森林的错误率越低
  • 减小特征选择个数m,树的相关性和分类能力也会相应的降低;增大m,两者也会随之增大。所以关键问题是如何选择最优的m(或者是范围),这也是随机森林唯一的一个参数。

估值过程


  • 指定m值,即随机产生m个变量用于节点上的二叉树,m的选择原则是使错误率最低。
  • 应用bootstrap自助法在原数据集中又放回地抽取k个样本集,组成k棵决策树,每个决策树输出一个结果。
  • 对k个决策树组成的随机森林对样本进行分类或预测:分类原则:少数服从多数;预测原则:简单平均。

oob error


  • 如何选择最优的特征个数m,要解决这个问题,我们主要依据计算得到的袋外错误率oob error(out-of-bag error)
  • OOB:在构造单棵决策树时我们只是随机有放回的抽取了N个样例,所以可以用没有抽取到的样例来测试这棵决策树的分类准确性,这些样例大概占总样例数目的三分之一(作者这么说的,我还不知道理论上是如何出来的,但是可以自己做试验验证)。所以对于每个样例j,都有大约三分之一的决策树(记为SetT(j))在构造时没用到该样例,我们就用这些决策树来对这个样例进行分类。我们对于所有的训练样例j,用SetT(j)中的树组成的森林对其分类,然后看其分类结果和实际的类别是否相等,不相等的样例所占的比例就是OOB错误估计。OOB错误估计被证明是无偏的。
  • 随机森林有一个重要的优点就是,没有必要对它进行交叉验证或者用一个独立的测试集来获得误差的一个无偏估计。它可以在内部进行评估,也就是说在生成的过程中就可以对误差建立一个无偏估计
  • 在构建每棵树时,对训练集使用了不同的bootstrap sample(随机且有放回地抽取)。所以对于每棵树而言,部分训练实例没有参与这棵树的生成,它们称为第k棵树的oob样本
  • 袋外错误率(oob error)计算方式如下:
    1. 对每个样本计算它作为oob样本的树对它的分类情况
    2. 以简单多数投票作为该样本的分类结果
    3. 最后用误分个数占样本总数的比率作为随机森林的oob误分率

R实现


  • 基本操作步骤如下:
    1. 包安装及数据预处理
    2. 遍历比较确定最优mtry值
    3. 选择合适的ntree参数值
    4. 建模与观察
  • 在R语言中,我们调用randomForest包中的randomForest()函数来实现随机森林算法,该函数中的决策树基于基尼指数(Gini index)构建,即CART分类决策树。不过该函数有两点不足:
    1. 第一,它不能处理缺失值,如果数据集有缺失值的话,我们必须在使用该函数之前填补;
    2. 第二,每个分类属性的最大数量不能超过32个,如果属性超过32个,那么在使用randomForest()之前那些属性必须被转化。
  • 安装程序包,查看样本数据结构
    > remove(list=ls())
    > 
    > #检验包是否安装
    > valiate <- any(grepl("randomForest",installed.packages()))
    > if (valiate == FALSE)
    + {
    +   install.packages("randomForest")
    + }
    > library(randomForest)
    > 
    > head(iris)
      Sepal.Length Sepal.Width Petal.Length Petal.Width Species
    1          5.1         3.5          1.4         0.2  setosa
    2          4.9         3.0          1.4         0.2  setosa
    3          4.7         3.2          1.3         0.2  setosa
    4          4.6         3.1          1.5         0.2  setosa
    5          5.0         3.6          1.4         0.2  setosa
    6          5.4         3.9          1.7         0.4  setosa
    > str(iris)
    data.frame:    150 obs. of  5 variables:
     $ Sepal.Length: num  5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
     $ Sepal.Width : num  3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
     $ Petal.Length: num  1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
     $ Petal.Width : num  0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
     $ Species     : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
  • 遍历比较确定最优mtry值。mtry参数是随机森林建模中,构建决策树分支时随机抽样的变量个数。选择合适的mtry参数值可以降低随机森林模型的预测错误率。示例的数据中共有4个自变量,可通过遍历设定mtry参数1至4进行4次建模,并打印出每次建模的错误率,选择错误率最低的mytry取值
    > #选择最优mtry参数值
    > n <- ncol(iris) -1
    > errRate <- c(1)
    > for (i in 1:n){  
    +  m <- randomForest(Species~.,data=http://www.mamicode.com/iris,mtry=i,proximity=TRUE)  
    +  err<-mean(m$err.rate)  
    +  errRate[i] <- err  
    + }  
    > print(errRate)
    [1] 0.05462878 0.04320072 0.04302654 0.04316091
    > #选择平均误差最小的m  
    >  m= which.min(errRate)  
    >  print(m)
    [1] 3
  • 根据遍历打印结果,当mtry=3时,错误率达到最低,因此本次建模过程中以3作为mtry参数值
  • 选择合适的ntree参数值: ntree参数指出建模时决策树的数量。ntree值设置过低会导制错误率偏高,ntree值过高会提升模型复杂度,降低效率。以mtry=3进行随机森林建模,并将模型错误率与决策树数量的关系可视化,如下:
     #选择最优ntree参数值
     rf_ntree <- randomForest(Species~.,data=http://www.mamicode.com/iris)
     plot(rf_ntree)
  •  结果图如下:

  • 技术分享
  • 从图中可以看到,当ntree=100时,模型内的误差就基本稳定了,出于更保险的考虑,我们确定ntree值为100。
  • 建模与观察:根据以上结果,以mtry=3,mtree=100为参数建立随机森林模型,并打印模型信息
    > m <- randomForest(Species~.,data=http://www.mamicode.com/traindata,mtry=3,ntree=100, proximity=TRUE)  
    >  print(m)
    
    Call:
     randomForest(formula = Species ~ ., data = http://www.mamicode.com/traindata, mtry = 3,      ntree = 100, proximity = TRUE) 
                   Type of random forest: classification
                         Number of trees: 100
    No. of variables tried at each split: 3
    
            OOB estimate of  error rate: 5.41%
    Confusion matrix:
               setosa versicolor virginica class.error
    setosa         39          0         0  0.00000000
    versicolor      0         33         3  0.08333333
    virginica       0          3        33  0.08333333
  •  importance()函数:用于计算模型变量的重要性

    > # importance()函数用于计算模型变量的重要性
    >  importance(m)
                 MeanDecreaseGini
    Sepal.Length         1.201101
    Sepal.Width          1.685455
    Petal.Length        32.926760
    Petal.Width         37.559478
    >  varImpPlot(m)
  •  图例:

  • 技术分享
  • 从返回的数据和图形可知,在四个变量中,Petal.Width和Petal.Length最为重要,其次分别是Sepal.Length和Sepal.Width
  • 接着使用已建立好的随机森林模型进行新数据集的测试,如:pred <- predict(m,newdata=http://www.mamicode.com/testdata)
  • 可通过绘制测试数据的预测边距图,数据点的边距为正确归类后的比例减去被归到其他类别的最大比例。一般来说,边距为正数说明该数据点划分正确,如下图:
  • 技术分享
  • 至此,一个简单的随机森林模型的R实现就完成了

ML(4.3): R Random Forest