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


36

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

以下数据只是解决问题的一个示例(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. 一次屏蔽一个值或几个值:在这种方法中,我们通过用NA替换数据集(y)中的一个值来对其进行随机屏蔽,并对其进行预测。该过程重复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?工作示例将不胜感激。


您是否有兴趣检查数据的有效性或验证b系数的预测估计值或值。
Subhash C. Davar 2014年

我有兴趣验证b系数的预测估计或值
rdorlearn 2014年

我在方法1上遇到的问题是样本大小比实际情况小得多。因此,估计的置信带/可变性可能会更大。另外,我猜方法2和方法3的性能相似。如果我是您,请从K = 5,6,...,14,15的K倍交叉验证开始,然后看看您的结果是否非常相似。
2014年

另外,您打算进行模型选择以减少协变量的数量吗?100似乎很多。
2014年

@ user2432701不,我想用所有的100
rdorlearn

Answers:


34

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

一,名字:

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

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

有许多交叉验证技术:

b)坚持是上面的方法1。将集合分为训练和一项测试。关于培训和测试集的相对大小的讨论和实践已有很长的历史。

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

d)留一法–上面的方法3。

e)引导程序:如果您的集合具有N个数据,请从集合中随机选择N个具有可替换性的样本并将其用作训练。来自原始集合的任何时候都没有被采样的数据被用作测试集合。有多种计算模型误差的最终估计的方法,该方法同时使用测试集的误差(样本外)和火车集的误差(样本内)。例如,请参阅.632引导程序。我认为还有一个.632+公式–它们是使用样本外和样本内误差来估计模型真实误差的公式。

f)与上述方法的选择正交的是重复问题。除了留一法,上述所有方法都可以重复多次。实际上,可以谈论REPEATED保留或REPEATED k倍。公平地说,引导程序方法几乎总是重复使用。


下一个问题是,哪种方法“更好”。问题是“更好”的含义。

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

2)第二种选择是这些方法收敛到真实模型误差的速度或程度(如果没有偏差)。我相信这仍然是研究的主题。让我指出这两篇论文(位于“付费壁”的后面),但摘要使我们对它们试图实现的目标有了一些理解。还要注意,将k折叠本身称为“交叉验证” 是很常见的。

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

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

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

在这里事情变得有些复杂。据我从论文中了解到的那样,没有k倍交叉验证方差的无偏估计(也不在付费墙后面),人们不能相信从k倍得到的方差–因此,人们不能从k构筑良好的置信区间-褶皱。同样从我从论文中了解到的比较监督分类学习算法的近似统计测试(不位于付费墙后面),使用重复测量的技术(重复k倍的重复保留(不确定引导程序)会估计误差测度的真实方差(很容易看到这一点),因为如果从有限集采样,则重复非常大的量多次,相同的值将不断重复,这将保持均值不变,但会减少方差)。因此,重复测量技术将对置信区间过于乐观。

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

编辑:

当然,在“交叉验证”中对于这些问题中的一些问题有很好的答案(尽管有时它们彼此之间并不一致)。这里有一些:

交叉验证或自举以评估分类性能?

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

交叉验证或自举以评估分类性能?

了解引导进行验证和模型选择

通常,标签是您的朋友。


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


至于交叉验证的复杂方差属性,我认为需要注意要测量的方差。IIRC,Bengio 等。针对手头问题的大小为n 数据集关注方差。在我手头数据集上训练的模型的预测中,与随机不确定性不同(更大)。另请参见上面链接的Dietterich论文中的问题分类法。
cbeleites支持Monica

7

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

浏览完该页面后,以下内容可能会对您有所帮助。让我集中讨论问题的一部分,在该部分中,人们希望从其建模过程中选择一种方法。由于这是一个人经常做出的选择,并且他们可以从其他知识中受益,所以这是我针对两种情况的答案:

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

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

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

    • 现在,留一法和其他方法,例如“ 留出p ”和“ 随机拆分并重复 ”(本质上是上述的自举,就像上述过程一样)是绝对好的竞争者。

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

    • 'leave p out'和'bootstrap'与k折交叉验证略有不同,但是本质上的区别在于折痕的定义方式和重复次数'k'。

    • 就像Wiki页面上所说的那样,k折和' 离开p '都是' 预期表现/拟合度 '的恰当估算器(尽管在这些估算器的方差上押注了)。

  2. 您的情况:与特征数量(100)相比,样本大小仅为200。我认为存在多个线性模型给出相同性能的可能性很高。我建议对大于10个重复使用k倍交叉验证。选择ak值3或5。

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

    • 重复值的原因:在这里,较高的重复值可能很关键,因为单个k倍交叉验证计算的输出可能会受到我们引入的倍数拆分变异性/随机性的影响。

其他想法:

  • 也许我还会采用“ leave p out ”和“ bootstrap像随机拆分重复 ”方法(除了进行k折交叉验证外)进行相同的性能/拟合度测试,以检查我的k折交叉验证方法的输出是否正常。

  • 尽管您想使用所有100个功能,但有人建议,但要注意多重共线性/相关性,并可能减少功能数量。



我会简单介绍一下,直接转到R rms软件包validatecalibrate函数中实现的Efron-Gong乐观引导。
弗兰克·哈雷尔
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.