随机森林
本文主要介绍了随机森林算法的原理、优缺点以及R语言的实现。
一、概述
1.原理
随机森林(Random Forest)的实质是一种基于决策树的集成学习(Ensemble Learning),亦称多分类器系统(Multi-classifier System)。由于集成学习的核心是如何产生并结合“好而不同”的个体学习器,而随机森林在以决策树为基学习器的基础上,引入了两个随机性:(1)采样随机性:运用自助采样法在给定包含m个样本的数据集中采样出T个含m个训练样本的采样集(由于采样为可放回抽样,因此m个采样集中的样本与原始样本的m个样本不等同,实验表明,初始训练集中约有63.2%的样本出现在采样集中);(2)属性选择随机性:在随机森林中,对基决策树的每个结点,先从该结点的属性集中随机选择一个包含k(一般情况下,推荐值
2.组成
随机森林由随机采样和随机选择属性形成的多个CART决策树构成,在构建决策树的过程中,不进行任何剪枝动作。对于分类模型,往往通过投票法为待测样本进行分类;对于预测模型,往往通过单棵树的简单平均法或加权平均法进行预测,当然除此之外学习法等结合策略,在此不作过多解释。
3.性能影响因素
影响随机森林性能的因素主要有以下几个方面:
- 组成随机森林的决策树的数量
- 组成随机森林的每棵决策树的准确性:每棵树生长越茂盛,集成的随机森林的性能越好;
- 组成随机森林的决策树的相关性:树之间的相关性越差,随机森林的性能越好。
二、随机森林的优缺点
1.优点:
- 很好地解决了单棵决策树出现的过拟合问题;
- 在没有大幅提高运算量的基础上,有着较高的预测精度;
- 对多元共线性不敏感,结果对缺失数据和非平衡的数据比较稳健;
- 对数据集的适应能力强:既能处理离散型数据,也能处理连续型数据,数据集无需规范化;
- 可以很好地适应较多属性的数据集,并且不用做特征选择;
- 随着个体学习器数目增加,随机森林通常会收敛到更低的泛化误差,且训练效率较高;
- 在对数据进行分类的同时,还可以给出各个变量的重要性评分,评估各个变量在分类中所起的作用(因此可以用于重要特征的选择)。
2.缺点:
- 在某些噪音较大的分类或回归问题上会过拟;
- 对于有不同取值的属性的数据,取值划分较多的属性会对随机森林产生更大的影响,所以随机森林在这种数据上产出的属性权值是不可信的;
- 无法用业务知识解释分类过程。
三、实例
1.R语言函数介绍
randomForest(x, y=NULL, xtest=NULL, ytest=NULL, ntree=500,
mtry=if (!is.null(y) && !is.factor(y))
max(floor(ncol(x)/3), 1) else floor(sqrt(ncol(x))),
replace=TRUE, classwt=NULL, cutoff, strata,
sampsize = if (replace) nrow(x) else ceiling(.632*nrow(x)),
nodesize = if (!is.null(y) && !is.factor(y)) 5 else 1,
maxnodes = NULL,
importance=FALSE, localImp=FALSE, nPerm=1,
proximity, oob.prox=proximity,
norm.votes=TRUE, do.trace=FALSE,
keep.forest=!is.null(y) && is.null(xtest), corr.bias=FALSE,
keep.inbag=FALSE, …)
其中:
x 模型:类似于y~x1 + x2
ntree 决策树数量:默认为500
mtry 决策树的属性数量
importance 是否需要变量重要性:默认为FALSE
2.R语言实战
本次实战使用毒蘑菇数据集,由于之前在学习朴素贝叶斯算法时,曾经使用过该数据集,所以不对数据集细节做过多介绍。
#加载相关的包
library("randomForest")
#读取毒蘑菇数据集
mushrooms <- read.csv("C:\\Temp\\mushrooms.csv")
#查看数据结构信息
summary(mushrooms)
str(mushrooms)
#将数据集分为训练集和测试集,并通过type的分布查看抽样合理性
set.seed(12)
index <- sample(1:nrow(mushrooms),0.75*nrow(mushrooms))
traindata <- mushrooms[index, ]
testdata <- mushrooms[-index, ]
prop.table(table(mushrooms$type))
prop.table(table(traindata$type))
prop.table(table(testdata$type))
#建模
model <- randomForest(type ~ ., data = traindata, mtry = 4, ntree = 100, importance = TRUE)
plot(model)
#查看变量重要性
importance <- importance(x = model)
varImpPlot(model)
#预测
pred <- predict(model, newdata = testdata)
table(pred, testdata$type)
(1)预测结果
没错,预测的准确率达到了100%,可见随机森林之强大(用朴素贝叶斯算法,预测准确率为97%)。当然,能达到这么高的精度,除了随机森林优良的性能之外,同时也得益于高质量的数据集(完整性、都是因子类型、几乎没有噪音)。
(2)几个小问题
看完结果,再来细看过程:
- 随机森林的运算量还是比较大的,比较耗内存,本来打算使用信用卡诈骗数据集,30+属性,28w+条记录,发现R语言根本跑不动,提示需要额外内存,在网上找了各种办法(清内存,减少决策树等等)都不行,只好作罢。
-
随机森林对mtry参数似乎很不敏感,在这个例子中mtry从1~7我都试了,结果都是一样的,可以直接使用推荐值
log2d ,这里我选择了4。(也有可能是我太菜了,找了个太简单的问题~~) -
ntree参数可以通过plot(model)进行选择。如下图所示,那三条线表示模型内误差,选择稳定后的即可,这里我选择了20。
(3)变量重要性
随机森林不仅可以用在分类问题和回归问题之中,还可以在预测的同时给出各个变量的重要性评分,评估各个变量在分类中所起的作用,因此可以用于重要特征的选择。特地将该部分单独拎出来讲。
该功能由RandomFores()函数中的importance参数控制,为可选变量,默认为FALSE,需要手动设置其为TRUE时才能发挥作用。
在此例中,用importance变量存储变量重要性结果,并将其输出如下:
用varImpPlot(model)命令将其可视化:
可以看出主要由MeanDecreaseAccuracy和MeanDecreaseGini参数进行判别,其值越大,重要性程度越高。这里的重要特征与在朴素贝叶斯一节中选择的特征基本一致。
但是值得注意的是,在2.2节随机森林算法的缺点中也有提到:对于有不同取值的属性的数据,取值划分较多的属性会对随机森林产生更大的影响,所以随机森林在这种数据上产出的属性权值是不可信的,此时要结合其他方法进行特征的选取。
参考资料:
【1】周志华.机器学习[M].北京:清华大学出版社,2016.
【2】随机森林算法
【3】随机森林的优缺点
【4】基于R语言的随机森林算法运用