两大类集成学习和随机森林

集成学习和随机森林的关系

集成学习是通过几个模型的组合来解决单一预测问题,它的工作原理是生成多个预测模型,每一个模型都独立的学习并给出预测,最后将这些预测结合成单个预测,因此最后的预测优于任何单分类模型给出的预测。

随机森林是包含多个决策树的分类器,这些决策树之间是没有关联的,最终的分类结果是各个决策树分类结果的投票。
所以随机森林是集成学习的一个子类。为此,先介绍一些常见的集成学习的内容,参考的博文见集成学习原理小结集成学习之Adaboost算法原理小结bagging与随机森林算法小结

关于Bagging思想的说明

Bagging原理图

随机森林

随机森林是Bagging算法的进化版,它的思想仍然是Bagging思想,但是在某些方面进行了一定的改进。这里,我们想说明几点:

1、为什么要采用随机有放回的采样?

如果不进行随机抽样,每棵树的训练集都一样,那么最终训练出的树分类结果也是完全一样的,这样的话完全没有bagging的必要;
图片上的随机采样通常指的是boostrap采样,即有放回的采样。

2、随机森林中的每棵树的生成过程是怎样的?

Step1:设训练集大小为m,随机森林中决策树的数量为T,对于每一棵决策树, 随 机 \textcolor{red}{随机} 有放回地抽取m个训练样本(boostrap采样),作为该书树的训练集;

所以每棵树的训练集都是随机的且是不同的,并且每一个训练集中都包含重复的训练样本。正如Bagging与随机森林算法小结中介绍的一样,在有放回的随机采样中,每个数据点被抽中的概率是 1 m \frac{1}{m} m1,不被抽中的概率是 1 − 1 m 1-\frac{1}{m} 1m1,m次采样都没被抽中的概率是 ( 1 − 1 m ) m (1-\frac{1}{m})^m (1m1)m,当 m → ∞ m\rightarrow \infty m时, ( 1 − 1 m ) m → 1 e = 0.368 (1-\frac{1}{m})^m\rightarrow \frac{1}{e}=0.368 (1m1)me1=0.368.
也就是说,在bagging的每轮随机采样中,训练集中大约有36.8%的数据没有被采样集采集中。对于这部分大约36.8%的没有被采样到的数据,我们常常称之为袋外数据(Out Of Bag, 简称OOB)这些数据没有参与训练集模型的拟合,因此可以用来检测模型的泛化能力。

Step2: 如果每个样本的特征维度为D,指定一个常数d<<D, 随 机 \textcolor{red}{随机} 地从D个特征中选取d个特征子集,每次树进行分裂时,从这d个特征中选择最优的;
Step3: 采用常见的决策树的算法,比如ID3、C4.5和CART算法去训练每一个决策树。

3、 随机森林的"随机"性体现在哪里?

随机森林的随机性便是上面标红的地方。两个随机性的引入对随机森林的分类性能至关重要。由于它们的引入,使得随机森林不容易陷入过拟合,并且具有很好得抗噪能力(比如:对缺省值不敏感)。

4、随机森林是Bagging算法的进阶体现在哪里?

  • RF通常使用CART决策树作为弱学习器
  • 在使用决策树的基础上,RF对决策树的建立做了改进。对于普通的决策树,我们会在节点上所有的D个样本特征中选择一个最优的特征来做决策树的左右子树划分,但是RF通过 随 机 \textcolor{red}{随机} 选择节点上的一部分样本特征,这个数字小于D,假设为d, 然后在这些随机选择的d个样本特征中,选择一个最优的特征来做决策树的左右子树划分。这样进一步增强了模型的泛化能力。

5、随机森林分类效果的影响因素有哪些?

随机森林分类效果(错误率)的两个影响因素:

  • 森林中任意两棵树的相关性:相关性越大,错误率越大;
  • 森林中每棵树的分类能力:每棵树的分类能力越强,整个森林的错误率越低。

减少部分特征选择个数d, 各个决策树之间的相关性会降低,但是每个树的分类能力也相应的降低;如果增大d,两者也会随之增大。因此,要选择一个合适的d对这两种影响因素做出权衡,如何选择最优的d是随机森林要解决的重要的问题,d也是随机森林中唯一的参数。

6、如何找到最优的部分特征数d?

随机森林关键的问题是如何找到最优的d,要解决这个问题可以利用交叉验证的思想。考虑到随机森林算法中,每一棵决策树的训练集总是有可能包含不了0.368的样本数据,在做交叉验证的时候可以直接利用这里没被抽中的样本集进行验证。

7、随机森林在R中的实现

我们将用UCI数据库中的威斯康星州的乳腺癌数据进行上述的方法的R实现,这个数据集可以在UCI数据库中下载,也可以在机器学习数据库中找到,采用下面的R code 可以直接读取数据进到R中。

loc<-"http://archive.ics.uci.edu/ml/machine-learning-databases/"
ds<-"breast-cancer-wisconsin/breast-cancer-wisconsin.data"
url<-paste(loc,ds,sep="")
data<-read.table(url,sep=",",header=F,na.strings="?")

数据集共有689条数据,有16条是存在缺失数据的数据,数据集中的各列分别代表"编号",“肿块厚度”,“肿块大小”,“肿块形状”,“边缘黏附”,“单个表皮细胞大小”,“细胞核大小”,“染色质”,“细胞核常规”,“有丝分裂”,“类别”,其中类别为2代表是良性,类别为4代表是恶性。

### 数据预处理
names(data)<-c("编号","肿块厚度","肿块大小","肿块形状","边缘黏附","单个表皮细胞大小","细胞核大小","染色质","细胞核常规","有丝分裂","类别")
data$类别[data$类别==2]<-"良性"
data$类别[data$类别==4]<-"恶性"
list <- which(rowSums(is.na(data))>0)
miss_data <- data[list,] #只有细胞核大小这一列变量存在缺失
7.1、决策树算法的R实现

在决策树算法中,是没有考虑确实问题的,因为最后选取的分裂决策树的特征可能总不会是缺失变量。
决策树常用的两个R包是rpart和party。关于这两个包的区别,见rpart包与party包的区别

data<-data[-1] #删除第一列元素#
set.seed(1234) #随机抽样设置种子
train<-sample(nrow(data),0.7*nrow(data)) #抽样函数,第一个参数为向量,nrow()返回行数 后面的是抽样参数前
tdata<-data[train,]  #训练集
vdata<-data[-train,] #测试集


####  构建决策树
dtree<-rpart(类别~.,data=tdata,method="class", parms=list(split="information"))#CART算法,split = “gini”
printcp(dtree)  # 查看当前的决策树的复杂性参数
print(dtree)

tree<-prune(dtree,cp=dtree$cptable[which.min(dtree$cptable[,"xerror"]),"CP"]) #自动选择xerror最小时候对应的cp值来剪枝

### 画决策树 格式:rpart.plot(tree,type,fallen.leaves=T,branch,)
opar<-par(no.readonly = T)
par(mfrow=c(1,2))
library(rpart.plot)
rpart.plot(dtree,branch=1,type=2, fallen.leaves=T,cex=0.8, sub="剪枝前")
rpart.plot(tree,branch=1, type=4,fallen.leaves=T,cex=0.8, sub="剪枝后")
par(opar)
#dev.off()

### 测试集检验
predtree<-predict(tree,newdata=vdata,type="class")   #利用预测集进行预测
print(predtree)
table(vdata$类别,predtree,dnn=c("真实值","预测值"))    #输出混淆矩阵
7.2 随机森林算法
##############################################################
##############################  随机森林 ###############
install.packages("randomForest")
library(randomForest)

#################################################################
###  在随机森林算法中需要确定两个重要的参数:mtry和ntree
###  mtry 是每个决策树选择的特征数量 
###  ntree 是随机森林中决策树的数量
### 一般对mtry的选择是逐一尝试,直到找到比较理想的值,
###  ntree的选择可通过图形大致判断模型内误差稳定时的值。
############################################################
loc<-"http://archive.ics.uci.edu/ml/machine-learning-databases/"
ds<-"breast-cancer-wisconsin/breast-cancer-wisconsin.data"
url<-paste(loc,ds,sep="")
data<-read.table(url,sep=",",header=F,na.strings="?")
names(data)<-c("编号","肿块厚度","肿块大小","肿块形状","边缘黏附","单个表皮细胞大小","细胞核大小","染色质","细胞核常规","有丝分裂","类别")
data <- data[-1,]

set.seed(1234) #随机抽样设置种子
train<-sample(nrow(data),0.7*nrow(data)) #抽样函数,第一个参数为向量,nrow()返回行数 后面的是抽样参数前
rf_tdata<-data[train,]  #训练集
rf_vdata<-data[-train,] #测试集

#### 寻找最优参数mtry na.roughfix是对缺失数据进行填补
d <- length(names(tdata))

rate=1     #设置模型误判率向量初始值

for(i in 1:(d-1)){
  set.seed(123)
  mtry_fit <- randomForest(as.factor(rf_tdata$类别)~.,data = rf_tdata,mtry=i,
                           na.action = na.roughfix,
                           importance = TRUE)
  rate[i]<-mean(mtry_fit$err.rate)   #计算基于OOB数据的模型误判率均值
  print(mtry_fit)    
}
rate     #展示所有模型误判率的均值
plot(rate) # mtry 取为2最好

### 寻找最佳参数ntree 
set.seed(100)
rf_train<-randomForest(as.factor(as.factor(rf_tdata$类别))~.,rf_tdata,mtry=2,ntree=1000,
                       na.action = na.roughfix,
                       importance = TRUE)
plot(rf_train)    #绘制模型误差与决策树数量关系图 ntree 取200-400都比较合适

########### 进行随机森林建模

set.seed(101)
rf_train<-randomForest(as.factor(as.factor(rf_tdata$类别))~.,rf_tdata,mtry=2,ntree=300,
                       na.action = na.roughfix,
                       importance = TRUE,proximity=TRUE)    



### 输出变量重要性测评
importance<- importance(rf_train,type=1) 
#计算各个变量在模型中的重要性,1表示使用精度平均较少值作为度量标准
#2表示采用节点不纯度的平均减少值最为度量标准。值越大说明变量的重要性越强;
write.csv(importance,file="/importance.csv",row.names=T,quote=F)
barplot(rf_train$importance[,1],main="输入变量重要性测度指标柱形图")
box()

importance(rf_train,type=1)
varImpPlot(x=rf_train,sort=TRUE,n.var=nrow(rf_train$importance),
           main="输入变量重要性测度散点图")
print(rf_train)    #展示随机森林模型简要信息

###可视化
hist(treesize(rf_train))  #展示随机森林模型中每棵决策树的节点数
max(treesize(rf_train));min(treesize(rf_train))
MDSplot(rf_train,rf_tdata$类别,palette=rep(1,2),
        pch=as.numeric(rf_tdata$类别))  #展示数据集在二维情况下各类别的具体分布情况


### 预测
pred<-predict(rf_train,newdata=rf_vdata)  
pred_out_1<-predict(object=rf_train,newdata=rf_vdata,type="prob")  #输出测试点是两类的概率
table <- table(pred,rf_vdata$类别)  
sum(diag(table))/sum(table)  #预测准确率
plot(margin(rf_train,test_data$IS_LIUSHI),main=观测值被判断正确的概率图)

pred <-predict(rf_train,newdata=rf_vdata,type="class")   #利用预测集进行预测
print(pred)
table2 <- table(rf_vdata$类别,pred,dnn=c("真实值","预测值"))    #输出混淆矩阵
rate2 <- sum(diag(table2))/sum(table2)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值