R中的K折交叉验证

K fold cross validation in R

据我所知,k折交叉验证是将训练数据集划分为k个相等的子集,每个子​​集都是不同的。下面附上来自 R-bloggers 的用于 k 折验证的 R 代码。该数据有 506 个 obs。和 14 个变量。根据代码,他们使用了 10 折。 我的问题是,如果每个折叠都有不同的子集或每个折叠中有一些重复的数据点。我想确保在不重复的情况下测试每个数据点,所以我的目标是让每个fold 有不同的数据点。

set.seed(450)
cv.error <- NULL
k <- 10

library(plyr) 
pbar <- create_progress_bar('text')
pbar$init(k)

for(i in 1:k){
index <- sample(1:nrow(data),round(0.9*nrow(data)))
train.cv <- scaled[index,]
test.cv <- scaled[-index,]

nn <- neuralnet(f,data=train.cv,hidden=c(5,2),linear.output=T)

pr.nn <- compute(nn,test.cv[,1:13])
pr.nn <- pr.nn$net.result*(max(data$medv)-min(data$medv))+min(data$medv)

test.cv.r <- (test.cv$medv)*(max(data$medv)-min(data$medv))+min(data$medv)

cv.error[i] <- sum((test.cv.r - pr.nn)^2)/nrow(test.cv)

pbar$step()
}

您可以从循环外部随机播放整个群体。 以下代码可能会给您解决问题的思路。

set.seed(450)
cv.error <- NULL
k <- 10

library(plyr) 
pbar <- create_progress_bar('text')
pbar$init(k)

total_index<-sample(1:nrows(data),nrows(data)) 
    ## shuffle the whole index of samples

for(i in 1:k){
index<-total_index[(i*(k-1)+1):(i*(k-1)+k)] 
    ## pick the k samples from (i*(k-1)+1) to (i*(k-1)+k).
    ## so you can avoid of picking overlapping data point in other validation set
train.cv <- scaled[-index,] ## pick the samples not in the index(-validation)
test.cv <- scaled[index,]  ## pick the k samples for validation.

nn <- neuralnet(f,data=train.cv,hidden=c(5,2),linear.output=T)

pr.nn <- compute(nn,test.cv[,1:13])
pr.nn <- pr.nn$net.result*(max(data$medv)-min(data$medv))+min(data$medv)

test.cv.r <- (test.cv$medv)*(max(data$medv)-min(data$medv))+min(data$medv)

cv.error[i] <- sum((test.cv.r - pr.nn)^2)/nrow(test.cv)

pbar$step()
}

那不是K-fold交叉验证;每一次折叠,都会选择一个新的随机样本,而不是将样本预先分配到 K 次折叠中,然后循环遍历,依次将每次折叠分配给测试集。

set.seed(450)
cv.error <- NULL
k <- 10

library(plyr) 
pbar <- create_progress_bar('text')
pbar$init(k)

## Assign samples to K folds initially
index <- sample(letters[seq_len(k)], nrow(data), replace=TRUE)
for(i in seq_len(k)) {
    ## Make all samples assigned current letter the test set
    test_ind <- index == letters[[k]]
    test.cv <- scaled[test_ind, ]
    ## All other samples are assigned to the training set
    train.cv <- scaled[!test_ind, ]

    ## It is bad practice to use T instead of TRUE, 
    ## since T is not a reserved variable, and can be overwritten
    nn <- neuralnet(f,data=train.cv,hidden=c(5,2),linear.output=TRUE)

    pr.nn <- compute(nn,test.cv[,1:13])
    pr.nn <- pr.nn$net.result*(max(data$medv)-min(data$medv))+min(data$medv)

    test.cv.r <- (test.cv$medv) * (max(data$medv) - min(data$medv)) + min(data$medv)

    cv.error[i] <- sum((test.cv.r - pr.nn) ^ 2) / nrow(test.cv)

    pbar$step()
}

然后,为了产生方差较小的误差估计,我会多次重复这个过程,并可视化 cross-validation 误差在重复测定中的分布。我认为你最好使用一个为你完成这样的任务的包,比如优秀的 caret.