11.随机森林

#####11 随机森林#####
library(randomForest)

#####1.2.2 核心函数#####
#这个软件包主要有5个函数,分别为:importance()、MDSplot()、rfImpute、treesize()以及
#randomForest().

#函数importance()用来提取在利用函数randomForest()建立随机森林过程中方程中各个变量的
#重要性度量结果。

#函数MDSplot()用来绘制在利用函数randomForest()建立随机森林模型过程中所产生的临近矩
#阵经过标准化后的坐标图,简而言之,就是可以将高位图缩放到任意小的维度下来观看模型各
#个类别在不同维度下的分布情况。

#函数rfImpute()用来对数据中的缺失值进行插值,该函数也是随机森林模型的一个重要用途之一。

#函数treesize()用来查看随机森林模型中,每一棵树所具有的节点数。

#函数randomForest()是随机森林中最核心的函数,它用来建立随机森林模型,该函数既可以建
#立判别模型,也可以用来建立回归模型,还可以建立无监督模型。

#1. importance()函数
#importance(x, type=NULL, class=NULL, scale=TRUE, ...)

#参数x在这里代指的是利用函数randomForest()生成的随机森林函数模型。
#参数class在这里这要针对随机森林中的分类问题。当type参数取值为1时,该参数的取值范围
#为响应变量中的样本类别,并返回结果为该参数的取值对应类别的重要值情况。
#参数type在这里指代的是对于变量重要值的度量标准。该参数共有两个区直,1和2.其中1代表
#采用精度平均较少之作为度量标准;而2 代表采用节点不纯度的平均较少之作为度量标准。
#参数scale代表是否对变量重要值进行标准化,即是否将计算而得的重要值除以它们对应的标
#准差。

#通过importance()所得到的结果是一个由变量重要值组成的矩阵。其中每一行代表一个预测变
#量,而不同的列代表着不同的重要值度量方法。
set.seed(4)                       #设定产生随机数的初始值
data(mtcars)                      #调用数据集mtcars(1973~1974年车型的32辆汽车的10项指标)
mtcars.rf=randomForest(mpg~.,data=mtcars,ntree=1000,importance=TRUE)
                                  #基于数据集建立随机森林模型
importance(mtcars.rf)             #提取随机森林模型中的重要值
importance(mtcars.rf, type=1)     #提取随机森林模型中以第一章度量标准得到的重要值
#对应变量的重要值越大,这说明改变了对于模型进行分类越重要。

#2. MDSplot()函数
#用于绘制在利用函数randomForest()建立随机森林模型过程中,所产生的临近矩阵经过标准化后
#的坐标图。即在不同维度下各个样本点的分布情况。
#MDSplot(rf, fac, k=2, palette=NULL, pch=20, ...)

#参数rf在这里指代的是利用函数randomForest()所构建的随机森林模型。在此需要强调的是,在
#构建该模型时,必须在模型中包含有模型的临近矩阵。
#参数fac在这里指代的是在构建rf随机森林过程中所使用到的一个因子变量。
#参数k在这里是用来决定所绘制的图像中各个类别所包含的经过缩放的维度。该参数默认为2.
#参数palette在这里是用来决定所绘制的图像中各个类别的样本点的颜色。
#参数pch在这里是用来决定所绘制的图像中各个类别的样本点的形状。

set.seed(1)                        #设定产生随机数的初始值
data(iris)                         #数据集
iris.rf=randomForest(Species~., iris, proximity=TRUE)
MDSplot(iris.rf, iris$Species, palette=rep(1, 3), pch=as.numeric(iris$Species))

#3. rflmpute()函数

#第一类函数使用格式:
#rfImpute(x, y, iter=5, ntree=300, ...)

#第二类函数使用格式:
#rfImpute(x, data, ..., subset)

#参数x在这里为一个含有一些缺失值的预测数据集,同时x也可以为一个公式。
#参数y在这里为相应变量向量,在该函数中,参数y不能存在缺失值。
#参数iter为插值过程中的迭代次数。
#参数ntree为每次迭代生成的随机森林模型的决策树数量。
#参数subset决定了将采用的样本集。

data(iris)      
iris.na=iris                       #生成所需要的数据集
iris.na[75,2]=NA;iris.na[125,3]=NA;#在第75号样本和第125号样本中设置缺失值
set.seed(111)
iris.imputed=rfImpute(Species~.,data=iris.na) #对数据集iris.na进行插值
list("real"=iris[c(75,125),1:4],"have-NA"=iris.na[c(75,125),1:4],
     "disposed"=round(iris.imputed[c(75,125),2:5],1)) #列式插值结果与真实值的比较

#4. treesize()函数
#treesize(x, treminal=TRUE)

#参数x在这里指代的是利用函数randomForest()所构建的随机森林模型。
#参数terminal主要用于决定节点的计数方式,如果值为默认值TRUE,则只计算最终根节点数
#目,如果值为FALSE,则将所有的节点全部计数。

iris.rf=randomForest(Species~.,iris) #利用数据iris构建相关随机森林模型
hist(treesize(iris.rf))              #绘制相应的柱状图

#5. randomForset()函数

#第一类函数使用格式:
#randomForest(formula, data=NULL, ..., subset, na.action=na.fail)

#第二类函数使用格式:
#randomForset(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.forset=!is.null(y) && is.null(xtest),
#corr.bias=FALSE,keep.inbag=FALSE, ...)

#在第一类使用格式中,formula代表的是函数模型的形式。
#data代表的是在模型中包含的有变量的一组可选格式数据。
#subset主要用于抽取样本数据中的部分样本作为训练集,该参数所使用的数据格式为一向量
#向量中的每个数代表所需要抽取样本的行数。
#na.fail,不能出现缺失值,还可以使用na.omit即忽略缺失值。

#在第二类中x为一个矩阵或一个格式化数据集。自变量数据
#y为建立随机森林模型中的响应变量。如果y为字符向量,则为判别模型,若为数量变量,则为
#回归模型;不设定y,为无监督模型。
#参数xtest是一个格式数据或矩阵。该参数所代表的是用来进行预测的测试集的预测指标。
#参数ytest是参数xtest决定的测试集的真实分类情况。
#ntree指森林中树的数目。该参数不宜过小。
#参数mtry用来决定在随机森林中决策树的每次分支所选择的变量个数。默认值在判别模型中
#为变量个数的二次根号,在回归模型中为变量个数的三分之一。
#参数replace用来决定随机抽样的方式。TRUE有放回,FALSE无放回。
#strata是一个因子向量,主要用于决定分层抽样。
#参数sampsize是用来决定抽样的规模的。strata决定抽取的类别,sampsize决定该类别应抽取
#的数量。
#参数nodesize是用来决定随机森林中决策树的最少节点数的。默认值在判别为1,在回归为5.
#参数maxnodes是用来决定随机森林中决策树的最大节点数的。
#参数importance用来决定是否计算各个变量在模型中的重要值。
#参数proximity是用来决定是否计算模型的临近矩阵的

#输出结果
#predicted,包含了利用所建的随机森林模型基于OOB数据进行预测的结果。
#importance,包含了各个变量在模型中的重要值
#输出结果call主要概述模型的基本参数;type展示模型的类别,回归、判别、无监督。在随机森
#林中,如果响应变量为连续变量,则为回归模型,该类模型将每棵决策树的结果进行平均得出最
#后预测结果;定性变量,为判别模型,主要通过统计每棵决策树的决策结果,将出现概率最大的
#结果作为预测结果;不设定,为无监督,主要用于文本分析以及文本分类。
#ntree说明随机森林中存在决策树的数量;mtry说明在决策树的节点分支上所选择的变量个数;输
#出结果err.rate则是利用模型基于OOB数据进行预测的总体误判率;同时该函数还能输出模型基于
#OOB数据计算而得到的相邻矩阵以及混淆矩阵。

#使用大型数据集时,不建议使用第一类输入格式。

#####11.2.3 可视化分析#####
#可以利用函数plot()绘制相关误差与随机森林中决策树数量的关系图。用来确定在构建随机森林时
#应该使用的决策树数量
data(airquality)       #调用数据集
set.seed(131)          #是指随机数生成器
ozone.rf=randomForest(Ozone~.,data=airquality,mtry=3,importance=TRUE,na.action=na.omit)
                       #建立随机森林回归模型
plot(ozone.rf)         #绘制相关图像
#该模型误差最小值并非500,210左右就可以了。

#####11.3 应用案例#####
#下面我们选择使用来源于UCI数据框中的关于白酒品质研究的数据集进行算法分析,该数据集是关于
#白酒中的各项变量对白酒品质的影响情况。
library(randomForest)
wine=read.csv("E://books/数据挖掘 R语言实战/wine/winequality-white.csv",sep=";")
names(wine)=c("fixedacidity","volatileacidity","citricaid","residualsugar","chlorides",
              "freesulfurdioxide","totalsulfurdioxide","density","PH","sulphates",
              "alcohol","quality")  #为数据集wine中的各个变量命名
summary(wine)                       #获取wine数据集的概括信息
#数据集中的quality为结果变量,有11个等级,0到10,在本数据集中仅包含3至9这7个等级。
#本数据采集了白酒品质的11项基本特征,分别为:非会发性酸、挥发性酸、柠檬酸、剩余糖分、氯
#化物、游离二氧化硫、总二氧化硫、密度、酸性、硫酸盐、酒精度。

#####11.3.1 数据处理#####
#画出直方图,我们看到,品质6的样本量最大,与此同时,品质等级为3、4、8、9的样本量微乎其微,
#所以综合以上分析判断以及实际情况,将白酒品质分为三个等级,其中品质3、4、5对应品质"bad",
#品质6对应品质为"mid",品质7、8、9对应品质为"good"。
hist(wine$quality)

cha=0                 #设置中间变量对处理后的向量进行临时存储
for(i in 1:4898)      #针对没一个样本进行调整
{
  if(wine[i,12]>6)cha[i]="good"
  else if(wine[i,12]>5)cha[i]="mid"
  else cha[i]="bad"
}
wine[,12]=factor(cha) #将字符型变量转换为含有因子的变量并复制给数据集wine
summary(wine$quality)

#####11.3.2 建立模型#####
set.seed(71)    #设置随机数生成器初始值
samp=sample(1:4898,3000) #从全部数据集中抽取3000个样本作为训练集
set.seed(111)
wine.rf=randomForest(quality~.,data=wine,importance=TRUE,proximity=TRUE,ntree=500,subset=samp)
                                     #构建决策树为500棵的随机森林模型
#根据函数的第二种使用格式,我们针对上述数据建立模型时,首先应该讲响应变量和自变量分别
#提取出来。
x=subset(wine,select=-quality) #提取wine数据集中除quality列以外的数据作为自变量
y=wine$quality                 #提取wine数据集中quality列数据作为响应变量
set.seed(71)
samp=sample(1:4898, 3000)      #从全部数据集中抽取3000个样本作为训练集
xr=x[samp,];yr=y[samp]
set.seed(111)                  #设置随机数生成器初始值
wine.rf1=randomForest(xr,yr, importance=TRUE, proximity=TRUE, ntree=500)
#在使用第二种格式建立模型时,不需要特别强调所建立的形式,函数会自动将所有输入的x矩阵
#中的数据作为建立模型所需要的自变量。

#####11.3.3 结果分析#####
print(wine.rf)             #展示所构建的随机森林模型
print(wine.rf1)
#两种格式建立的模型是等价的

#结果Call中展示了模型构建的相关参数设定
#结果Type中说明了所构建的模型的类别,从该结果中我们得知模型为判别模型。
#结果Number of trees展示了所构建的随机森林中包含了500棵决策树。
#结果No. of variables tried at each split: 3还告知了每棵决策树节点所选择的变量个数为3.
#模型基于OOB样本集进行预测得到的结果正如结果中的Confusion matrix所示,且模型总的预测
#                                                                       误差为29.8%。
#结果中的Confusion matrix展示了最终模型的预测结果同训练集实际结果之间的差别情况。
#class.error为类别在该类样本下的预测误判率。

#####11.3.4 自变量的重要程度#####
importance(wine.rf) #对前文中建立的模型wine.rf提取其重要值列表
#自变量对应较高的指标值说明该自变量对模型的判别情况影响大。

#####11.3.5 优化建模#####
#两个主要因素,其一为决策树节点分支所选择的变量个数;其二是随机森林模型中决策树的数量。
n=ncol(wine)-1              #计算数据集中自变量个数
rate=1                      #设置模型误判率向量初始值
for(i in 1:n)               #依次逐个增加节点所选变量个数
{
  set.seed(222)             #设置随机数生成器初始值
  model=randomForest(quality~.,data=wine,mtry=i,importance=TRUE,ntree=1000)
  rate[i]=mean(model$err.rate) #计算基于OOB数据的模型的模型误判率均值
  print(model)
}
rate                        #展示所有模型误判率的均值
#在这里当决策树节点为3时,误判率最低。下面确定决策树数量。
set.seed(222)
model=randomForest(quality~.,data=wine,mtry=3,importance=TRUE,ntree=1000)
plot(model,col=1:1)         #绘制模型误差与决策树量的关系
legend(800,0.23,"mid",cex=0.9,bty="n") #为图像添加图例
legend(800,0.29,"bad",cex=0.9,bty="n")
legend(800,0.37,"good",cex=0.9,bty="n")
legend(800,0.26,"total",cex=0.9,bty="n")

#从图中看见,当决策树数量在大于350之后模型误差趋于稳定
set.seed(222)
model=randomForest(quality~.,data=wine,mtry=3,importance=TRUE,ntree=350,proximity=TRUE)
print(model)                #展示随机森林模型简要信息
hist(treesize(model))       #展示随机森林模型中的每棵决策树的节点数
MDSplot(model,wine$quality, palette=rep(1, 3),pch=as.numeric(wine$quality))
                            #展示数据集在二维情况下各类别的具体分布情况
importance(model)
#模型基于OOB数据的总体误判率为24.46%;在模型中,变量挥发性酸、游离二氧化硫和酒精度对模
#型的预测能力影响较大;在分布图中可以看到,该数据集的三个类别均出现交叉,并且在部分区
#域,三个类别的交叉情况较为严重,这同时也解释了模型精度较低的原因。






猜你喜欢

转载自blog.csdn.net/qq_39124646/article/details/83214755