拆分数据集并将子集并行传递给函数,然后重新组合结果

时间:2013-06-27 18:42:02

标签: r foreach parallel-processing random-forest na

以下是我尝试使用 foreach 包执行的操作。 我有600行和58000列的数据集,有很多缺失值。

我们需要使用名为“missForest”的包来对缺失值进行估算,其中它不是并行的,需要花费很多时间来立即运行这些数据。 所以,我想把数据分成7个数据集(我有7个核心),行数(行数)和col(标记数)不同。 然后使用%dopar%将数据集并行传递给missForest?

我没有看到如何将数据划分为更小的数据集并将这些数据集传递给missForest然后重新组合输出!

如果你能告诉我怎么样,我会非常感激吗?

这是一个小例子,表格BLR包,展示了我的问题:

   library(BLR)
   library(missForest)
   data(wheat)
   X2<- prodNA(X, 0.1)
   dim(X2)                 ## i need to divide X2 to several 7 data frames (ii)

  X3<- missForest(X2)

  X3$Ximp  ## combine ii data frames

3 个答案:

答案 0 :(得分:7)

当并行处理大型矩阵时,仅传递每个群集工作者所需的数据非常重要。在Linux上使用mclapply时直接或间接使用doParallel时,这不是问题。但在Windows上,输入数据通过套接字连接发送给集群工作者,因此非常重要。

对于这样的情况,我使用isplitCol包中的itertools函数。它在矩阵的列块上创建迭代器。使用chunks参数,您可以拆分矩阵,以便每个集群工作者只获得一个子矩阵。

以下是将您的示例转换为foreach,使用isplitCol将输入矩阵拆分为7个子矩阵,从而将发送给每个工作人员的数据与自动导出{相比减少了7倍{ {1}}每个工人:

X2

答案 1 :(得分:2)

library(multicore)

n.cores <- 7
cuts <- cut(1:ncol(X2), n.cores)
X3 <- mclapply(levels(cuts), function(x) missForest(X2[,cuts == x])$ximp , mc.cores = n.cores)
X3 <- do.call(cbind, X3)

剪切以将列分成7个间隔,然后mclapply发送到您的7个核心。最后把它们放在一起

编辑:添加我的foreach实现。注意:我之前从未使用过这个包,但似乎正在做我期望的事情

library(doParallel)
library(foreach)
n.cores <- 7
cuts <- cut(1:ncol(X2), n.cores)

cl <- makeCluster(n.cores)
registerDoParallel(cl)

X3 <- foreach(x = levels(cuts), .combine = cbind, .multicombine = TRUE) %dopar% { library(missForest); missForest(X2[, cuts == x])$ximp }

答案 2 :(得分:0)

您必须在ncores部分中拆分矩阵,然后再将它们合并。由于您使用的是随机森林,您可以随机拆分数据(并多次执行以检查并验证结果)。

ncores = 7

split = sample(seq(ncores), size=ncol(X2), replace=TRUE) # random partitioning

X3 = foreach(i=seq_len(ncores), .combine=cbind, .inorder=FALSE) %dopar% {
  ind = which(split==i) # the selected rows for this core
  X = rbind(ind, missForest(X2[,ind])$ximp) # add the index as first row!
}

ind = X3[1,] # get all the index back
ind = sort(ind, index.return=TRUE)$ix # sort the index to recover the original row order
X3 = X3[-1,ind] # remove the index