R 生成交叉验证的集合

R 生成交叉验证的集合,r,R,如何使用R自动拆分矩阵进行5倍交叉验证? 实际上,我想生成5组(测试矩阵索引、训练矩阵索引)。我想您希望矩阵行成为要拆分的案例。然后您只需要示例和拆分: X <- matrix(rnorm(1000),ncol=5) id <- sample(1:5,nrow(X),replace=TRUE) ListX <- split(x,id) # gives you a list with the 5 matrices X[id==2,] # gives you the second

如何使用R自动拆分矩阵进行5倍交叉验证?
实际上,我想生成5组(测试矩阵索引、训练矩阵索引)。

我想您希望矩阵行成为要拆分的案例。然后您只需要
示例
拆分

X <- matrix(rnorm(1000),ncol=5)
id <- sample(1:5,nrow(X),replace=TRUE)
ListX <- split(x,id) # gives you a list with the 5 matrices
X[id==2,] # gives you the second matrix
给你一个测试矩阵,它的大小是训练矩阵的两倍

如果要确定案例的确切数量,
sample
prob
不是最佳选择。您可以使用以下技巧:

indices <- rep(1:5,c(100,20,20,20,40))
id <- sample(indices)

索引无拆分的解决方案:

set.seed(7402313)
X <- matrix(rnorm(999), ncol=3)
k <- 5 # number of folds

# Generating random indices 
id <- sample(rep(seq_len(k), length.out=nrow(X)))
table(id)
# 1  2  3  4  5 
# 67 67 67 66 66 

# lapply over them:
indicies <- lapply(seq_len(k), function(a) list(
    test_matrix_indices = which(id==a),
    train_matrix_indices = which(id!=a)
))
str(indicies)
# List of 5
#  $ :List of 2
#   ..$ test_matrix_indices : int [1:67] 12 13 14 17 18 20 23 28 41 45 ...
#   ..$ train_matrix_indices: int [1:266] 1 2 3 4 5 6 7 8 9 10 ...
#  $ :List of 2
#   ..$ test_matrix_indices : int [1:67] 4 19 31 36 47 53 58 67 83 89 ...
#   ..$ train_matrix_indices: int [1:266] 1 2 3 5 6 7 8 9 10 11 ...
#  $ :List of 2
#   ..$ test_matrix_indices : int [1:67] 5 8 9 30 32 35 37 56 59 60 ...
#   ..$ train_matrix_indices: int [1:266] 1 2 3 4 6 7 10 11 12 13 ...
#  $ :List of 2
#   ..$ test_matrix_indices : int [1:66] 1 2 3 6 21 24 27 29 33 34 ...
#   ..$ train_matrix_indices: int [1:267] 4 5 7 8 9 10 11 12 13 14 ...
#  $ :List of 2
#   ..$ test_matrix_indices : int [1:66] 7 10 11 15 16 22 25 26 40 42 ...
#   ..$ train_matrix_indices: int [1:267] 1 2 3 4 5 6 8 9 12 13 ...

编辑:与Wojciech的解决方案进行比较:

f_K_fold <- function(Nobs, K=5){
    id <- sample(rep(seq.int(K), length.out=Nobs))
    l <- lapply(seq.int(K), function(x) list(
         train = which(x!=id),
         test  = which(x==id)
    ))
    return(l)
}

f_K_fold
f_K_foldEdit:感谢您的回答。
我找到了以下解决方案(http://eric.univ-lyon2.fr/~ricco/tanagra/fichiers/fr\u tanagra\u Validation\u Croisee\u Suite.pdf):


下面的
n在不创建单独数据的情况下实现了这一技巧。帧/矩阵,您需要做的只是保留一个整数sequence,
id
,用于存储每个折叠的无序索引

X <- read.csv('data.csv')

k = 5 # number of folds
fold_size <-nrow(X)/k
indices <- rep(1:k,rep(fold_size,k))
id <- sample(indices, replace = FALSE) # random draws without replacement

log_models <- new.env(hash=T, parent=emptyenv()) 
for (i in 1:k){
  train <- X[id != i,]
  test <- X[id == i,]
  # run algorithm, e.g. logistic regression
  log_models[[as.character(i)]] <- glm(outcome~., family="binomial", data=train)
}

Xsperrorest
包提供了这种能力。您可以选择随机分割(
partition.cv()
),空间分割(
partition.kmeans()
),或基于因子级别的分割(
partition.factor.cv()
)。后者目前仅在版本中提供

例如:

library(sperrorest)
data(ecuador)

## non-spatial cross-validation:
resamp <- partition.cv(ecuador, nfold = 5, repetition = 1:1)

# first repetition, second fold, test set indices:
idx <- resamp[['1']][[2]]$test

# test sample used in this particular repetition and fold:
ecuador[idx , ]


然后可以使用
sperrorest()
(顺序)或
parsperrest()
(并行)执行交叉验证

+1表示拆分-我自己一直在想如何生成交叉验证矩阵,这太完美了。joris很棒的代码,谢谢。交叉验证的想法是循环所有集合,并将每个组作为测试数据至少使用一次,这不符合使用列表并像您那样命名的目的吗?@apple使用列表只是为了避免在您的工作区中生成单独的矩阵。这是为了让一切都保持在一起。交叉验证和引导有多种方法,根据不同的方法,您需要对统计数据进行不同的更正。我刚刚给出了一种方法,用一种有组织的方式创建这些矩阵。在交叉验证中,褶皱不是应该大小相等吗?根据上面的代码
table(id)
根据方法返回不同折叠的可变大小。对于较大的数据集,拥有较小的训练集和较大的评估集并不少见。这样你就能更好地模拟从无限大的人群中获得(相对)小样本的效果。请不要把答案混入你的问题中。这让人困惑。如果您想回答自己的问题,请在新的答案中回答。对于K折叠交叉验证,您必须将K-1子集合并为训练集,并将其中一个作为测试(重复K次),因此这不是您问题的完整解决方案。我已将我的答案放入“答案”部分。这是一个优雅的解决方案。谢谢。此外,这个解决方案可以通过添加set.seed(n)什么id d来确定?我不明白。类似于注意到,当nrow(X)不是k的倍数时,一些样本被丢弃。
lapply(matrices, function(x) {
     m <- build_model(x$train_matrix)
     performance(m, x$test_matrix)
})
f_K_fold <- function(Nobs, K=5){
    id <- sample(rep(seq.int(K), length.out=Nobs))
    l <- lapply(seq.int(K), function(x) list(
         train = which(x!=id),
         test  = which(x==id)
    ))
    return(l)
}
f_K_fold <- function(Nobs,K=5){
    rs <- runif(Nobs)
    id <- seq(Nobs)[order(rs)]
    k <- as.integer(Nobs*seq(1,K-1)/K)
    k <- matrix(c(0,rep(k,each=2),Nobs),ncol=2,byrow=TRUE)
    k[,1] <- k[,1]+1
    l <- lapply(seq.int(K),function(x,k,d) 
                list(train=d[!(seq(d) %in% seq(k[x,1],k[x,2]))],
                     test=d[seq(k[x,1],k[x,2])]),k=k,d=id)
   return(l)
}
n <- nrow(mydata)
K <- 5
size <- n %/% K
set.seed(5)
rdm <- runif(n)
ranked <- rank(rdm)
block <- (ranked-1) %/% size+1
block <- as.factor(block)
for (k in 1:K) {
    matrix_train<-matrix[block!=k,]
    matrix_test<-matrix[block==k,]
    [Algorithm sequence]
    }
X <- read.csv('data.csv')

k = 5 # number of folds
fold_size <-nrow(X)/k
indices <- rep(1:k,rep(fold_size,k))
id <- sample(indices, replace = FALSE) # random draws without replacement

log_models <- new.env(hash=T, parent=emptyenv()) 
for (i in 1:k){
  train <- X[id != i,]
  test <- X[id == i,]
  # run algorithm, e.g. logistic regression
  log_models[[as.character(i)]] <- glm(outcome~., family="binomial", data=train)
}
library(sperrorest)
data(ecuador)

## non-spatial cross-validation:
resamp <- partition.cv(ecuador, nfold = 5, repetition = 1:1)

# first repetition, second fold, test set indices:
idx <- resamp[['1']][[2]]$test

# test sample used in this particular repetition and fold:
ecuador[idx , ]
# this may take some time...
plot(resamp, ecuador)