什么是随机森林?
开门见山,随机森林这个名称真的非常符合这一模型的特点,我们结合下面的示意图来看随机森林模型的具体运算步骤:
随机森林模型运算过程示意图
3.按照上述方式得到多棵不尽相同的决策树形成森林,对于测试数据集,综合所有决策树的预测结果得到最终预测结果。
例如对于分类任务,可以取所有决策树预测类别中数量最多的那一类作为个体的最终分类结果;
对于回归任务,可以取所有决策树预测结果的平均值作为个体的预测值。
既然已经有了决策树算法,为什么还要开发随机森林算法呢?
核心原因是决策树算法存在容易过拟合、模型结构不稳定的缺点,随机森林能够通过袋装法(Bagging)集成多棵决策树提高模型的泛化能力和稳健性。
通俗的说,就算决策树是诸葛亮,随机森林也至少是多个臭皮匠,多人决策的结果未必是最好的,但是是最中肯的,能避免过激的决策。
为什么要用随机抽样和随机特征选取来构建决策树?
在个体分类器的错误率相互独立的条件下,根据Hoeffding不等式可知,随着集成模型中个体分类器数量的增加,集成模型的错误率将指数级下降,最终趋向于0。
在实际中,个体分类器是为解决同一个问题训练出来的,分类错误率显然并不是相互独立的。尽管我们在实际中无法做到个体学习器间的完全独立,但可以设法让个体学习器尽可能不同,随机抽样和随机特征选取就是这样的两种办法。
随机森林的核心超参数有哪些?
随机森林最重要的超参数有两个,一个是决策树的数量,另一个是生成单棵决策树时每个决策节点随机选取的变量数,这两个超参数设置是否合理对预测效果影响较大。
另外所有决策树的最大深度、节点分裂最小样本数也是较重要的。
R语言随机森林预测模型实例
## 加载数据 ##
library(MASS)
data(biopsy)
## 数据预处理 ##
library(dplyr)
biopsy_2 <- biopsy %>%
dplyr::select(-ID) %>% #去掉id列
filter(complete.cases(.)) %>% #去掉变量有缺失值的观测
rename(nd=V1, jyd.size=V2, jyd.shape=V3,
nzd=V4, size.dsp=V5, lxbh=V6,
rsz=V7, hr=V8, ysfl=V9) #改变细胞特征变量的变量名,方便后面查看
细胞特征变量包括:细胞浓度(nd)、细胞大小均匀度(jyd.size)、细胞形状均匀度(jyd.shape)、边缘黏着度(nzd)、单上皮细胞大小(size.dsp)、裸细胞核(lxbh)、平和染色质(rsz)、正常核仁(hr)、有丝分裂状态(ysfl)。 class变量是肿瘤良恶性诊断结果,“benign”是良性,“malignant”是恶性,该变量是我们分析的结果变量。
√其次将数据集按7:3比例随机划分为训练集和测试集:
## 数据集划分 ##
set.seed(0) #设置随机种子数,用于复现结果
index.train <- sample(1:nrow(biopsy_2), 0.7*nrow(biopsy_2)) #训练集的观测索引
index.test <- setdiff(1:nrow(biopsy_2),index.train) #测试集的观测索引
data.train <- biopsy_2[index.train, ] #训练集
data.test <- biopsy_2[index.test, ] #测试集
√接着训练随机森林模型并查看过程中的一些信息:
## 构建随机森林模型 ##
library(randomForest)#加载随机森林的包
set.seed(12345678)
rf.trained <- randomForest(class ~ ., data = data.train)#训练好的随机森林模型
rf.trained#查看训练过程的信息
plot(rf.trained)#决策树数量和袋外数据分类误差的关系图
黑线表示全部袋外数据的错分率,绿线、红线分别表示袋外数据中malignant类别、benign类别的错分率。
从图中可以看到袋外数据错分率并不是在ntree=500时达到最小,而是150左右。
我们以此调整模型结构,重新训练模型。
√接下来调整随机森林中树的数量,重新训练:
## 调整决策树数量 ##
ntrees.minerr <- which.min(rf.trained$err.rate[, 1])#袋外数据(“验证集”)分类误差最小时的决策树数量
ntrees.minerr#147棵
set.seed(12345678)
rf.trained.best <- randomForest(class ~ ., data = data.train, ntree=ntrees.minerr)#用147棵决策树构建随机森林
rf.trained.best#查看训练过程的信息
## 测试集评价最优模型预测效果 ##
predicted_probs.test <- predict(rf.trained.best, newdata = data.test,
type = "prob")[,2]#对测试集的结局预测,输出为malignant的概率
predicted_values.test <- predict(rf.trained.best, newdata = data.test,
type = "class")#测试集的结局预测,输出分类结果
# 查看预测效果
confusion_matrix <- table(Predicted = predicted_values.test, Actual = data.test$class)# 创建混淆矩阵
library(caret)
confusionMatrix(confusion_matrix)#输出模型预测准确率、灵敏度、特异度
library(pROC)
roc_curve <- roc(data.test$class, predicted_probs.test) #构建ROC曲线
roc_curve$auc#输出模型AUC值
plot(roc_curve, main = "ROC曲线", col = "blue",
lwd = 2, lty = 1,
xlab = "1-特异度", ylab = "灵敏度",
print.auc = TRUE, grid = TRUE)#可视化ROC曲线
# 查看每个变量对分类的重要性 ##
varImpPlot(rf.trained.best)
随机森林模型的优缺点
关于郑老师团队及公众号
大型医学统计服务公众号平台,专注于医学生、医护工作者学术研究统计支持,我们是你们统计助理
我们开展对临床预测模型、机器学习、医学免费数据库NHANES、GBD数据库、孟德尔随机化方法、MIMIC 一对一R语言指导开展统计分析(一年内不限时间,周末、晚上均统计师一对一指导)。
①指导学习R语言基本技巧
②全程指导课程学习
③课程R语言代码运行bug修复
④支持学员一篇SCI论文的数据分析
详情联系助教小董咨询(微信号aq566665)