2014-01-27 306 views
9

我正在尝试为之前在R中构建的一些glm模型做一个10倍交叉验证。我对boot包中的cv.glm()函数有点困惑,尽管我读过很多帮助文件。当我提供以下公式:glm()模型的交叉验证

library(boot) 
cv.glm(data, glmfit, K=10) 

是否“数据”的说法在这里指的是整个数据集或仅对测试集?

到目前为止,我所看到的例子提供了“数据”参数作为测试集,但这并没有什么意义,比如为什么在同一个测试集上做10倍?他们都会给出完全相同的结果(我认为!)。

不幸?cv.glm解释了它在一个有雾的方式:

数据:一个矩阵或包含该数据的数据帧。该行应 案件列对应于变量,其中一个是 响应

我的另一个问题是关于$delta[1]结果。这是10次试验的平均预测误差吗?如果我想要得到每次折叠的错误怎么办?

这里是我的脚本如下:

##data partitioning 
sub <- sample(nrow(data), floor(nrow(x) * 0.9)) 
training <- data[sub, ] 
testing <- data[-sub, ] 

##model building 
model <- glm(formula = groupcol ~ var1 + var2 + var3, 
     family = "binomial", data = training) 

##cross-validation 
cv.glm(testing, model, K=10) 
+0

看看'启动::: CV的例子部分。 glm'。你应该输入整个数据,模型和CV的折叠。 –

+0

感谢您的回复@RomanLuštrik。听起来很棒。尽管如此,我仍然想知道一些事情。此功能是否使用交叉验证中提供的所有数据?假设我为'cv.glm(data,glm,K = 10)'提供了一个1000行的数据框,它是否为数据创建了10个分区,每个数据分区是100,并进行交叉验证?对不起,我已经通过了?cv。glm但我没有在那里找到。 – Error404

+1

如果你要做2倍的CV,这个函数将占用50%的数据并且适合模型。它会使用另外50%的数据来查看模型如何描述数据。或者,在一次性的简历中,除了一个数据“点”之外,它将适用于所有模型,并且看看单个“点”做得如何。重复N次,你会得到你的结果。 –

回答

11

我总是有点谨慎使用各种包10倍交叉验证方法。我有我自己的简单的脚本来手动创建测试和训练分区的任何机器学习包:

#Randomly shuffle the data 
yourData<-yourData[sample(nrow(yourData)),] 

#Create 10 equally size folds 
folds <- cut(seq(1,nrow(yourData)),breaks=10,labels=FALSE) 

#Perform 10 fold cross validation 
for(i in 1:10){ 
    #Segement your data by fold using the which() function 
    testIndexes <- which(folds==i,arr.ind=TRUE) 
    testData <- yourData[testIndexes, ] 
    trainData <- yourData[-testIndexes, ] 
    #Use test and train data partitions however you desire... 
} 
+1

谢谢杰克德鲁。为了测试目的,我将上面的代码与cv.glm的结果进行了比较,结果相同。感谢您的文章,我现在可以信任cv.glm ;-) – citraL

+0

很高兴为您提供帮助! –

5

@Roman提供了他的评论的一些答案,但回答你的问题,通过与检查码提供cv.glm

我相信这段代码会将数据建立随机进入K-褶皱,安排如果K文件不是n分四舍五入为必要的:

if ((K > n) || (K <= 1)) 
    stop("'K' outside allowable range") 
K.o <- K 
K <- round(K) 
kvals <- unique(round(n/(1L:floor(n/2)))) 
temp <- abs(kvals - K) 
if (!any(temp == 0)) 
    K <- kvals[temp == min(temp)][1L] 
if (K != K.o) 
    warning(gettextf("'K' has been set to %f", K), domain = NA) 
f <- ceiling(n/K) 
s <- sample0(rep(1L:K, f), n) 

这里该位表明delta值不是根均方误差。正如帮助文件所示,The default is the average squared error function.这是什么意思?我们可以通过检查函数声明看到这一点:

function (data, glmfit, cost = function(y, yhat) mean((y - yhat)^2), 
    K = n) 

这表明一个折内,我们计算错误的平均平方,其中错误是在预测的响应与实际响应之间的通常意义。

delta[1]简直就是所有这些条款每个折叠的总和的weighted average,看到的cv.glm代码我的内联注释:

for (i in seq_len(ms)) { 
    j.out <- seq_len(n)[(s == i)] 
    j.in <- seq_len(n)[(s != i)] 
    Call$data <- data[j.in, , drop = FALSE] 
    d.glm <- eval.parent(Call) 
    p.alpha <- n.s[i]/n #create weighted average for later 
    cost.i <- cost(glm.y[j.out], predict(d.glm, data[j.out, 
     , drop = FALSE], type = "response")) 
    CV <- CV + p.alpha * cost.i # add weighted average error to running total 
    cost.0 <- cost.0 - p.alpha * cost(glm.y, predict(d.glm, 
     data, type = "response")) 
}