R 加速数据表的子集设置和数千次回归的实现

R 加速数据表的子集设置和数千次回归的实现,r,foreach,parallel-processing,regression,R,Foreach,Parallel Processing,Regression,我有一个data.table,有100行和3列。这些行被分组为30个组。这三列是我的自变量 在每次迭代中,我从每个组中随机选取一行,并创建一个包含30行的子集 然后,我将子集连接到另一个包含因变量的数据表 有数千种可能的组合。我尝试使用foreach加速代码,如下所示。到目前为止,我已经尝试了1000次迭代,这似乎有所帮助,但由于我将不得不执行数千次以上的组合,我想知道是否有更有效或更快的方法 library(parallel) library(foreach) library(doParall

我有一个
data.table
,有100行和3列。这些行被分组为30个组。这三列是我的自变量

在每次迭代中,我从每个组中随机选取一行,并创建一个包含30行的子集

然后,我将子集连接到另一个包含因变量的
数据表

有数千种可能的组合。我尝试使用
foreach
加速代码,如下所示。到目前为止,我已经尝试了1000次迭代,这似乎有所帮助,但由于我将不得不执行数千次以上的组合,我想知道是否有更有效或更快的方法

library(parallel)
library(foreach)
library(doParallel)

#data.table containing all independent values
ids <- vector()
#my experiment results in multiple rows per group. Creating such repetitive  
#group ids was surprisingly not very straight forward 
for(i in 1:100){ids[i] <- sample(1:30,1)}
ids <- sort(ids)
x1 <- rnorm(100)
x2 <- rnorm(100)
x3 <- rnorm(100)
dd1 <- data.table(ids,x1,x2,x3)

#data.table containing all dependent values
ids <- seq(1:30)
y <- rnorm(30)
dd2 <- data.table(ids,y)

clus <- makeCluster(detectCores() - 1)
registerDoParallel(clus, cores = detectCores() - 1)


out <- foreach(i = 1:1000, .packages=c("dplyr", "data.table", "caret"), .combine='c') %dopar% {
  dd3 <- dd1[, .SD[sample(.N, min(1,.N))], by = ids]
  dd3 <- right_join(dd2, dd3, by="ids")

  model <- train(y~x1+x2+x3,
                 data = dd3,
                 method = "lm",
                 trControl = trainControl(method="LOOCV"))
  list(model$results$RMSE,
       model$results$Rsquared,
       model$results$MAE)
}
stopCluster(clus)
库(并行)
图书馆(foreach)
图书馆(双平行)
#包含所有独立值的data.table

ids如下面的基准所示,速率限制步骤是模型训练。即使data.table子集设置时间减少了87%,总体运行时间也几乎相同

library(data.table)
library(caret)
library(microbenchmark)

microbenchmark(
    a = {
        dd3 <- dd1[, .SD[sample(.N, min(1,.N))], by = ids]
        dd3 <- right_join(dd2, dd3, by="ids")
    },
    b = {
        dd3 <- dd1[sample.int(nrow(dd1))][order(ids)][!duplicated(ids)]
        dd3[, y := dd2$y]
    }, times = 10)
# Unit: microseconds
#  expr      min       lq      mean    median       uq      max neval
#     a 5151.775 5178.159 5248.1007 5214.2990 5260.367 5517.200    10
#     b  661.024  671.663  729.1066  699.2115  744.380  988.915    10

microbenchmark(
    a = {
        dd3 <- dd1[, .SD[sample(.N, min(1,.N))], by = ids]
        dd3 <- right_join(dd2, dd3, by="ids")
        model <- train(y~x1+x2+x3, data = dd3, method = "lm", trControl = trainControl(method="LOOCV"))
        list(model$results$RMSE, model$results$Rsquared, model$results$MAE)
    },
    b = {
        dd3 <- dd1[sample.int(nrow(dd1))][order(ids)][!duplicated(ids)]
        dd3[, y := dd2$y]
        model <- train(y~x1+x2+x3, data = dd3, method = "lm", trControl = trainControl(method="LOOCV"))
        list(model$results$RMSE, model$results$Rsquared, model$results$MAE)
    }, times = 10)
# Unit: milliseconds
#  expr      min       lq     mean   median       uq      max neval
#     a 450.1885 451.4723 454.9538 452.6399 459.6504 463.7085    10
#     b 445.2466 446.8068 449.4441 447.1629 450.0173 460.8545    10
库(data.table)
图书馆(插入符号)
图书馆(微基准)
微基准(
a={

dd3如下面的基准所示,速率限制步骤是模型训练。即使data.table子集设置时间减少87%,总体运行时间几乎相同

library(data.table)
library(caret)
library(microbenchmark)

microbenchmark(
    a = {
        dd3 <- dd1[, .SD[sample(.N, min(1,.N))], by = ids]
        dd3 <- right_join(dd2, dd3, by="ids")
    },
    b = {
        dd3 <- dd1[sample.int(nrow(dd1))][order(ids)][!duplicated(ids)]
        dd3[, y := dd2$y]
    }, times = 10)
# Unit: microseconds
#  expr      min       lq      mean    median       uq      max neval
#     a 5151.775 5178.159 5248.1007 5214.2990 5260.367 5517.200    10
#     b  661.024  671.663  729.1066  699.2115  744.380  988.915    10

microbenchmark(
    a = {
        dd3 <- dd1[, .SD[sample(.N, min(1,.N))], by = ids]
        dd3 <- right_join(dd2, dd3, by="ids")
        model <- train(y~x1+x2+x3, data = dd3, method = "lm", trControl = trainControl(method="LOOCV"))
        list(model$results$RMSE, model$results$Rsquared, model$results$MAE)
    },
    b = {
        dd3 <- dd1[sample.int(nrow(dd1))][order(ids)][!duplicated(ids)]
        dd3[, y := dd2$y]
        model <- train(y~x1+x2+x3, data = dd3, method = "lm", trControl = trainControl(method="LOOCV"))
        list(model$results$RMSE, model$results$Rsquared, model$results$MAE)
    }, times = 10)
# Unit: milliseconds
#  expr      min       lq     mean   median       uq      max neval
#     a 450.1885 451.4723 454.9538 452.6399 459.6504 463.7085    10
#     b 445.2466 446.8068 449.4441 447.1629 450.0173 460.8545    10
库(data.table)
图书馆(插入符号)
图书馆(微基准)
微基准(
a={

dd3使用LOOCV评估RMSE等有点过分。如果你的数据很大,这需要花费很长时间,这与使用CV有多大不同?回归中使用的数据不是很大。事实上,它非常小,只有30个观察值。此外,在我的测试中还有第四个自变量。因此,LOOCV似乎是唯一的选择。30 o观察可以从我的初始数据集中以数千种方式提取。这就是为什么我必须重复这么多次。谢谢!使用LOOCV来评估RMSE等有点过分。如果你的数据很大,这需要永远的时间,这与使用CV有多大不同?回归中使用的数据不是很大。事实上,它非常小只有30个观察值。另外,在我的测试中还有第四个自变量。因此,LOOCV似乎是唯一的选择。30个观察值可以通过数千种方式从我的初始数据集中提取。这就是为什么我必须重复这么多次的原因。谢谢!是的,我想我能做的不多。对于一些初始测试,我使用d使用
lm()
函数只是为了大致了解模型。使用
foreach
时速度非常快。但接下来,我相信我应该使用LOOCV。不过,我将合并更快的子集。谢谢!是的,我想我对此无能为力。对于一些初始测试,我使用了
lm()
函数只是为了大致了解模型。使用
foreach
时速度非常快。但接下来,我相信我应该使用LOOCV。不过,我将合并更快的子集。谢谢!