为K-fold交叉验证R手动创建折叠



我正在尝试使用K=5制作K-fold CV回归模型。我尝试使用"启动"包cv。glm函数,但是我的电脑内存不足,因为引导包总是在它旁边计算一个LOOCV MSE。所以我决定手工做,但我遇到了下面的问题。我试图将我的数据帧分成5个相同长度的向量,其中包含我df的行数的1/5的样本,但我从第三次折叠中得到无法解释的长度。

a <- sample((d<-1:1000), size = 100, replace = FALSE)
b <- sample((d<-1:1000), size = 100, replace = FALSE)
c <- sample((d<-1:1000), size = 100, replace = FALSE)
df <- data.frame(a,b,c)
head(df)
# create first fold (correct: n=20)
set.seed(5)
K1row <- sample(x = nrow(df), size = (nrow(df)/5), replace = FALSE, prob = NULL)
str(K1row) # int [1:20] 21 68 90 28 11 67 50 76 88 96 ...
# create second fold (still going strong: n=20)
set.seed(5)
K2row <- sample(x = nrow(df[-K1row,]), size = ((nrow(df[-K1row,]))/4), replace = FALSE, prob = NULL)
str(K2row) # int [1:20] 17 55 72 22 8 53 40 59 69 76 ...
# create third fold (this is where it goes wrong: n=21)
set.seed(5)
K3row <- sample(x = nrow(df[-c(K1row,K2row),]), size = ((nrow(df[-c(K1row,K2row),]))/3), replace = FALSE, prob = NULL)
str(K3row) # int [1:21] 13 44 57 18 7 42 31 47 54 60 ...
# create fourth fold (and it gets worse: n=26)
set.seed(5)
K4row <- sample(x = nrow(df[-c(K1row,K2row,K3row),]), size = ((nrow(df[-c(K1row,K2row,K3row),]))/2), replace = FALSE, prob = NULL)
str(K4row) # int [1:26] 11 35 46 14 6 33 25 37 43 5 ...

向量长度似乎从K=3开始增加。谁能告诉我我做错了什么吗!我的代码(和推理)看起来合乎逻辑,但结果却不是这样。提前感谢!

这是因为K1row和K2row有一些共同的元素。你可以有效地进行替换抽样。下面的方法使用模来平均分割行。

set.seed(5)
rand <- sample(nrow(df))
K1row <- rand[rand %% 5 + 1 == 1]
K2row <- rand[rand %% 5 + 1 == 2]
K3row <- rand[rand %% 5 + 1 == 3]
K4row <- rand[rand %% 5 + 1 == 4]
K5row <- rand[rand %% 5 + 1 == 5]

最新更新