如前文所述,随机森林目前拥有比较好的正确率,在各种数据中表现位于前列。随机森林顾名思义,是用随机的方式建立一个森林,森林里面有很多的决策树组成,随机森林的每一棵决策树之间是没有关联的。在得到森林之后,当有一个新的输入样本进入的时候,就让森林中的每一棵决策树分别进行一下判断,看看这个样本应该属于哪一类(对于分类算法),然后看看哪一类被选择最多,就预测这个样本为那一类。在建立每一棵决策树的过程中,有两点需要注意 - 采样与完全分裂。对于行采样,采用有放回的方式,也就是在采样得到的样本集合中,可能有重复的样本。假设输入样本为N个,那么采样的样本也为N个。这样使得在训练的时候,每一棵树的输入样本都不是全部的样本,使得相对不容易出现over-fitting。 然后进行列采样。之后就是对采样之后的数据使用完全分裂的方式建立出决策树,这样决策树的某一个叶子节点要么是无法继续分裂的,要么里面的所有样本的都是指向的同一个分类。
按这种算法得到的随机森林中的每一棵都是很弱的,但是大家组合起来就很厉害了。我觉得可以这样比喻随机森林算法:每一棵决策树就是一个精通于某一个窄领域的专家,这样在随机森林中就有了很多个精通不同领域的专家,对一个新的问题(新的输入数据),可以用不同的角度去看待它,最终由各个专家,投票得到结果。
R语言中的randomForest包可以实现随机森林算法的应用,该包中主要涉及5个重要函数,关于这5个函数的语法和参数请见下方:
用于计算模型变量的重要性
importance(x, type=NULL, class="NULL", scale=TRUE, ...)
用于实现随机森林的可视化
MDSplot(rf, fac, k=2, palette=NULL, pch=20, ...)
可为存在缺失值的数据集进行插补(随机森林法),得到最优的样本拟合值
setwd("E:\\Rwork")
library(randomForest)
data("iris")
index <- sample(nrow(iris),0.75*nrow(iris))
train <- iris[index,]
test <- iris[index,]
n <- length(names(train))
set.seed(100)
library(tcltk)
pb<-tkProgressBar("进度","已完成 %",0,400)
for (i in 1:(n-1)){
info<- sprintf("已完成 %d%%", round(i*100/length(n)))
setTkProgressBar(pb, i*100/length(n), sprintf("进度 (%s)", info),info)
mtry_fit <- randomForest(Species~.,data = train,mtry = i)
error <- mean(mtry_fit$err.rate)
print(error)
}
[1] 0.04328544
[1] 0.04293262
[1] 0.04588242
[1] 0.04616312
set.seed(100)
ntree_fit<-randomForest(Species~.,data=train,mtry=2,ntree=1000)
plot(ntree_fit)
rf <- randomForest(Species~., data = train ,mtry = 2 ,
ntree = 200,importance= TRUE)
)
rf
Call:
randomForest(formula = Species ~ ., data = train, mtry = 2, ntree = 200, importance = TRUE)
Type of random forest: classification
Number of trees: 200
No. of variables tried at each split: 2
OOB estimate of error rate: 4.44%
Confusion matrix:
setosa versicolor virginica class.error
setosa 32 0 0 0.00000000
versicolor 0 29 2 0.06451613
virginica 0 2 25 0.07407407
importance <- importance(rf)
importance
importance
setosa versicolor virginica MeanDecreaseAccuracy MeanDecreaseGini
Sepal.Length 4.268225 0.2564647 7.822284 6.792504 7.123898
Sepal.Width 2.409402 -0.7655617 2.686758 2.304386 0.750602
Petal.Length 12.652948 15.2819119 17.274815 19.071343 23.149037
Petal.Width 14.672686 18.1435246 18.742883 21.238528 28.105741
varImpPlot(rf)
pred1<-predict(rf,data=train)
Freq1<-table(pred1,train$Species)
sum(diag(Freq1))/sum(Freq1)
[1] 0.9555556
table(actual=test$Species,predicted=predict(rf,newdata = test,type = "class"))
predicted
actual setosa versicolor virginica
setosa 30 0 0
versicolor 0 30 0
virginica 0 0 30