如何使用 R 中的 k 折 CV 每折手动训练数据?
How train data manually per fold with k-fold CV in R?
我有以下适合我的代码段,我得到了模型结果:
library(base)
library(caret)
library(tidyverse)
dataset <- read_csv("https://gist.githubusercontent.com/dmpe/bfe07a29c7fc1e3a70d0522956d8e4a9/raw/7ea71f7432302bb78e58348fede926142ade6992/pima-indians-diabetes.csv", col_names=FALSE)
X = dataset[, 1:8]
Y = as.factor(ifelse(dataset$X9 == 1, 'diabetes', 'nondiabetes'))
set.seed(88)
nfolds <- 3
cvIndex <- createFolds(Y, nfolds, returnTrain = T)
fit.control <- trainControl(method="cv",
index=cvIndex,
number=nfolds,
classProbs=TRUE,
savePredictions=TRUE,
verboseIter=TRUE,
summaryFunction=twoClassSummary,
allowParallel=FALSE)
model <- caret::train(X, Y,
method = "svmLinear",
trControl = fit.control,
preProcess=c("center","scale"),
tuneLength=10)
使用它我可以访问最终模型 model$finalModel
,但是,在这种情况下,我实际上想要 3 个模型而不是一个最终模型,因为我有 3 倍。所以,我想在第一次折叠后得到经过训练的模型,然后是第二次折叠后,最后是第三次折叠后,这对应于实际的最终模型。任何想法如何在 R 中实现这一点?请注意 caret
的用法并不严格,如果您可以使用 mlr
也欢迎。
插入符号中的训练函数简化了模型评估和训练
https://cran.r-project.org/web/packages/caret/vignettes/caret.html
"使用重采样评估模型调整参数对性能的影响
在这些参数中选择“最佳”模型
从训练集中估计模型性能
所以,它给出的模型是最优的最终模型。
没有理由使用在每个折叠上训练的模型。我不知道如何在 R
中执行此操作
既不是插入符号也不是机器学习专家,但为什么不在随机样本上训练模型并将结果存储在列表中呢?
data <- read_csv("https://gist.githubusercontent.com/dmpe/bfe07a29c7fc1e3a70d0522956d8e4a9/raw/7ea71f7432302bb78e58348fede926142ade6992/pima-indians-diabetes.csv", col_names=FALSE)
train_multiple_models <- function(data, kfolds) {
resultlist <- list()
for(i in 1:kfolds) {
sample <- sample.int(n = nrow(data), size = floor(.75*nrow(data)), replace = F)
train <- data[sample, ]
X = train[, 1:8]
Y = as.factor(ifelse(train$X9 == 1, 'diabetes', 'nondiabetes'))
model <- caret::train(X, Y,
method = "svmLinear",
preProcess=c("center","scale"),
tuneLength=10)
resultlist[[i]] <- model
}
return(resultlist)
}
result <- train_multiple_models(data, kfolds = 3)
> result[[1]]$finalModel
Support Vector Machine object of class "ksvm"
SV type: C-svc (classification)
parameter : cost C = 1
Linear (vanilla) kernel function.
Number of Support Vectors : 307
Objective Function Value : -302.065
Training error : 0.230903
这里有一个使用 mlr 包的方法:
library(mlr)
library(base)
library(tidyverse)
dataset <- read_csv("https://gist.githubusercontent.com/dmpe/bfe07a29c7fc1e3a70d0522956d8e4a9/raw/7ea71f7432302bb78e58348fede926142ade6992/pima-indians-diabetes.csv", col_names=FALSE)
X = dataset[, 1:8]
Y = as.factor(ifelse(dataset$X9 == 1, 'diabetes', 'nondiabetes'))
创建一个 mlr 任务:
mlr_task <- makeClassifTask(data = data.frame(X, Y),
target = "Y",
positive = "diabetes")
定义重采样:
set.seed(7)
cv3 <- makeResampleInstance(makeResampleDesc("CV", iters = 3),
task = mlr_task)
定义超参数搜索的类型
ctrl <- makeTuneControlRandom(maxit = 10L)
定义学习者
lrn <- makeLearner("classif.ksvm", predict.type = "prob")
可选地检查学习者参数以查看要调整的参数
mlr::getLearnerParamSet(lrn)
定义搜索space(vanilladot 是 kernlab 包中的线性内核,在内部为 "classif.ksvm" 调用)。有关 mlr 中集成学习器的更多信息:https://mlr.mlr-org.com/articles/tutorial/integrated_learners.html
ps <- makeParamSet(makeDiscreteParam("kernel", "vanilladot"),
makeNumericParam("C", lower = 2e-6, upper = 2e-6))
调整超参数。我只是设置了一些随机的措施,列出的第一个用于评估性能,其他的只是为了展示。
res <- tuneParams(lrn,
mlr_task,
cv3,
measures = list(auc, bac, f1),
par.set = ps,
control = ctrl)
为学习者设置最佳超参数
lrn <- setHyperPars(lrn, par.vals = res$x)
使用 models = TRUE
重新采样
rsmpls <- resample(lrn,
mlr_task,
cv3,
measures = list(auc, bac, f1),
models = TRUE)
模型在
rsmpls$models[[1]]$learner.model
rsmpls$models[[2]]$learner.model
rsmpls$models[[3]]$learner.model
它的作用是首先调整超参数,然后在相同的折叠上使用调整后的参数执行另一组交叉验证。
一种替代方法,在我看来,一种更好的方法是在嵌套交叉验证的内部折叠中选择超参数,并在外部折叠上进行评估,使外部折叠模型保持 fiddle with.
lrn <- makeLearner("classif.ksvm", predict.type = "prob")
定义内部重采样策略
cv3_inner <- makeResampleDesc("CV", iters = 3)
创建一个 tune wrapper - 定义内部交叉验证循环中发生的事情
lrn <- makeTuneWrapper(lrn,
resampling = cv3_inner,
measures = list(auc, bac, f1),
par.set = ps,
control = ctrl)
执行外部交叉验证
rsmpls <- resample(lrn,
mlr_task,
cv3,
measures = list(auc, bac, f1),
models = TRUE)
这在外循环中执行三重 CV,在每个训练实例中,另一个,执行三重 CV 以调整超参数,并使用最佳超参数在整个训练实例上拟合模型,评估这些模型在外循环测试实例上。这样做是为了减少评估偏差。另见:https://mlr.mlr-org.com/articles/tutorial/nested_resampling.html
我有以下适合我的代码段,我得到了模型结果:
library(base)
library(caret)
library(tidyverse)
dataset <- read_csv("https://gist.githubusercontent.com/dmpe/bfe07a29c7fc1e3a70d0522956d8e4a9/raw/7ea71f7432302bb78e58348fede926142ade6992/pima-indians-diabetes.csv", col_names=FALSE)
X = dataset[, 1:8]
Y = as.factor(ifelse(dataset$X9 == 1, 'diabetes', 'nondiabetes'))
set.seed(88)
nfolds <- 3
cvIndex <- createFolds(Y, nfolds, returnTrain = T)
fit.control <- trainControl(method="cv",
index=cvIndex,
number=nfolds,
classProbs=TRUE,
savePredictions=TRUE,
verboseIter=TRUE,
summaryFunction=twoClassSummary,
allowParallel=FALSE)
model <- caret::train(X, Y,
method = "svmLinear",
trControl = fit.control,
preProcess=c("center","scale"),
tuneLength=10)
使用它我可以访问最终模型 model$finalModel
,但是,在这种情况下,我实际上想要 3 个模型而不是一个最终模型,因为我有 3 倍。所以,我想在第一次折叠后得到经过训练的模型,然后是第二次折叠后,最后是第三次折叠后,这对应于实际的最终模型。任何想法如何在 R 中实现这一点?请注意 caret
的用法并不严格,如果您可以使用 mlr
也欢迎。
插入符号中的训练函数简化了模型评估和训练 https://cran.r-project.org/web/packages/caret/vignettes/caret.html
"使用重采样评估模型调整参数对性能的影响 在这些参数中选择“最佳”模型 从训练集中估计模型性能
所以,它给出的模型是最优的最终模型。 没有理由使用在每个折叠上训练的模型。我不知道如何在 R
中执行此操作既不是插入符号也不是机器学习专家,但为什么不在随机样本上训练模型并将结果存储在列表中呢?
data <- read_csv("https://gist.githubusercontent.com/dmpe/bfe07a29c7fc1e3a70d0522956d8e4a9/raw/7ea71f7432302bb78e58348fede926142ade6992/pima-indians-diabetes.csv", col_names=FALSE)
train_multiple_models <- function(data, kfolds) {
resultlist <- list()
for(i in 1:kfolds) {
sample <- sample.int(n = nrow(data), size = floor(.75*nrow(data)), replace = F)
train <- data[sample, ]
X = train[, 1:8]
Y = as.factor(ifelse(train$X9 == 1, 'diabetes', 'nondiabetes'))
model <- caret::train(X, Y,
method = "svmLinear",
preProcess=c("center","scale"),
tuneLength=10)
resultlist[[i]] <- model
}
return(resultlist)
}
result <- train_multiple_models(data, kfolds = 3)
> result[[1]]$finalModel
Support Vector Machine object of class "ksvm"
SV type: C-svc (classification)
parameter : cost C = 1
Linear (vanilla) kernel function.
Number of Support Vectors : 307
Objective Function Value : -302.065
Training error : 0.230903
这里有一个使用 mlr 包的方法:
library(mlr)
library(base)
library(tidyverse)
dataset <- read_csv("https://gist.githubusercontent.com/dmpe/bfe07a29c7fc1e3a70d0522956d8e4a9/raw/7ea71f7432302bb78e58348fede926142ade6992/pima-indians-diabetes.csv", col_names=FALSE)
X = dataset[, 1:8]
Y = as.factor(ifelse(dataset$X9 == 1, 'diabetes', 'nondiabetes'))
创建一个 mlr 任务:
mlr_task <- makeClassifTask(data = data.frame(X, Y),
target = "Y",
positive = "diabetes")
定义重采样:
set.seed(7)
cv3 <- makeResampleInstance(makeResampleDesc("CV", iters = 3),
task = mlr_task)
定义超参数搜索的类型
ctrl <- makeTuneControlRandom(maxit = 10L)
定义学习者
lrn <- makeLearner("classif.ksvm", predict.type = "prob")
可选地检查学习者参数以查看要调整的参数
mlr::getLearnerParamSet(lrn)
定义搜索space(vanilladot 是 kernlab 包中的线性内核,在内部为 "classif.ksvm" 调用)。有关 mlr 中集成学习器的更多信息:https://mlr.mlr-org.com/articles/tutorial/integrated_learners.html
ps <- makeParamSet(makeDiscreteParam("kernel", "vanilladot"),
makeNumericParam("C", lower = 2e-6, upper = 2e-6))
调整超参数。我只是设置了一些随机的措施,列出的第一个用于评估性能,其他的只是为了展示。
res <- tuneParams(lrn,
mlr_task,
cv3,
measures = list(auc, bac, f1),
par.set = ps,
control = ctrl)
为学习者设置最佳超参数
lrn <- setHyperPars(lrn, par.vals = res$x)
使用 models = TRUE
rsmpls <- resample(lrn,
mlr_task,
cv3,
measures = list(auc, bac, f1),
models = TRUE)
模型在
rsmpls$models[[1]]$learner.model
rsmpls$models[[2]]$learner.model
rsmpls$models[[3]]$learner.model
它的作用是首先调整超参数,然后在相同的折叠上使用调整后的参数执行另一组交叉验证。
一种替代方法,在我看来,一种更好的方法是在嵌套交叉验证的内部折叠中选择超参数,并在外部折叠上进行评估,使外部折叠模型保持 fiddle with.
lrn <- makeLearner("classif.ksvm", predict.type = "prob")
定义内部重采样策略
cv3_inner <- makeResampleDesc("CV", iters = 3)
创建一个 tune wrapper - 定义内部交叉验证循环中发生的事情
lrn <- makeTuneWrapper(lrn,
resampling = cv3_inner,
measures = list(auc, bac, f1),
par.set = ps,
control = ctrl)
执行外部交叉验证
rsmpls <- resample(lrn,
mlr_task,
cv3,
measures = list(auc, bac, f1),
models = TRUE)
这在外循环中执行三重 CV,在每个训练实例中,另一个,执行三重 CV 以调整超参数,并使用最佳超参数在整个训练实例上拟合模型,评估这些模型在外循环测试实例上。这样做是为了减少评估偏差。另见:https://mlr.mlr-org.com/articles/tutorial/nested_resampling.html