如何在R中并行化k-means?

时间:2016-11-10 22:45:03

标签: r parallel-processing k-means

我有一个非常大的数据集(5000 * 100),我想使用kmeans函数来查找集群。但是,我不知道如何使用clusterApply函数。

set.seed(88)
mydata=rnorm(5000*100)
mydata=matrix(data=mydata,nrow = 5000,ncol = 100)

parallel.a=function(i) {
kmeans(mydata,3,nstart = i,iter.max = 1000)
} 

library(parallel)
cl.cores <- detectCores()-1
cl <- makeCluster(cl.cores)
clusterSetRNGStream(cl,iseed=1234)
fit.km = clusterApply(cl,x,fun=parallel.a(500))
stopCluster(cl)

clusterApply要求&#39; x&#39;我不知道如何设置的价值。另外,clusterApplyparSapplyparLapply之间有什么区别?非常感谢。

1 个答案:

答案 0 :(得分:1)

这是一种使用clusterApply通过并行化nstart参数来执行并​​行kmeans的方法(假设它大于1):

library(parallel)
nw <- detectCores()
cl <- makeCluster(nw)
clusterSetRNGStream(cl, iseed=1234)
set.seed(88)
mydata <- matrix(rnorm(5000 * 100), nrow=5000, ncol=100)

# Parallelize over the "nstart" argument
nstart <- 100
# Create vector of length "nw" where sum(nstartv) == nstart
nstartv <- rep(ceiling(nstart / nw), nw)
results <- clusterApply(cl, nstartv,
        function(n, x) kmeans(x, 3, nstart=n, iter.max=1000),
        mydata)
# Pick the best result
i <- sapply(results, function(result) result$tot.withinss)
result <- results[[which.min(i)]]
print(result$tot.withinss)

人们通常会将mydata导出给工作人员,但此示例将其作为clusterApply的附加参数传递给工作人员。这是有意义的(因为任务的数量等于工作者的数量),稍微更高效(因为它有效地将导出与计算结合起来),并且避免在集群工作者上创建全局变量(这更多一点)整洁)。 (当然,如果您计划对具有该数据集的工作人员执行更多计算,则导出更有意义。)

请注意,如果您愿意,可以使用detectCores()-1工作人员,但在我的计算机上进行基准测试表明,detectCores()工作人员的执行速度要快得多。我建议你在你的机器上对它进行基准测试,看看什么对你有用。

至于不同并行函数之间的差异,clusterApplylapply的并行版本,它在单独的任务中处理x的每个值。 parLapplylapply的并行版本,它将x拆分,以便每个群集工作者只发送一个任务(效率更高)。 parSapply调用了parLapply,但以sapply简化调用lapply的结果的方式简化了结果。

clusterApply对于并行kmeans是有意义的,因为您手动拆分nstart,使得每个群集工作程序只发送一个任务,从而不需要parLapply