这是带插入符号的分层 k-CV 吗?

Is this stratified k-CV with caret?

我想知道如何仅使用 R 中的 caret 包来编写分层 k-CV。请参阅以下示例:

library(mlbench)
library(caret)

data(Sonar)

set.seed(998)
inTraining <- createDataPartition(Sonar$Class, p = .75, list = FALSE)
training <- Sonar[ inTraining,]
testing  <- Sonar[-inTraining,]


folds <- createFolds(factor(training$Class), k = 10, list = TRUE)

fitControl <- trainControl(## 10-fold CV
method = "cv",
indexOut=folds,
savePredictions="all")

set.seed(825)
gbmFit1 <- train(Class ~ ., data = training, 
             method = "gbm", 
             trControl = fitControl,
             ## This last option is actually one
             ## for gbm() that passes through
             verbose = FALSE)

d=gbmFit1$pred

请注意,我没有指定 index,而只指定了 indexOut。 caret 是否每次都用 IndexOut 的补码训练模型?通过检查d,我可以看到rowIndex 匹配每个折叠的定义,但是我如何确认每次训练集都是第i 个元素的补集?

我发现这很有趣,因为我一直在使用 caret 并且从未想过关于 indexindexOut 的这种直接问题。 ?trainControl 下的帮助文档说 indexOut if NULL 将包含 index 中不包含的唯一样本集,但没有说明相反的情况。所以我深入研究 train.default 以了解发生了什么。当您分配

fitControl = trainControl(..., indexOut = ...)

你可以自己断言fitControl$index == NULL。在 train.default 的代码中有一行(函数定义的第 109 行)检查此条件,然后使用(对于 "cv")createFolds 和参数 returnTrain = TRUE。它会在不检查您为 indexOut 设置的内容的情况下执行此操作。

train.default 中似乎没有其他与 indexindexOut 相关的代码用于此特定场景。这表明没有什么可以保证 index$Fold01indexOut$Fold01.

之间没有交集

我们可以进一步研究

intersect(x$control$index$Fold01,x$control$indexOut$Fold01)
## [1]  12  18  33  34  53  58  67  95 109 111 115 120 137 143 156

来自 运行 您在问题中的确切代码。所以看起来 indexindexOut 并不是彼此的完美补充。

我建议最安全的方法是指定 index 而不是 indexOut 以获得预期的效果。