# 使用的数据集
library(mlbench)
data(Sonar)
dim(Sonar)
## [1] 208 61
str(Sonar[, 1:10])# 展示前10列
## 'data.frame': 208 obs. of 10 variables:
## $ V1 : num 0.02 0.0453 0.0262 0.01 0.0762 0.0286 0.0317 0.0519 0.0223 0.0164 ...
## $ V2 : num 0.0371 0.0523 0.0582 0.0171 0.0666 0.0453 0.0956 0.0548 0.0375 0.0173 ...
## $ V3 : num 0.0428 0.0843 0.1099 0.0623 0.0481 ...
## $ V4 : num 0.0207 0.0689 0.1083 0.0205 0.0394 ...
## $ V5 : num 0.0954 0.1183 0.0974 0.0205 0.059 ...
## $ V6 : num 0.0986 0.2583 0.228 0.0368 0.0649 ...
## $ V7 : num 0.154 0.216 0.243 0.11 0.121 ...
## $ V8 : num 0.16 0.348 0.377 0.128 0.247 ...
## $ V9 : num 0.3109 0.3337 0.5598 0.0598 0.3564 ...
## $ V10: num 0.211 0.287 0.619 0.126 0.446 ...
41 caret实现多模型比较
该方法基于
caret
实现,caret
曾经是R语言里做机器学习和预测模型最火爆的R包之一(现在不是了),公众号后台回复caret即可获取caret
合集链接,带你全面了解caret
。
caret
是R里面经典的综合性统计建模R包,目前来看已经落后于mlr3
和tidymodels
了,但是作为老牌R包,日常使用还是没问题的(速度很慢)。
41.1 数据划分
下面是一个分类数据的演示。这个数据一共208行,61列,其中Class
是结果变量,二分类,因子型,其余变量都是预测变量。
划分训练集、测试集:
# 加载R包,划分数据集
library(caret)
# 训练集、测试集划分,比例为0.75
set.seed(998)
<- createDataPartition(Sonar$Class, p = .75, list = FALSE)
inTraining <- Sonar[inTraining,]
training <- Sonar[-inTraining,] testing
41.2 建立多个模型
首先建立一个boosted tree
模型,并设置好它的超参数范围以及重抽样方法:
# 网格搜索,首先设定超参数范围
<- expand.grid(interaction.depth = c(1, 5, 9),
gbmGrid n.trees = (1:30)*50,
shrinkage = 0.1,
n.minobsinnode = 20)
nrow(gbmGrid)
## [1] 90
head(gbmGrid)
## interaction.depth n.trees shrinkage n.minobsinnode
## 1 1 50 0.1 20
## 2 5 50 0.1 20
## 3 9 50 0.1 20
## 4 1 100 0.1 20
## 5 5 100 0.1 20
## 6 9 100 0.1 20
设置boosted tree
模型的重抽样方法:
# trainControl函数用来设置非常多的东西,重复10次的10折交叉验证
<- trainControl(method = "repeatedcv",
fitControl number = 10,
repeats = 10,
classProbs = TRUE, # 计算概率
summaryFunction = twoClassSummary # 二分类指标
)
选择好之后开始拟合模型(及超参数调优):
# 选择好之后开始调优
set.seed(825)
<- train(Class ~ .,
gbmFit3 data = training,
method = "gbm",
trControl = fitControl,
verbose = FALSE,
tuneGrid = gbmGrid,
metric = "ROC" # 选择指标
)
gbmFit3#saveRDS(gbmFit3,file = "./datasets/gbmFit3.rds")
上面的例子展示了caret
包建模的基本语法,就是一个train()
就可以了,method
参数选择模型,trControl
选择重抽样方法,preProcess
选择数据预处理方法(上面这个例子没有进行数据预处理)。
train()
函数中的metric
参数可以指定调优的指标,默认分类模型是accuracy和Kappa,回归模型是RMSE/R2/MAE。
trainControl()
中的summaryFunction
参数还提供了额外的调优指标选项,比如上面这个twoClassSummary
,内含3种指标:敏感度、特异度、ROC。
然后再建立一个支持向量机模型和正则化的判别分析模型。
# 选择重抽样方法,重复10次的10折交叉验证
<- trainControl(method = "repeatedcv", #默认是simple boost
fitControl number = 10,
repeats = 10,
classProbs = T # 计算概率
)
开始拟合模型:
# 支持向量机,高斯径向基核
set.seed(825)
<- train(Class ~ .,
svmFit data = training,
method = "svmRadial",
trControl = fitControl,
preProc = c("center", "scale"),
tuneLength = 8,
metric = "ROC")
# 正则化的判别分析
set.seed(825)
<- train(Class ~ .,
rdaFit data = training,
method = "rda",
trControl = fitControl,
tuneLength = 4,
metric = "ROC")
#save(svmFit, rdaFit,file = "./datasets/svm_rda_fit.rdata")
这样我们就建立好了3个模型。
41.3 结果查看
可以单独查看每个模型的结果,直击打印即可:
# 比如查看gbm模型
gbmFit3
Stochastic Gradient Boosting
157 samples
60 predictor
2 classes: 'M', 'R'
-processing
No pre: Cross-Validated (10 fold, repeated 10 times)
Resampling: 141, 142, 141, 142, 141, 142, ...
Summary of sample sizes:
Resampling results across tuning parameters
interaction.depth n.trees ROC Sens Spec 1 50 0.8634003 0.8631944 0.6905357
1 100 0.8844097 0.8486111 0.7544643
##省略一部分,太长了
9 1500 0.9181721 0.8805556 0.8039286
'shrinkage' was held constant at a value of 0.1
Tuning parameter
'n.minobsinnode' was held constant at a value of 20
Tuning parameter
ROC was used to select the optimal model using the largest value.for the model were n.trees =
The final values used 1450, interaction.depth = 5, shrinkage = 0.1 and n.minobsinnode = 20.
结果没什么难度,我就不帮大家翻译了。
也可以一起放入resamples()
函数里面,可以得到每个模型的指标的统计值,比如ROC的最大值、最小值、均值、中位数等:
<- resamples(list(GBM = gbmFit3,
resamps SVM = svmFit,
RDA = rdaFit))
#resamps
summary(resamps)
##
## Call:
## summary.resamples(object = resamps)
##
## Models: GBM, SVM, RDA
## Number of resamples: 100
##
## ROC
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## GBM 0.6964286 0.874504 0.9454365 0.9216468 0.9821429 1 0
## SVM 0.7321429 0.905878 0.9464286 0.9339658 0.9821429 1 0
## RDA 0.5625000 0.812500 0.8750000 0.8698115 0.9392361 1 0
##
## Sens
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## GBM 0.5555556 0.7777778 0.8750000 0.8787500 1 1 0
## SVM 0.5000000 0.7777778 0.8888889 0.8730556 1 1 0
## RDA 0.4444444 0.7777778 0.8750000 0.8604167 1 1 0
##
## Spec
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## GBM 0.4285714 0.7142857 0.8571429 0.8119643 1.0000000 1 0
## SVM 0.4285714 0.7142857 0.8571429 0.8205357 0.9062500 1 0
## RDA 0.1428571 0.5714286 0.7142857 0.6941071 0.8571429 1 0
结果就很强!分别给出了3种指标下的每种模型的统计值。
41.4 结果可视化
喜闻乐见的结果可视化也是必不可少的。主要包括以下几种(都是基于lattice
的):
- density plots,
- box-whisker plots,
- scatterplot matrices,
- scatterplots
箱线图:
# 设主题
<- trellis.par.get()
theme1 $plot.symbol$col = rgb(.2, .2, .2, .4)
theme1$plot.symbol$pch = 16
theme1$plot.line$col = rgb(1, 0, 0, .7)
theme1$plot.line$lwd <- 2
theme1
# 画图,箱线图
trellis.par.set(theme1)
bwplot(resamps, layout = c(3, 1))
密度图:
# 密度图
trellis.par.set(theme1)
densityplot(resamps)
换个指标,点线图:
# 换个指标,点线图
trellis.par.set(caretTheme())
dotplot(resamps, metric = "ROC")
散点图:
# 散点图
trellis.par.set(theme1)
xyplot(resamps, what = "BlandAltman")
散点图矩阵:
# 散点图矩阵
splom(resamps)
41.5 显著性检验
除此之外,我们还可以对不同模型之间的差异进行显著性检验,比如t检验,结果会给出多重校正检验(bonferroni法)的p值,非常高大上:
<- diff(resamps)
difValues
difValues##
## Call:
## diff.resamples(x = resamps)
##
## Models: GBM, SVM, RDA
## Metrics: ROC, Sens, Spec
## Number of differences: 3
## p-value adjustment: bonferroni
summary(difValues)
##
## Call:
## summary.diff.resamples(object = difValues)
##
## p-value adjustment: bonferroni
## Upper diagonal: estimates of the difference
## Lower diagonal: p-value for H0: difference = 0
##
## ROC
## GBM SVM RDA
## GBM -0.01232 0.05184
## SVM 0.3408 0.06415
## RDA 5.356e-07 2.638e-10
##
## Sens
## GBM SVM RDA
## GBM 0.005694 0.018333
## SVM 1.0000 0.012639
## RDA 0.4253 1.0000
##
## Spec
## GBM SVM RDA
## GBM -0.008571 0.117857
## SVM 1 0.126429
## RDA 8.230e-07 1.921e-10
这个结果展示的是不同模型之间的差异和t检验的p值。比如第一个矩阵(ROC的这个),先横着看,GBM和GBM是一个,不用比,GBM和SVM比,平均ROC的差异是-0.01232,GBM和RDA比,平均ROC的差异是0.05184;再顺着看,GBM和SVM的t检验的p值是0.3408,说明无统计学差异,GBM和RDA的t检验的p值是5.356e-07,有统计学差异。
结果的可视化,使用箱线图,同时展示3种指标,这个图展示的是不同模型之间性能指标的差异分布情况:
trellis.par.set(theme1)
bwplot(difValues, layout = c(3, 1))
下面这个图展示的是不同模型性能指标差异的95%可信区间,如果通过了0,说明没差异,这个图的结果和上面统计检验的结果是相同的:
trellis.par.set(caretTheme())
dotplot(difValues)
是不是很强!
这里介绍的caret
的内容比较简单,大家如果想认真学习这个R包的话肯定是要下一番功夫的,我在公众号写了非常多相关的推文,可以在公众号后台回复caret
获取合集。