我有一个非常大的数据集(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;我不知道如何设置的价值。另外,clusterApply
,parSapply
和parLapply
之间有什么区别?非常感谢。
答案 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()
工作人员的执行速度要快得多。我建议你在你的机器上对它进行基准测试,看看什么对你有用。
至于不同并行函数之间的差异,clusterApply
是lapply
的并行版本,它在单独的任务中处理x
的每个值。 parLapply
是lapply
的并行版本,它将x
拆分,以便每个群集工作者只发送一个任务(效率更高)。 parSapply
调用了parLapply
,但以sapply
简化调用lapply
的结果的方式简化了结果。
clusterApply
对于并行kmeans是有意义的,因为您手动拆分nstart
,使得每个群集工作程序只发送一个任务,从而不需要parLapply
。