机器学习-R语⾔-随机森林-分类、回归、预测、筛选变量有史以来超详细解析
(⼲货满满)
关系代词R语⾔随机森林详细解析(基于randomforest包和varSelRF包)
研究如何⽤R去实现随机森林也有三个⽉的时间了,从⼀开始的完全不理解,到现在的游刃有余,我似乎花了过多的时间,毕竟是初学者嘛。不知各位有没有发现,CSDN上随机森林的教程都说的有些模糊,好像在刻意回避着什么,⽽且很少有⼈说变量筛选的问题。所以,今⽇,我觉得有必要记录⼀下了。
随机森林基于R
你即将从这⾥看到
1.如何使⽤随机森林做回归、分类、预测、交叉验证
2.如何评价模型效能(ROC、AUC)
3.如何筛选变量
在这⾥你不会看到
1.长篇⼤段没有注释的代码
2.故弄⽞虚,简单问题复杂化
3.重复造轮⼦(本⽂以解决实际问题为主)四头狮子
分类与回归
数据科学最基础的问题,分类与回归。
⽽随机森林做分类还是回归是取决于label是factor类型的还是numerical类型的
1.导包
⼀般需要四个包,如下,第⼀个是导⼊数据⽤的,第⼆个是随机森林包,第三个是筛选变量⽤的,第四个是绘制ROC曲线、计算AUC得分的包
library(xlsx)
library(randomForest)
library(varSelRF)
library(pROC)
2.数据读取、缺失值处理
读取数据,此数据是我做社会调查⾃⼰收集来的数据,各位可替换成鸢尾花数据集
d<-read.xlsx('socialrecode2.xlsx',1)#这种直接引⽤⽂件名的写法请确保⽂件在⼯作空间内
#参数1代表使⽤第⼀⾏作为列名
d1<-na.omit(d) #删去缺失值,随机森林分类器内不能传⼊缺失值
#如果⼿头没有待处理的数据,请使⽤鸢尾花数据集
d1<-data(iris) #鸢尾花数据集是⽆缺失值的,故不需删去缺失值
如果你的数据量不够多,但是⼜含有许多缺失值,建议使⽤randomforest包⾃带的缺失值填充函数:na.roughfix(object, …)
按中位数或者模型进⾏填充
3.训练模型
弓形虫检查多少钱
在直觉上,似乎⼀⽚森林中决策树越多越好,但真的是这样吗?(此处有疑问不要紧,可参考⽂末原理部分)
为了测试出多少棵树时模型是最优的,我们先试探性的⽤800棵树试⼀下,即第⼆部分的代码。然后画出错误率与决策树的数量的关系曲线
#按index拆分训练集与测试集
index <- sample(2,nrow(iris),replace = TRUE,prob=c(0.7,0.3))
traindata <- iris[index==1,]
testdata <- iris[index==2,]
#试验性训练模型
t.ed(1234)#设置随机种⼦数,确保以后再执⾏代码时可以得到⼀样的结果
rf_ntree<- randomForest(Species ~ ., data=traindata, #我这⾥把代码分成两⾏来写了
国考报名要求ntree=800,important=TRUE,proximity=TRUE)
plot(rf_ntree)
我们可以看出,在树的数量⼤于200的时候就基本稳定了,在500左右会浮动⼀下,在600以后⼜是稳定的,⽽且错误率⽔平其实差不多,所以我们避开500左右的取值,在保证效能的情况下减少决策树的数量,减少运⾏时间。在这⾥我们就取ntree=200好了。
#正式训练
iris_rf <- randomForest(Species ~ ., data=traindata,
ntree=200,important=TRUE,proximity=TRUE)
在这⾥需要注意的是,,important=TRUE意为保留指标重要性、proximity=TRUE意为保留近似矩阵,这两个参数分别在筛选变量、数据可视化的时候起很⼤作⽤,⼀定不可漏掉。
当然也有另⼀种写法,这种写法⽐较贴近我的习惯,谁是feature谁是label⼀⽬了然
iris_rf <- randomForest(x=traindata[,1:4], y=traindata[,5],
ntree=200,important=TRUE,proximity=TRUE)
然后我们查看模型具体情况
iris_rf
###输出结果如下(这是输出结果,不是代码)
Call:
randomForest(formula = Species ~ ., data = traindata, ntree = 200, important = TRUE, proximity = TRUE)
Type of random forest: classification
Number of trees: 200
No. of variables tried at each split: 2
OOB estimate of error rate: 5.66%
Confusion matrix:
tosa versicolor
tosa 35 0 0 0.00000000
versicolor 0 32 3 0.08571429
virginica 0 3 33 0.08333333
4.预测
很简单,直接⽤predict函数就可以,第⼀个参数可以理解为“以什么样的⽅式进⾏预测”,第⼆个参数就是你要根据什么数据进⾏预测
iris_pred<-predict(iris_rf, newdata=testdata)
table(iris_pred,testdata$Species)
#输出结果如下
#iris_pred tosa versicolor virginica
#tosa 15 0 0
#versicolor 0 14 1
#virginica 0 1 13
混淆矩阵可以看出本来属于某个品种的鸢尾花被分到另⼀个品种的数量。
5.模型评价(AUC)
roc<- (as.ordered(testdata$Species) ,as.ordered(iris_pred$iris_pred))
roc
###输出结果为
Call:
Data: as.ordered(iris_pred$iris_pred) with 3 levels dered(testdata$Species): tosa, versicolor, virginica.
Multi-class area under the curve: 0.977
Multi-class area under the curve: 0.977,AUC得分为0.977,相当不错。
那roc曲线怎么绘制?pROC只能画⼆分类问题的曲线,假如你使⽤其他的数据,并且是⼆分类问题,那么可使⽤如下代码
roc<-dered(testdata$Species) ,as.ordered(iris_pred$iris_pred))
plot(roc,print.auc=T, auc.polygon=T, grid=c(0.1, 0.2), l=c("green","red"),
max.auc.polygon=T, l="skyblue",print.thres=T)
交叉验证
# 交叉验证
##先清除NA的数据样本,交叉验证不允许有NA
it(airquality)
第二委托方代理myairquality=cbind(airquality[1:6],matrix(runif(96*nrow(airquality)),nrow(airquality),96))
# 交叉验证中添加随机数的训练集、分组、交叉验证的次数
result=rfcv(myairquality,airquality$Ozone,cv.fold = 5)
# 绘制错误率曲线,观察错误率与使⽤Markers数量的变化
with(result,plot(n.var,error.cv,log="x",type="o",lwd=2))
##使⽤replicate多次交叉验证
result=replicate(5,rfcv(myairquality,airquality$Ozone),simplify = FALSE)
error.cv=sapply(result,"[[","error.cv")
matplot(result[[1]]$n.var,cbind(rowMeans(error.cv),error.cv),type = "l",lwd = c(2,rep(1,ncol(error.cv))),col = 1,lty = 1,log="x",xlab = "Number of variables",yla b="CV Error")
多次交叉验证曲线重合,说明结果可信
变量筛选
我⽤我⾃⼰的社会调查数据举例。我的错误率曲线画出来是这样的(代码和上⽂交叉验证相同)
南充景点
这说明特征数量不宜超过20左右的某个数字,否则错误率会上升。
那好,我们输出重要性前20个变量,就是我们模型所需要的最佳变量。
安阳旅游景点
注意,这⾥不是⽤鸢尾花数据集做的,建议换数据来测试⼀下。参数可以根据⾃⼰的数据调整。varImpPlot(rf,n.var=20,cex=2)
当然,输出鸢尾花数据集的变量重要性也是可以的
varImpPlot(iris_rf)
换成你的数据,就取前⼆⼗个就好了。
那有没有另⼀种⽅法筛选变量?
有的。
那就是varSelRF包
1.varSelRF()函数
varSelRF(xdata, Class, c.sd = 1, mtryFactor = 1, ntree = 5000,
ntreeIterat = 2000, vars.drop.num = NULL, vars.drop.frac = 0.2,
whole.range = TRUE, recompute.var.imp = FALSE, verbo = FALSE,诗经共有多少篇
returnFirstForest = TRUE, fitted.rf = NULL, keep.forest = FALSE)
等于单独做⼀次随机森林。
2.randomVarImpsRF()
randomVarImpsRF(xdata, Class, forest, numrandom = 100,
whichImp = "impsUnscaled", usingCluster = TRUE,
TheCluster = NULL)
⽤现成的随机森林筛选变量,第三个参数放置随机森林对象
3.变量重要性可视化⽅法
有两种⽅法
这是基于varSelRF()
rf.vs1 <- varSelRF(x, cl, ntree = 200, ntreeIterat = 100,
vars.drop.frac = 0.2)
rf.vs1
plot(rf.vs1)