随机森林填补法

随机森林,指的是利用多棵树对样本进行训练并预测的一种分类器。该分类器最早由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。

理解上这个1/n是每次抽样的比率吗?所以out of bag到底是什么意思?

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

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

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

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

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

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

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

library(kernlab)

library(randomForest)

data(spam)

set.seed(1)

rf <- randomForest(type~. ,data=spam ,importance=TRUE ,proximity=FALSE ,ntree=300 ,do.trace=20 ,na.action=na.omit
,mtry=7 ,keep.forest=FALSE)

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

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

par(mfrow = c(2,2))

for(i in 1:4){

plot(sort(rf$importance[,i],decreasing =TRUE)%>%head(20)

     ,type='h'

     ,main=paste0(colnames(rf$importance)[i])

     ,xlab='variable'

     ,ylab='importance')

 

text(sort(rf$importance[,i],decreasing =TRUE)

                ,labels=names(sort(rf$importance[,i]))%>%head(20)

                   ,pos=1

                   ,cex=0.9)

}
以上代码能画出变量重要性的图,如下。(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值最大。

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

对于mtry这个值的设定:

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

make.data = function(obs=5000,vars=6,noise.factor = .2,smallGroupFraction=.01) {

X = data.frame(replicate(vars,rnorm(obs)))

yValue = with(X,sin(X1*pi)+sin(X2*pi*2)+rnorm(obs)*noise.factor)

yQuantile = quantile(yValue,c(smallGroupFraction,.5))

yClass = apply(sapply(yQuantile,function(x) x<yValue),1,sum)

yClass = factor(yClass)

print(table(yClass)) #five classes, first class has 1% prevalence only

Data=data.frame(X=X,y=yClass)

}

Data = make.data()

yClass

0 1 2

50 2450 2500

rf1 = randomForest(y~.,Data,ntree=500, sampsize=5000)

# 下面是rf1的结果,可以看出对于yClass==0的预测错误率100%,但是总体的预测错误率在

# 13.7%左右,如果是做fraud detection,这绝对是不可行的。

    OOB estimate of  error rate: 13.7%

Confusion matrix:

0 1 2 class.error

0 0 50 0 1.0000000

1 0 2109 341 0.1391837

2 0 294 2206 0.1176000

###########下面用分层抽样改进###########

rf2 = randomForest(y~.,Data,ntree=4000,sampsize=c(50,500,500),strata=Data$y)

rf3 = randomForest(y~.,Data,ntree=4000,sampsize=c(50,100,100),strata=Data$y)

rf4 = randomForest(y~.,Data,ntree=4000,sampsize=c(50,50,50) ,strata=Data$y)

###########结果看下来,rf3,rf4效果最好###########

#作者也提到,让每个class的错误率都均等一些,可能会使总体的预测错误率上升,这需要权衡
参考资料

[1]Random Forest Classification/Clustering

[2]randomForest manual

[3]Classification and Regression by randomForest

[4]Using Random Forest to Learn Imbalanced Data

本文 copy地址:http://www.cnblogs.com/litao1105/p/5021747.html

感谢

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值