这是我尝试使用 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
最佳答案
在并行处理大型矩阵时,仅传递每个集群工作人员所需的尽可能多的数据非常重要。在Linux上使用mclapply
时,无论直接还是间接使用doParallel
,这都不是问题。但是在Windows上,输入数据是通过套接字连接发送到群集工作程序的,因此它非常重要。
对于这种情况,我使用isplitCol
包中的itertools
函数。它在矩阵的列块上创建迭代器。使用chunks
参数,您可以拆分矩阵,以便每个集群工作者都可以恰好获得一个子矩阵。
这是您的示例到foreach
的翻译,它使用isplitCol
将输入矩阵拆分为7个子矩阵,因此与自动将X2
自动导出到每个工作者相比,发送给每个工作者的数据减少了七倍:
library(doParallel)
library(itertools)
library(BLR)
library(missForest)
ncores <- 7
cl <- makePSOCKcluster(ncores)
registerDoParallel(cl)
data(wheat)
X2 <- prodNA(X, 0.1)
X3 <- foreach(m=isplitCols(X2, chunks=ncores), .combine='cbind',
.packages='missForest') %dopar% {
missForest(m)$ximp
}
print(X3)
stopCluster(cl)