决策树模型与随机森林一文入门,原理、R语言示例
树模型,可解释的,简单粗暴的
几个例子理解决策树模型
想象一下:你的手里有一个篮子,里面既有苹果又有香蕉。而你的任务是区分它们。
你可能会问:“这个水果是黄色的吗?”如果答案是“是”,那么很可能是香蕉;如果答案是“否”,那么可能是苹果。
以上就是一个简单的决策树模型,用于分类任务,可以被称为分类树。
用于回归任务的决策树模型即回归树的原理也差不多,还是上面的例子:
这时,你的任务是推测这个水果的长度。
你可能会问:“这个水果是黄色的吗?”如果答案是“是”,那么它的长度可能是10cm(香蕉的平均长度);如果答案是“否”,那么它的长度可能是5cm(苹果的平均长度)。
更规范的讲
基于树的回归和分类方法,主要根据分层和分割的方式将预测变量的空间(水果的颜色)划分为一系列简单区域(黄色或者红色)。
▲ 分类树示意图(众数方法)
在模型的训练过程中,用预测变量空间中训练集的平均值(回归任务,黄色水果的平均长度是10)或众数(分类任务,黄色水果中香蕉的出现次数最多)对其进行预测。由于划分预测变量空间的分裂规则可以被概括为一棵树,所以该类方法被称为决策树方法。常见的决策树方法有:装袋法(bagging)、随机森林(random forest)、提升法(boosting)。
上面讲的例子用的是类别属性,也就是离散变量(颜色)。但是,实际情况下的决策树模型存在连续变量(比如水果的重量)。此外,预测变量的数目也不仅仅限于单一的水果的颜色(还可能有重量、生长周期等等的多种变量)。这时,预测变量的空间选择方法会复杂一些,常用的是递归二叉分裂(选择能够让当前分支RSS最小的预测变量以及相应的空间分裂点),不过会有很大过拟合的风险(当然,也有处理的方法,比如代价复杂性剪枝)。这里就不展开论述。
随机森林是什么
说起随机森林,必须先搞懂两个概念:
-
自助法:一种有放回的统计采样技术。举个例子,有一个容量为100的篮子,里面有100个球,编号从1到100。自助法采样是指,你每次随机地从篮子里抽出一个球(有放回的抽样,也就是说抽出的球会放回篮子里),并记下它的编号。这样抽100次,你就得到了一个新的编号列表。由于是随机且会放回的抽样,所以某些篮球可能被抽到了多次,也有些篮球可能一次都没有被抽到。更直接的讲,由自助法生成的数据集随机放大了某些样本对训练的影响,而又随机去除了某些样本对训练的影响。
-
袋装法:袋装法是一种集成学习技术。其基本思想是:从原始数据集中多次进行自助法采样,为每次的采样数据集建立一个模型,然后综合每个采样数据集生成的模型给出预测结果。例如:你想使用决策树进行袋装法建模。你可以从原始数据中抽取10个自助样本,然后为每个样本建立一个决策树。最后,当你有一个新的数据点需要预测时,你可以让这10棵决策树模型都进行预测,然后采取10颗树中最多次出现的类型(对于分类问题)或10颗树的平均值(对于回归问题)得到最终结果。
接下来就好讲了,因为随机森林只是在袋装法的基础上改进了两点:
-
特征的随机选择:在构建每棵决策树时,随机森林不是在所有的特征来找到最佳的分裂点(使得RSS最小),而是随机选择一个特征的子集来找分裂点。这增加了模型的多样性,有助于减少过拟合。简单来讲,一共有20个预测变量,但是在每次分叉时,只选取其中的一部分(比如10个)来进行筛选。在随机选出的10个预测变量中选择其中的一个变量对样本空间进行分割。
-
模型的多样性:由于每棵树都是在一个自助法随机抽取的数据子集上,并且使用随机的特征子集进行构建的,所以每棵树模型都是略有不同的。当这些树的预测被综合时,模型的方差会降低,从而增加模型的稳定性。
随机森林的构建与优化
随机森林的构建步骤:
-
Draw ntree bootstrap samples.
-
For each bootstrap, grow an un-pruned tree by choosing the best split based on a random sample of mtry predictors at each node
-
Predict new data using majority votes for classification and average for regression based on ntree trees.
1.引用r包:
library(randomForest)
library(datasets)
library(caret)
2.生成数据:
#The datasets contain 150 observations and 5 variables.
#Species considered as response variables. Species variable should be a factor variable.
data<-iris
str(data)
3.分割数据:
# 使用sample随机分割数据并生成数据集
set.seed(222)
ind <- sample(2, nrow(data), replace = TRUE, prob = c(0.7, 0.3))
train <- data[ind==1,]
test <- data[ind==2,]
4.构建Random Forest模型:
rf <- randomForest(Species~., data=train, proximity=TRUE)
print(rf)
# Call:
# randomForest(formula = Species ~ ., data = train)
# Type of random forest: classification
# Number of trees: 500
# No. of variables tried at each split: 2
# OOB estimate of error rate: 2.83%
optionTrees <- which.min(model$err.rate[,1]) # 选择误差最小树模型
model <- randomForest(labels~.-labels, data = train_expd, ntree=optionTrees)
# 预测新数据集
predict(rf, test)
# 可视化
plot(rf)
5.10折交叉验证选择最优模型:
# 10 folds repeat 3 times
# Create control function for training with 10 folds and keep 3 folds for training. search method is grid.
control <- trainControl(method='repeatedcv',
number=10,
repeats=3,
search='grid')
# create tunegrid with 15 values from 1:15 for mtry to tunning model. Our train function will change number of entry variable at each split according to tunegrid.
tunegrid <- expand.grid(.mtry = (1:15)) # 在1:15之间调整超参
rf_gridsearch <- train(Class ~ .,
data = train_expd,
method = 'rf',
metric = 'Accuracy',
tuneGrid = tunegrid)
rf_gridsearch <- rf_gridsearch$finalModel
print(rf_gridsearch)
# 可视化
plot(rf_gridsearch)
引用
-
https://rpubs.com/phamdinhkhanh/389752
-
https://www.r-bloggers.com/2021/04/random-forest-in-r/