2016-11-10 55 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

非常感謝! –