以下是我尝试使用 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
答案 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