2014-01-27 188 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")) 
}