我怎么知道哪种交叉验证方法最好?

机器算法验证 r 回归 交叉验证 线性模型
2022-01-30 17:47:59

我试图找出哪种交叉验证方法最适合我的情况。

以下数据只是解决问题的一个示例(在 R 中),但我的真实X数据 ( xmat) 彼此相关,并且与y变量 ( ymat) 有不同程度的相关。我提供了 R 代码,但我的问题不是关于 R,而是关于方法。Xmat包括 X 变量 V1 到 V100,同时ymat包括单个 y 变量。

set.seed(1233)
xmat           <- matrix(sample(-1:1, 20000, replace = TRUE), ncol = 100)
colnames(xmat) <- paste("V", 1:100, sep ="")
rownames(xmat) <- paste("S", 1:200, sep ="")
  # the real y data are correlated with xmat
ymat           <- matrix(rnorm(200, 70,20), ncol = 1)
rownames(ymat) <- paste("S", 1:200, sep="")

我想建立一个y基于所有变量的预测模型xmat所以这将是一个线性回归模型y ~ V1 + V2 + V3+ ... + V100从评论中,我可以看到以下三种交叉验证方法:

  1. 将数据分成大约一半,一个用于训练,另一半用于测试(交叉验证):

    prop       <- 0.5 # proportion of subset data
    set.seed(1234)
      # training data set 
    training.s <- sample (1:nrow(xmat), round(prop*nrow(xmat),0))
    xmat.train <- xmat[training.s,]
    ymat.train <- ymat[training.s,]
    
      # testing data set 
    testing.s <- setdiff(1:nrow(xmat), training)
    xmat.test <- xmat[testing.s,]
    ymat.test <- ymat[testing.s,]
    
  2. K 折交叉验证- 使用 10 折交叉验证:

    mydata <- data.frame(ymat, xmat)
    fit    <- lm(ymat ~ ., data=mydata)
    library(DAAG)
    cv.lm(df=mydata, fit, m=10) # ten-fold cross validation 
    
  3. 一次屏蔽一个或几个值:在这种方法中,我们通过将数据集 (y) 中的一个值替换为 NA 来随机屏蔽一个值并对其进行预测。该过程重复n次。

    n = 500 
    predicted.v <- rep(NA, n)
    real.v      <- rep(NA, n)
    
    for (i in 1:n){
      masked.id <- sample (1:nrow(xmat), 1)
      ymat1     <- ymat 
      real.v[i] <- ymat[masked.id,]
      ymat1[masked.id,] <- NA
      mydata            <- data.frame(ymat1, xmat)
      fit               <- lm(ymat1 ~ ., data=mydata)
      predicted.v[i]    <- fit$fitted.values[masked.id]
    }
    

我怎么知道哪种情况最适合?还有其他方法吗?Bootstrap validationCV工作示例将不胜感激。

2个回答

由于 OP 在这个问题上悬赏,它应该引起一些注意,因此它是讨论一些一般性想法的正确场所,即使它没有直接回答 OP。

一、名称:

a)交叉验证是所有使用不同于训练集的测试集的估计​​/测量技术的总称。同义词:样本外或样本外估计。反义词:样本内估计。

样本内估计是使用训练集上的一些信息来估计模型质量(不一定是错误)的技术。如果模型有很大的偏差,这很常见——也就是说,它对数据做出了强有力的假设。在线性模型(高偏差模型)中,如问题示例中一样,使用 R 平方、AIC、BIC、偏差作为模型质量的度量——所有这些都是样本内估计量。例如,在 SVM 中,支持向量中的数据与数据数量的比率是模型误差的样本内估计。

有许多交叉验证技术:

b)坚持是上面的方法#1。将集合拆分为一个训练和一个测试。关于训练集和测试集的相对大小的讨论和实践由来已久。

c) k -fold – 上面的方法#2。很标准。

d)留一法——上面的方法#3。

e) bootstrap:如果你的集合有N个数据,从集合中随机选择N个带替换的样本作为训练。原始集合中没有任何时间样本的数据用作测试集。有不同的方法来计算模型误差的最终估计,它使用测试集的误差(样本外)和训练集的误差(样本内)。例如,参见 .632 引导程序。我认为还有一个 .632+ 公式——它们是使用样本外和样本内误差估计模型真实误差的公式。

f) 与上述方法的选择正交的是重复问题。除了留一法外,以上所有方法都可以重复任意次数。事实上,人们可以谈论 REPEATED hold-out 或 REPEATED k -fold。公平地说,几乎总是以重复的方式使用引导方法。


下一个问题是,哪种方法“更好”。问题是“更好”是什么意思。

1)第一个答案是这些方法中的每一个是否对模型误差的估计都有偏差(对于无限量的未来数据)。

2)第二种选择是这些方法中的每一种收敛到真实模型误差的速度或程度(如果它们没有偏差)。我相信这仍然是一个研究课题。让我指出这两篇论文(在付费墙后面),但摘要让我们对他们试图完成的工作有所了解。另请注意,将k -fold 本身称为“交叉验证”是很常见的。

关于这些主题可能还有许多其他论文。这些只是一些例子。

3)“更好”的另一个方面是:给定使用上述技术之一的模型误差的特定度量,您如何确定正确的模型误差接近。

通常,在这种情况下,您需要对误差进行许多测量并计算置信区间(如果您遵循贝叶斯方法,则为可信区间)。在这种情况下,问题是您可以在多大程度上信任一组错误度量的方差。请注意,除了留一法之外,上述所有技术都会为您提供许多不同的测量值(k测量用于k倍,n测量用于n重复保持),因此您可以测量方差(或标准偏差) 并计算误差度量的置信区间。

这里的事情变得有些复杂。根据我从论文No unbiased estimator of the variance of k -fold cross-validation (not behind paywall) 的理解,人们不能相信你从k折中得到的方差——所以不能从k中构造一个好的置信区间——折叠。同样从我从论文Approximate Statistical Tests for Comparing Supervised Classification Learning Algorithms (not behind paywall) 中了解到,使用重复测量的技术(repeated k-fold,重复保持 - 不确定引导程序)将子估计误差测量的真实方差(这有点容易看出 - 因为如果你重复测量一个非常大的数字,你是从一个有限集合中抽样的有时,相同的值将不断重复,这使均值保持不变,但减少了方差)。因此,重复测量技术对置信区间过于乐观。

最后一篇论文建议做 5 次重复的 2 倍——他称之为 5×2 CV——作为许多测量 (10) 的良好平衡,但不要重复太多。

编辑:

当然,Cross Validated 中对其中一些问题有很好的答案(尽管有时他们之间不同意)。这里有一些:

交叉验证或引导来评估分类性能?

交叉验证和自举估计预测误差之间的差异

交叉验证或引导来评估分类性能?

了解验证和模型选择的引导

一般来说,标签是你的朋友吗?


那么最好的解决方案是什么?我不知道。当我需要非常严格时,我一直在使用 5×2 CV,当我需要确定一种技术比另一种更好时,尤其是在出版物中。如果我不打算对方差或标准差进行任何测量,或者如果我有时间限制,我会使用保留 - 在保留中只有一个模型学习。

有关方法定义,请参阅维基百科页面(它们比我在这里做的要好得多)。

在您查看该页面后,以下内容可能对您有所帮助。让我关注问题的一部分,即人们想为他们的建模过程选择其中一种方法。由于这是一个人经常做出的选择,并且他们可以从额外的知识中受益,因此我对两种情况的回答如下:

  1. 任何情况:使用k-fold cross validation适当数量的重复(例如 5 或 10)。

    • 无论如何,将数据分成 1 半,在前半部分进行训练并在另一部分进行验证是 2 折交叉验证的一个步骤(另一个步骤是重复相同的练习,两半互换)。因此,排除“将数据分成两半”的策略。

    • 许多机器学习和数据挖掘论文使用k 折交叉验证(没有引用),因此除非您在这一步非常小心,否则请使用它。

    • 现在,保留一个方法和其他方法,如“排除 p ”和“随机拆分和重复”(基本上是上述过程的引导程序)绝对是很好的竞争者。

    • 如果您的数据大小为 N,则 N 折交叉验证本质上与遗漏一个相同。

    • 'leave p out' 和 'bootstrap' 与 k 折交叉验证稍有不同,但区别主要在于折的定义方式和发生的重复次数“k”。

    • 正如 wiki 页面所说,k-fold 和“ leave p out ”都是“预期性能/拟合”的不错估计量(尽管关于这些估计量的方差的赌注是关闭的)。

  2. 您的情况:与特征数量(100)相比,您的样本量只有 200。我认为很有可能有多个线性模型提供相同的性能。我建议使用 > 10 次重复的 k 折交叉验证选择 3 或 5 的 ak 值。

    • k值的原因:通用选择。

    • 重复值的原因:一个相当高的重复值在这里可能很关键,因为单个 k 折交叉验证计算的输出可能容易受到我们引入的折叠分裂可变性/随机性的影响。

额外的想法:

  • 也许我还会使用“ leave p out ”和“ bootstrap like random split repeat ”方法(除了 k 折交叉验证)来进行相同的性能/拟合测量,以检查我的 k 折交叉验证方法的输出是否正常。

  • 正如有人建议的那样,尽管您想使用所有 100 个特征,但请注意多重共线性/相关性,并可能减少特征的数量。