0-写在前面

随机森林,指的是利用多棵树对样本进行训练并预测的一种分类器。该分类器最早由Leo Breiman和Adele Cutler提出。简单来说,是一种bagging的思想,采用bootstrap,生成多棵树,CART(Classification And Regression Tree)构成的。对于每棵树,它们使用的训练集是从总的训练集中有放回采样出来的,这意味着,总的训练集中的有些样本可能多次出现在一棵树的训练集中,也可能从未出现在一棵树的训练集中。对于一个有n行的数据集,out of bag 的概率大概是1/e=1/3。n趋向无穷大的时候,(1-1/n)^n~1/e。

选择的是The Elements of Statistical Learning 这本教材进行学习。

原因有两个1.翻了这本书在豆瓣的评论,看到的是评论者对这本书满满的敬仰! 2.女神的博客上有这本书的上课笔记(有中文笔记看,才是重点)

1-随机森林算法特色

因为之前有用过randomForest这个包,所以就先从自己最熟悉的算法开始。

先说说随机森林有哪些特色,我就简单翻译下[1]上面写的

  1. 在与其它现有的算法相比,其预测准确率很好
  2. 在较大的数据集上计算速度依然很快
  3. 不需要降维,算法本身是采取随机降维的
  4. 他能处理有缺失值的数据集。算法内部有补缺失值的函数
  5. 能给出变量的重要性
  6. 能处理imbalanced data set
  7. 能给出观测实例间的相似度矩阵,其实就是proximity啦,继而能做clustering 和 location outlier
  8. 能对unlabeled data 进行无监督的学习,进行clustering
  9. 生成的森林可以保留,应用在新的数据集上

个人感觉最重要的是1-6。7-9我并没找到很有说服力的例子能证明随机森林在这几方面也很强。

2-根据其特色说一说随机森林算法

先说4,随机森林是如何补全缺失值的。主要参考资料[1]、[2]

前提:训练数据集中label(被解释变量)一定要有,不然这条观测实例你为何拿他来学习模型?

randomForest包里,有两种补全缺失值的方法。

方法一(na.roughfix)简单粗暴,对于训练集,同一个class下的数据,如果是分类变量缺失,用众数补上,如果是连续型变量缺失,用中位数补。

方法二(rfImpute)这个方法计算量大,至于比方法一好坏?不好判断。他只能补训练集中的缺失值。是先用na.roughfix补上缺失值,然后构建森林并计算proximity matrix,再回头看缺失值,如果是分类变量,则用没有缺失的观测实例的proximity中的权重进行投票。如果是连续型变量,则用proximity矩阵进行加权平均的方法补缺失值。然后迭代4-5次。这个补缺失值的思想和KNN有些类似。

  1. ################ imputation ################
  2. library(kernlab)
  3. library(magrittr)
  4. data(spam)
  5. spam.na <- spam
  6. set.seed(111)
  7. ## artificially drop some data values.
  8. for (i in 1:57) spam.na[sample(length(spam[,1]), length(spam[,1])/10), i] <- NA
  9. ## calculate missing value ratio for coloumns
  10. missingvalue.ratio <- function(df){
  11. df <- as.data.frame(df)
  12. res <- is.na(df)%>%colSums()/length(df[,1])
  13. return(res)
  14. }
  15. missingvalue.ratio(spam.na)
  16. # na.roughfix impute
  17. spam.roughfix <- na.roughfix(spam.na)
  18. randomForest(type ~ ., data=spam.roughfix)
  19. # in another way
  20. randomForest(type ~ ., data=spam.na, na.action = na.roughfix)
  21. #rfImpute
  22. spam.rfImpute <- rfImpute(type~.,data=spam.na,iter=2,ntree=300)
  23. randomForest(type ~ ., data=spam.rfImpute)

对于7,proximity matrix

这个据说是randomForest中的亮点? [1]中说proximity are one of the most useful tools in random forests,[3]中写到The proximity matrix can be used to identify structure in the data (see Breiman, 2002) or for unsupervised learning with random forests 。

前面的rfImpute就是基于proximity matrix的,proximity matrix其实就是任意两个观测实例间的相似度矩阵。原理是如果两个观测实例落在同一棵树的同一个叶子节点的次数越多,则这两个观测实例的相似度越高。这个矩阵进行了归一化,就是除以ntree,你种了多少颗树。很简单的思想。

  1. library(kernlab)
  2. library(randomForest)
  3. data(spam)
  4. set.seed(1)
  5. rf <- randomForest(type~.
  6. ,data=spam
  7. ,importance=TRUE
  8. ,proximity=FALSE
  9. ,ntree=300
  10. ,do.trace=20
  11. ,na.action=na.omit
  12. ,mtry=7
  13. ,keep.forest=FALSE)

以上代码中设置proximity=TRUE就可以得到这个矩阵了。对很大的数据集,请慎用,对于一个有n个观测值的数据集,他会生成一个n*n的矩阵,spam是4601行,生成4601*4601的矩阵,就是160m在内存中。

对于5.能给出变量的重要性

这里借鉴[3]中的一段代码,自己改了一下。查看变量重要性,无非就是进行feature selection,降低模型的复杂度的同时获取较好的预测准确率。

  1. par(mfrow = c(2,2))
  2. for(i in 1:4){
  3. plot(sort(rf$importance[,i],decreasing =TRUE)%>%head(20)
  4. ,type='h'
  5. ,main=paste0(colnames(rf$importance)[i])
  6. ,xlab='variable'
  7. ,ylab='importance')
  8.  
  9. text(sort(rf$importance[,i],decreasing =TRUE)
  10. ,labels=names(sort(rf$importance[,i]))%>%head(20)
  11. ,pos=1
  12. ,cex=0.9)
  13. }

以上代码能画出变量重要性的图,如下。(spam数据集有57个解释变量,为了能看清图,变量重要性排名只取前20)

衡量变量重要性的方法有两种,Decrease GINI 和Decrease Accuracy

Decrease GINI: 引用一篇博客中很好的解释。对于分类问题(将某个样本划分到某一类),也就是离散变量问题,CART使用Gini值作为评判标准。定义为Gini=1-∑(P(i)*P(i)),P(i)为当前节点上数据集中第i类样本的比例。例如:分为2类,当前节点上有100个样本,属于第一类的样本有70个,属于第二类的样本有30个,则Gini=1-0.7×07-0.3×03=0.42,可以看出,类别分布越平均,Gini值越大,类分布越不均匀,Gini值越小。在寻找最佳的分类特征和阈值时,评判标准为:argmax(Gini-GiniLeft-GiniRight),即寻找最佳的特征f和阈值th,使得当前节点的Gini值减去左子节点的Gini和右子节点的Gini值最大。

对于回归问题,相对更加简单,直接使用argmax(Var-VarLeft-VarRight)作为评判标准,即当前节点训练集的方差Var减去减去左子节点的方差VarLeft和右子节点的方差VarRight值最大。

Decrease Accuracy:抄一下女神的文字

然后随机改变OOB样本的第j列:保持其他列不变,对第j列进行随机的上下置换,得到误差2。至此,我们可以用误差1-误差2来刻画变量j的重要性。当然这里loss function可以自己定。这里的大致思想就是,如果一个变量j足够重要,那么改变它会极大的增加测试误差;反之,如果改变它测试误差没有增大,则说明该变量不是那么的重要。(典型的实用主义啊!管用才是真,才不管他什么证明不证明呢!自从开始接触机器学习的这些算法,我真的是被他们的各种天真烂漫的想法打败的一塌糊涂,只要直觉上过得去、实际效果看起来比较好就可以了呢,规则真简单)

对于mtry这个值的设定:

default是sqrt(M),作者建议也试一下sqrt(M)/2,2sqrt(M), 甚至是对于有些数据集,取mtry=1效果也很好。

对于 6.能处理imbalanced data set,Balancing prediction error。

这个是非常重要的一个特点。往往我们的数据集,每个class下的观测实例个数,总是不那么均等,比如[4]中提到,在反欺诈识别,疾病识别这种数据集中,数据就非常不平衡。

[4]中提到两种方法处理这种情况,一种是balanced RF,另一种是weighted RF,对于前者采是用分层重抽样的方法,即对minority class采取up-sampling,对于majority class 进行down-smapling。下面举例说明(在Cross Validated 这上面找到的一个很好的例子)R package for Weighted Random Forest? classwt option?

  1. make.data = function(obs=5000,vars=6,noise.factor = .2,smallGroupFraction=.01) {
  2. X = data.frame(replicate(vars,rnorm(obs)))
  3. yValue = with(X,sin(X1*pi)+sin(X2*pi*2)+rnorm(obs)*noise.factor)
  4. yQuantile = quantile(yValue,c(smallGroupFraction,.5))
  5. yClass = apply(sapply(yQuantile,function(x) x<yValue),1,sum)
  6. yClass = factor(yClass)
  7. print(table(yClass)) #five classes, first class has 1% prevalence only
  8. Data=data.frame(X=X,y=yClass)
  9. }
  10. Data = make.data()
  11. # yClass
  12. # 0 1 2
  13. # 50 2450 2500
  14. rf1 = randomForest(y~.,Data,ntree=500, sampsize=5000)
  15. 下面是rf1的结果,可以看出对于yClass==0的预测错误率100%,但是总体的预测错误率在
  16. 13.7%左右,如果是做fraud detection,这绝对是不可行的。
  17. OOB estimate of error rate: 13.7%
  18. Confusion matrix:
  19. 0 1 2 class.error
  20. 0 0 50 0 1.0000000
  21. 1 0 2109 341 0.1391837
  22. 2 0 294 2206 0.1176000
  23. ###########下面用分层抽样改进###########
  24. rf2 = randomForest(y~.,Data,ntree=4000,sampsize=c(50,500,500),strata=Data$y)
  25. rf3 = randomForest(y~.,Data,ntree=4000,sampsize=c(50,100,100),strata=Data$y)
  26. rf4 = randomForest(y~.,Data,ntree=4000,sampsize=c(50,50,50) ,strata=Data$y)
  27. ###########结果看下来,rf3,rf4效果最好###########
  28. #作者也提到,让每个class的错误率都均等一些,可能会使总体的预测错误率上升,这需要权衡

randomForest能进行无监督的学习:

这里稍后再写

参考资料

[1]Random Forest Classification/Clustering

[2]randomForest manual

[3]Classification and Regression by randomForest

[4]Using Random Forest to Learn Imbalanced Data

#后续阅读

[1]How to interpret Mean Decrease in Accuracy and Mean Decrease GINI in Random Forest models

[2]http://www.loyhome.com/%E2%89%AA%E7%BB%9F%E8%AE%A1%E5%AD%A6%E4%B9%A0%E7%B2%BE%E8%A6%81the-elements-of-statistical-learning%E2%89%AB%E8%AF%BE%E5%A0%82%E7%AC%94%E8%AE%B0%EF%BC%88%E5%8D%81%E5%85%AD%EF%BC%89/

随机森林算法-Deep Dive的更多相关文章

  1. 随机森林算法demo python spark

    关键参数 最重要的,常常需要调试以提高算法效果的有两个参数:numTrees,maxDepth. numTrees(决策树的个数):增加决策树的个数会降低预测结果的方差,这样在测试时会有更高的accu ...

  2. Bagging与随机森林算法原理小结

    在集成学习原理小结中,我们讲到了集成学习有两个流派,一个是boosting派系,它的特点是各个弱学习器之间有依赖关系.另一种是bagging流派,它的特点是各个弱学习器之间没有依赖关系,可以并行拟合. ...

  3. R语言︱决策树族——随机森林算法

    每每以为攀得众山小,可.每每又切实来到起点,大牛们,缓缓脚步来俺笔记葩分享一下吧,please~ --------------------------- 笔者寄语:有一篇<有监督学习选择深度学习 ...

  4. R语言︱机器学习模型评估方案(以随机森林算法为例)

    笔者寄语:本文中大多内容来自<数据挖掘之道>,本文为读书笔记.在刚刚接触机器学习的时候,觉得在监督学习之后,做一个混淆矩阵就已经足够,但是完整的机器学习解决方案并不会如此草率.需要完整的评 ...

  5. Python机器学习笔记——随机森林算法

    随机森林算法的理论知识 随机森林是一种有监督学习算法,是以决策树为基学习器的集成学习算法.随机森林非常简单,易于实现,计算开销也很小,但是它在分类和回归上表现出非常惊人的性能,因此,随机森林被誉为“代 ...

  6. H2O中的随机森林算法介绍及其项目实战(python实现)

    H2O中的随机森林算法介绍及其项目实战(python实现) 包的引入:from h2o.estimators.random_forest import H2ORandomForestEstimator ...

  7. 用Python实现随机森林算法,深度学习

    用Python实现随机森林算法,深度学习 拥有高方差使得决策树(secision tress)在处理特定训练数据集时其结果显得相对脆弱.bagging(bootstrap aggregating 的缩 ...

  8. spark 随机森林算法案例实战

    随机森林算法 由多个决策树构成的森林,算法分类结果由这些决策树投票得到,决策树在生成的过程当中分别在行方向和列方向上添加随机过程,行方向上构建决策树时采用放回抽样(bootstraping)得到训练数 ...

  9. 随机森林算法原理及OpenCV应用

    随机森林算法是机器学习.计算机视觉等领域内应用较为广泛的一个算法.它不仅可以用来做分类(包括二分类和多分类),也可用来做回归预测,也可以作为一种数据降维的手段. 在随机森林中,将生成很多的决策树,并不 ...

随机推荐

  1. 【Tensorflow】 Object_detection之训练PASCAL VOC数据集

    参考:Running Locally 1.检查数据.config文件是否配置好 可参考之前博客: Tensorflow Object_detection之配置Training Pipeline Ten ...

  2. OpenGL进阶之Instancing

    Instancing Instancing绘制我想很多童鞋都不陌生,这个技术主要用来快速渲染大量相同的几何体,可以大大提高绘制效率.每个instance在shader中都有一个独一无二的索引,可以用来 ...

  3. Aaja.pro 未定义

    问题描述:安装新系统后,将代码迁至新系统,所有用到ajaxpro框架调用ajax方法时均报“xx未定义”的错: 解决问题的过程 : 1.看看你在前台调用的方法的命名空间,方法名和后台的是否对应.在后台 ...

  4. [转]ASP.NET Core / MVC 6 HttpContext.Current

    本文转自:http://www.spaprogrammer.com/2015/07/mvc-6-httpcontextcurrent.html As you know with MVC 6, Http ...

  5. SQL动态配置,动态解析SQL

    在项目中使用SQL动态配置的方式可以让后期的维护和发布后的修改变得更加方便,无论使用那种配置方式都离不开解析成最终真正能执行的SQL.下面代码就是一种比较简单的处理方法,SQL的参数以##括起来. 1 ...

  6. Java 条件语句

    1.if...else 一个 if 语句包含一个布尔表达式和一条或多条语句. if(布尔表达式) { //如果布尔表达式为true将执行的语句 }else{ //如果布尔表达式为false将执行的语句 ...

  7. 初识MySQL——人生若如初相逢

    CREATE TABLE `student`(`studentNo` INT (4) NOT NULL PRIMARY KEY COMMENT '学号',`loginPwd` VARCHAR(20) ...

  8. Android-自定义View实现ImageView播放gif

    http://blog.csdn.net/guolin_blog/article/details/11100315 总体思路是这样的 PowerImageView类继承ImageView类 给Powe ...

  9. iOS instruments之ui automation的简单使用(高手绕道)

    最近使用了几次instruments中的automation工具,现记录下automation的简单使用方法,希望对没接触过自动化测试又有需求的人有所帮助.  UI 自动测试是iOS 中重要的附加功能 ...

  10. MicroService