2013-12-16 3 views
30

私はk-meansクラスタリングをデータフレームdf1上で実行していますが、私は各観測の最も近いクラスタ中心を計算する簡単なアプローチを探しています新しいデータフレームdf2(同じ変数名を持つ)。 df1をトレーニングセット、df2をテストセットとみなします。トレーニングセットをクラスタリングし、各テストポイントを正しいクラスタに割り当てる必要があります。k-meansクラスタリング後の新しいデータのためのクラスタへの簡単なアプローチ

私はapply機能といくつかの簡単なユーザー定義関数(トピックに関する以前の記事は、通常と同様のものを提案している)でこれを行う方法を知っている:

df1 <- data.frame(x=runif(100), y=runif(100)) 
df2 <- data.frame(x=runif(100), y=runif(100)) 
km <- kmeans(df1, centers=3) 
closest.cluster <- function(x) { 
    cluster.dist <- apply(km$centers, 1, function(y) sqrt(sum((x-y)^2))) 
    return(which.min(cluster.dist)[1]) 
} 
clusters2 <- apply(df2, 1, closest.cluster) 

しかし、私はこのクラスタリングを準備しています学生がapply関数に慣れていないコースの例ですから、組み込み関数を使ってクラスターをdf2に割り当てることができればと思っています。最も近いクラスタを見つける便利な組み込み関数がありますか?

+1

[ここでRコードと説明と異なるクラスタリング手法を試すのに最適なリソースである](http://manuals.bioinformatics.ucr.edu/home/R_BioCondManual# TOC-Clustering-Exercises)[biganalyticsパッケージ](http://cran.r-project.org/web/packages/biganalytics/biganalytics.pdf)もあり、メモリに依存せず、K-meansアルゴリズム – marbel

+1

学生に 'apply()'を導入することは賢明です(特別な機会に覚えておかなければならないさまざまなパッケージにそれらを導入するのではなく、繰り返し使用することになります) (彼らが再びそれらを使用する場合)。 – naught101

答えて

31

あなたはK-手段のための実装predict方法があるflexclustパッケージ、使用することができますstats::kmeansまたはcluster::pamなどのクラスタ機能の結果を変換するための変換方法もあります

library("flexclust") 
data("Nclus") 

set.seed(1) 
dat <- as.data.frame(Nclus) 
ind <- sample(nrow(dat), 50) 

dat[["train"]] <- TRUE 
dat[["train"]][ind] <- FALSE 

cl1 = kcca(dat[dat[["train"]]==TRUE, 1:2], k=4, kccaFamily("kmeans")) 
cl1  
# 
# call: 
# kcca(x = dat[dat[["train"]] == TRUE, 1:2], k = 4) 
# 
# cluster sizes: 
# 
# 1 2 3 4 
#130 181 98 91 

pred_train <- predict(cl1) 
pred_test <- predict(cl1, newdata=dat[dat[["train"]]==FALSE, 1:2]) 

image(cl1) 
points(dat[dat[["train"]]==TRUE, 1:2], col=pred_train, pch=19, cex=0.3) 
points(dat[dat[["train"]]==FALSE, 1:2], col=pred_test, pch=22, bg="orange") 

flexclust plot

をクラスkccaおよびその逆のオブジェクトへ:

as.kcca(cl, data=x) 
# kcca object of family ‘kmeans’ 
# 
# call: 
# as.kcca(object = cl, data = x) 
# 
# cluster sizes: 
# 
# 1 2 
# 50 50 
7

質問のアプローチとフレックスクラウドのアプローチの両方が、どちらかというとかなり遅いということが気づいています(それぞれ2つの機能を備えた100万回の観測とテストセットでベンチマークされています)。元のモデルフィッティング

は適度に高速です:

set.seed(144) 
df1 <- data.frame(x=runif(1e6), y=runif(1e6)) 
df2 <- data.frame(x=runif(1e6), y=runif(1e6)) 
system.time(km <- kmeans(df1, centers=3)) 
# user system elapsed 
# 1.204 0.077 1.295 

それは別に各テスト・セットポイントのためclosest.clusterを呼び出すので、私は疑問に投稿されたソリューションは、テストセットクラスタの割り当てを計算するのが遅いです。

system.time(pred.test <- apply(df2, 1, closest.cluster)) 
# user system elapsed 
# 42.064 0.251 42.586 

はまた、flexclustパッケージは関係なく、我々は広報ものの(kccaで自分自身をas.kccaを装着したモデルを変換したり、新しいものに合うかどうかのオーバーヘッドの多くを追加するようです最後にedictionははるかに高速です)

# APPROACH #1: Convert from the kmeans() output 
system.time(km.flexclust <- as.kcca(km, data=df1)) 
# user system elapsed 
# 87.562 1.216 89.495 
system.time(pred.flexclust <- predict(km.flexclust, newdata=df2)) 
# user system elapsed 
# 0.182 0.065 0.250 

# Approach #2: Fit the k-means clustering model in the flexclust package 
system.time(km.flexclust2 <- kcca(df1, k=3, kccaFamily("kmeans"))) 
# user system elapsed 
# 125.193 7.182 133.519 
system.time(pred.flexclust2 <- predict(km.flexclust2, newdata=df2)) 
# user system elapsed 
# 0.198 0.084 0.302 

それは他の賢明なアプローチがここに存在しているようだ:内の各テスト・セットの観測の最近傍を見つけるために、kd木のような速いのk最近傍の溶液を用いて、クラスタ重心の集合。これは、コンパクトに書き込まれ、比較的迅速であることができる。

library(FNN) 
system.time(pred.knn <- get.knnx(km$center, df2, 1)$nn.index[,1]) 
# user system elapsed 
# 0.315 0.013 0.345 
all(pred.test == pred.knn) 
# [1] TRUE 
+1

この回答は非常に貴重です。 k-meansモデルでのpredict()の使用に伴うオーバーヘッドはちょっと狂っていました。ラスタの小さな部分を処理するのに1.5時間かかった。あなたのクラスタセンターアプローチを使用することで、私は15秒以内にプロセスを実行することができました。どうもありがとうございました。 – SeldomSeenSlim

関連する問題