在插入符号中,cv 和 repeatcv 之间的真正区别是什么?

机器算法验证 r 机器学习 插入符号
2022-01-16 22:04:12

这类似于问题Caret re-sampling methods,尽管这实际上从未以商定的方式回答这部分问题。

caret 的 train 函数提供cvrepeatedcv. 说做有什么区别:

MyTrainControl=trainControl(
    method = "cv",
    number=5,
    repeats=5
)

对比

MyTrainControl=trainControl(
   method = "repeatedcv",
   number=5,
   repeats=5
)

我了解cv将集合分解为 k 折叠(参数number),然后重新开始并运行参数repeats次数。

我唯一能想到的是,也许经常cv使用repeats每次折叠的完全相同的索引?基本上cv每次都在相同的确切折叠上运行,而不是每次都repeatedcv选择新的折叠?

有人可以澄清吗?

3个回答

根据插入符手册(参见“参考手册”),该参数repeats仅在method设置为时适用,因此在设置为repeatedcv时不执行重复所以这两种方法的区别确实是重复和不重复。methodcvrepeatedcvcv


顺便说一句:使用完全相同的拆分重复交叉验证将为每次重复产生完全相同的结果(假设模型以确定性方式进行训练),这不仅效率低下,而且在比较验证结果时也很危险以统计方式的不同模型算法。因此,如果您必须自己编写验证程序,请注意这一点。

这些参数背后的实际代码可以在包的“caret/R/”文件夹中的selectByFilter.RcreateDataPartition.R(以前的)源文件中找到。createFolds.R

请参阅这些文件,例如此处此处(请注意,这些永久链接最终可能指向旧版本的代码)。为方便起见,相关片段(截至 2017 年 11 月版本 6.0-78)如下所示

在 selectByFilter.R c。第 157 行

sbf <- function (x, ...) UseMethod("sbf")
... 

"sbf.default" <-
  function(x, y,
           sbfControl = sbfControl(), ...)
  {
    ...

    if(is.null(sbfControl$index)) sbfControl$index <- switch(
      tolower(sbfControl$method),
      cv = createFolds(y, sbfControl$number, returnTrain = TRUE),
      repeatedcv = createMultiFolds(y, sbfControl$number, sbfControl$repeats),
      loocv = createFolds(y, length(y), returnTrain = TRUE),
      boot =, boot632 = createResample(y, sbfControl$number),
      test = createDataPartition(y, 1, sbfControl$p),
      lgocv = createDataPartition(y, sbfControl$number, sbfControl$p))
...

在 createDataPartition.R c。第 227 行

createMultiFolds <- function(y, k = 10, times = 5) {
  if(class(y)[1] == "Surv") y <- y[,"time"]
  prettyNums <- paste("Rep", gsub(" ", "0", format(1:times)), sep = "")
  for(i in 1:times) {
    tmp <- createFolds(y, k = k, list = TRUE, returnTrain = TRUE)
    names(tmp) <- paste("Fold",
                        gsub(" ", "0", format(seq(along = tmp))),
                        ".",
                        prettyNums[i],
                        sep = "")
    out <- if(i == 1) tmp else c(out, tmp)

  }
  out
}

诚然,这是一个非常古老的帖子,但基于 user3466398 提供的代码片段,不同之处在于repeatcv 正是这样做的:它对训练数据重复执行X-fold 交叉验证,即如果您指定5 次重复10 -fold cross-validation,它将对训练数据执行 10 次交叉验证 5 次,每次交叉验证使用不同的折叠集。

我认为这样做的基本原理是为了让交叉验证测试具有更准确和稳健的准确度,即可以报告平均 CV 准确度。