2016-11-10 27 views
1

我有一个非常大的数据集(5000 * 100),我想用kmeans函数查找集群。但是,我不知道如何使用clusterApply函数。如何在R中进行并行化k-均值?

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需要“X”,我不知道如何设置值。另外,clusterApply,和parLapply之间有什么区别?非常感谢。

+0

对不起,但它不重复。我正在使用'clusterApply'。 –

+0

你可能想尝试'lowmemtkmeans'软件包。 – Henk

回答

1

下面是使用clusterApply通过并行在nstart参数执行并行k均值的方式(假设它是大于一):

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有意义的并行k均值,因为你是手工拆分nstart,使得它发送每个群集工人只有一个任务,使parLapply不必要的。

+0

非常感谢您的回复。但是我仍然有一些关于'clusterApply'的问题。在你的代码中,'results < - clusterApply(cl,nstartv,function(n,x)kmeans(x,3,nstart = n,iter.max = 1000),mydata)''。你能解释一下吗?我很困惑你为什么写'nstartv'。 'function(n,x)'中的'n'和'x'代表什么?非常感谢 –

+0

@YangYang集群应用程序与lapply基本相同,区别在于指定了一个集群对象作为第一个参数。在这种情况下,clusterApply会调用我的匿名工作函数'nw'次(因为'nstartv'的长度是'nw')。 worker函数的两个参数是来自'nstartv'(作为参数'n')和'mydata'矩阵(作为参数'x')的值。如果这是令人困惑的,我建议你试试lapply。 –

+0

非常感谢! –