2016-11-10 4 views
1

私は非常に大きなデータセット(5000 * 100)を持っており、クラスタを見つけるのにkmeans関数を使いたいと思います。しかし、私はclusterApply関数の使い方を知らない。Rの並列化k-meansのやり方は?

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,parSapplyparLapplyの違いは何ですか?どうもありがとう。ここで

+0

申し訳ありませんが重複していません。私は 'clusterApply'を使用しています。 –

+0

'lowmemtkmeans'パッケージを試してみてください。 – Henk

答えて

1

は(それが1以上であると仮定した場合)nstart引数上で並列化して並列関数kmeansを実行するためにclusterApplyを使用する方法です:

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は別タスクでxの各値を処理lapplyの並列バージョンです。 parLapplylapplyの並列バージョンで、xを分割して、クラスタワーカー1つにつき1つのタスクしか送信しないようにしています(より効率的です)。 parSapplyparLapplyを呼び出しますが、sapplylapplyを呼び出す結果を単純化するのと同じ方法で結果を単純化します。

clusterApplyは、クラスタワーカー1人につき1つのタスクしか送信しないように手作業で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 clusterApplyは、最初の引数としてクラスタオブジェクトが指定されている以外は、lapplyと基本的に同じです。この場合、clusterApplyは、(nstartvの長さは 'nw'なので)私の匿名ワーカー関数' nw'を呼び出します。 worker関数の2つの引数は、 'nstartv'(引数' n')と 'mydata'行列(引数' x')の値です。これが混乱している場合は、lapplyを試してみることをお勧めします。 –

+0

ありがとうございました! –

関連する問題