R 分层多个列以进行交叉验证

R 分层多个列以进行交叉验证,r,partitioning,cross-validation,r-caret,R,Partitioning,Cross Validation,R Caret,我见过很多方法通过单个变量对样本进行分层,以用于交叉验证。caret包通过createFolds()函数很好地实现了这一点。默认情况下,caret将进行分区,使每个折叠具有大致相同的目标事件率 我想做的是按目标利率和时间进行分层。我发现一个函数可以部分实现这一点,它是splitstackshape包,并使用lavelized()函数。尽管该函数的问题是它返回一个样本,但在给定条件下它不会将数据分成k个组 这里有一些虚拟数据需要复制 set.seed(123) time = rep(seq(1:

我见过很多方法通过单个变量对样本进行分层,以用于交叉验证。
caret
包通过
createFolds()
函数很好地实现了这一点。默认情况下,
caret
将进行分区,使每个折叠具有大致相同的目标事件率

我想做的是按目标利率和时间进行分层。我发现一个函数可以部分实现这一点,它是
splitstackshape
包,并使用
lavelized()
函数。尽管该函数的问题是它返回一个样本,但在给定条件下它不会将数据分成k个组

这里有一些虚拟数据需要复制

set.seed(123)

time = rep(seq(1:10),100)
target = rbinom(n=100, size=1, prob=0.3)

data = as.data.frame(cbind(time,target))

table(data$time,data$target)

      0  1
  1  60 40
  2  80 20
  3  80 20
  4  60 40
  5  80 20
  6  80 20
  7  60 40
  8  60 40
  9  70 30
  10 80 20
正如您所看到的,目标事件率在不同的时间段是不同的。时间1为40%,时间2为20%,等等。我希望在创建用于交叉验证的折叠时保留这一点。如果我理解正确,插入符号将按总事件率进行划分

table(data$target)

  0   1 
710 290 
总的来说,30%的比率将保持不变,但随着时间的推移,目标事件率将不会保持不变

我们可以得到这样一个样本:

library(splitstackshape)
train.index <- stratified(data,c("target","time"),size=.2)
库(splitstackshape)

train.index我知道这篇文章很旧,但我也遇到了同样的问题,我找不到其他解决办法。如果其他人需要答案,下面是我正在实施的解决方案

library(data.table)
mystratified <- function(indt, group, NUM_FOLDS) {

  indt <- setDT(copy(indt))

  if (is.numeric(group)) 
      group <- names(indt)[group]

  temp_grp <- temp_ind <- NULL
  indt[, `:=`(temp_ind, .I)]
  indt[, `:=`(temp_grp, do.call(paste, .SD)), .SDcols = group]

  samp_sizes <- indt[, .N, by = group]
  samp_sizes[, `:=`(temp_grp, do.call(paste, .SD)), .SDcols = group]

  inds <- split(indt$temp_ind, indt$temp_grp)[samp_sizes$temp_grp]

  z = unlist(inds,use.names=F)
  model_folds <- suppressWarnings(split(z, 1:NUM_FOLDS))

}
例如,每个折叠的序列和验证数据如下:

# first fold
train = data[-myfolds[[1]],]
valid = data[myfolds[[1]],]

# second fold
train = data[-myfolds[[2]],]
valid = data[myfolds[[2]],]

# etc...
# first fold
train = data[-myfolds[[1]],]
valid = data[myfolds[[1]],]

# second fold
train = data[-myfolds[[2]],]
valid = data[myfolds[[2]],]

# etc...