web-dev-qa-db-de.com

Clusteranalyse in R: Bestimmen Sie die optimale Anzahl von Clustern

Da ich ein Neuling in R bin, bin ich mir nicht sicher, wie ich die beste Anzahl von Clustern für eine k-means-Analyse auswählen soll. Wie viele Cluster eignen sich nach dem Plotten einer Teilmenge der folgenden Daten? Wie kann ich eine Cluster-Dendro-Analyse durchführen?

n = 1000
kk = 10    
x1 = runif(kk)
y1 = runif(kk)
z1 = runif(kk)    
x4 = sample(x1,length(x1))
y4 = sample(y1,length(y1)) 
randObs <- function()
{
  ix = sample( 1:length(x4), 1 )
  iy = sample( 1:length(y4), 1 )
  rx = rnorm( 1, x4[ix], runif(1)/8 )
  ry = rnorm( 1, y4[ix], runif(1)/8 )
  return( c(rx,ry) )
}  
x = c()
y = c()
for ( k in 1:n )
{
  rPair  =  randObs()
  x  =  c( x, rPair[1] )
  y  =  c( y, rPair[2] )
}
z <- rnorm(n)
d <- data.frame( x, y, z )
414
user2153893

Wenn Ihre Frage how can I determine how many clusters are appropriate for a kmeans analysis of my data? ist, dann sind hier einige Optionen. Der Wikipedia-Artikel zur Bestimmung der Anzahl von Clustern bietet einen guten Überblick über einige dieser Methoden.

Erstens einige reproduzierbare Daten (die Daten im Q sind mir ... unklar):

n = 100
g = 6 
set.seed(g)
d <- data.frame(x = unlist(lapply(1:g, function(i) rnorm(n/g, runif(1)*i^2))), 
                y = unlist(lapply(1:g, function(i) rnorm(n/g, runif(1)*i^2))))
plot(d)

enter image description here

Eins . Suchen Sie nach einer Biegung oder einem Ellbogen in der Summe der quadratischen Fehler (SSE). Weitere Informationen finden Sie unter http://www.statmethods.net/advstats/cluster.html & http://www.mattpeeples.net/kmeans.html . Die Position des Ellbogens in der resultierenden Darstellung legt eine geeignete Anzahl von Clustern für die Kilometer nahe:

mydata <- d
wss <- (nrow(mydata)-1)*sum(apply(mydata,2,var))
  for (i in 2:15) wss[i] <- sum(kmeans(mydata,
                                       centers=i)$withinss)
plot(1:15, wss, type="b", xlab="Number of Clusters",
     ylab="Within groups sum of squares")

Wir könnten daraus schließen, dass 4 Cluster durch diese Methode angezeigt werden: enter image description here

Zwei . Sie können Medoids partitionieren, um die Anzahl der Cluster mithilfe der Funktion pamk im fpc-Paket zu schätzen.

library(fpc)
pamk.best <- pamk(d)
cat("number of clusters estimated by optimum average silhouette width:", pamk.best$nc, "\n")
plot(pam(d, pamk.best$nc))

enter image description hereenter image description here

# we could also do:
library(fpc)
asw <- numeric(20)
for (k in 2:20)
  asw[[k]] <- pam(d, k) $ silinfo $ avg.width
k.best <- which.max(asw)
cat("silhouette-optimal number of clusters:", k.best, "\n")
# still 4

Drei . Calinsky-Kriterium: Ein weiterer Ansatz zur Diagnose, wie viele Cluster zu den Daten passen. In diesem Fall versuchen wir 1 bis 10 Gruppen.

require(vegan)
fit <- cascadeKM(scale(d, center = TRUE,  scale = TRUE), 1, 10, iter = 1000)
plot(fit, sortg = TRUE, grpmts.plot = TRUE)
calinski.best <- as.numeric(which.max(fit$results[2,]))
cat("Calinski criterion optimal number of clusters:", calinski.best, "\n")
# 5 clusters!

enter image description here

Vier . Bestimmen Sie das optimale Modell und die Anzahl der Cluster gemäß dem Bayes'schen Informationskriterium für die Erwartungsmaximierung, das durch hierarchisches Clustering für parametrisierte Gauß'sche Mischungsmodelle initialisiert wird

# See http://www.jstatsoft.org/v18/i06/paper
# http://www.stat.washington.edu/research/reports/2006/tr504.pdf
#
library(mclust)
# Run the function to see how many clusters
# it finds to be optimal, set it to search for
# at least 1 model and up 20.
d_clust <- Mclust(as.matrix(d), G=1:20)
m.best <- dim(d_clust$z)[2]
cat("model-based optimal number of clusters:", m.best, "\n")
# 4 clusters
plot(d_clust)

enter image description hereenter image description hereenter image description here

Fünf . Clustering der Affinitätsausbreitung (AP), siehe http://dx.doi.org/10.1126/science.11368

library(apcluster)
d.apclus <- apcluster(negDistMat(r=2), d)
cat("affinity propogation optimal number of clusters:", length([email protected]), "\n")
# 4
heatmap(d.apclus)
plot(d.apclus, d)

enter image description hereenter image description here

Sechs . Lückenstatistik zur Schätzung der Anzahl der Cluster. Siehe auch Code für eine nette grafische Ausgabe . Hier werden 2-10 Cluster ausprobiert:

library(cluster)
clusGap(d, kmeans, 10, B = 100, verbose = interactive())

Clustering k = 1,2,..., K.max (= 10): .. done
Bootstrapping, b = 1,2,..., B (= 100)  [one "." per sample]:
.................................................. 50 
.................................................. 100 
Clustering Gap statistic ["clusGap"].
B=100 simulated reference sets, k = 1..10
 --> Number of clusters (method 'firstSEmax', SE.factor=1): 4
          logW   E.logW        gap     SE.sim
 [1,] 5.991701 5.970454 -0.0212471 0.04388506
 [2,] 5.152666 5.367256  0.2145907 0.04057451
 [3,] 4.557779 5.069601  0.5118225 0.03215540
 [4,] 3.928959 4.880453  0.9514943 0.04630399
 [5,] 3.789319 4.766903  0.9775842 0.04826191
 [6,] 3.747539 4.670100  0.9225607 0.03898850
 [7,] 3.582373 4.590136  1.0077628 0.04892236
 [8,] 3.528791 4.509247  0.9804556 0.04701930
 [9,] 3.442481 4.433200  0.9907197 0.04935647
[10,] 3.445291 4.369232  0.9239414 0.05055486

Hier ist die Ausgabe von Edwin Chens Implementierung der Lückenstatistik: enter image description here

Sieben . Es kann auch nützlich sein, Ihre Daten mit Clustergrammen zu untersuchen, um die Clusterzuordnung zu visualisieren. Siehe http://www.r-statistics.com/2010/06/clustergram-visualization-and-diagnostics-for-cluster-). Analyse-r-Code / für weitere Details.

Acht . Das NbClust-Paket liefert 30 Indizes, um die Anzahl der Cluster in einem Dataset zu bestimmen.

library(NbClust)
nb <- NbClust(d, diss="NULL", distance = "euclidean", 
        min.nc=2, max.nc=15, method = "kmeans", 
        index = "alllong", alphaBeale = 0.1)
hist(nb$Best.nc[1,], breaks = max(na.omit(nb$Best.nc[1,])))
# Looks like 3 is the most frequently determined number of clusters
# and curiously, four clusters is not in the output at all!

enter image description here

Wenn Ihre Frage how can I produce a dendrogram to visualize the results of my cluster analysis ist, sollten Sie mit diesen beginnen: http://www.statmethods.net/advstats/cluster.htmlhttp: //www.r -tutor.com/gpu-computing/clustering/hierarchical-cluster-analysishttp://gastonsanchez.wordpress.com/2012/10/03/7-ways-to-plot-dendrograms-in -r / Und hier finden Sie weitere exotische Methoden: http://cran.r-project.org/web/views/Cluster.html

Hier einige Beispiele:

d_dist <- dist(as.matrix(d))   # find distance matrix 
plot(hclust(d_dist))           # apply hirarchical clustering and plot

enter image description here

# a Bayesian clustering method, good for high-dimension data, more details:
# http://vahid.probstat.ca/paper/2012-bclust.pdf
install.packages("bclust")
library(bclust)
x <- as.matrix(d)
d.bclus <- bclust(x, transformed.par = c(0, -50, log(16), 0, 0, 0))
viplot(imp(d.bclus)$var); plot(d.bclus); ditplot(d.bclus)
dptplot(d.bclus, scale = 20, horizbar.plot = TRUE,varimp = imp(d.bclus)$var, horizbar.distance = 0, dendrogram.lwd = 2)
# I just include the dendrogram here

enter image description here

Für hochdimensionale Daten steht auch die Bibliothek pvclust zur Verfügung, die p-Werte für hierarchisches Clustering über Multiskalen-Resampling bootstrap berechnet. Hier ist das Beispiel aus der Dokumentation (funktioniert nicht mit so geringen Maßangaben wie in meinem Beispiel):

library(pvclust)
library(MASS)
data(Boston)
boston.pv <- pvclust(Boston)
plot(boston.pv)

enter image description here

Hilft irgendetwas davon?

1004
Ben

Es ist schwer, etwas zu einer solch durchdachten Antwort hinzuzufügen. Obwohl ich der Meinung bin, dass wir hier identify erwähnen sollten, insbesondere weil @Ben viele Dendrogrammbeispiele zeigt.

d_dist <- dist(as.matrix(d))   # find distance matrix 
plot(hclust(d_dist)) 
clusters <- identify(hclust(d_dist))

Mit identify können Sie interaktiv Cluster aus einem Dendrogramm auswählen und Ihre Auswahl in einer Liste speichern. Drücken Sie die Esc-Taste, um den interaktiven Modus zu verlassen und zur R-Konsole zurückzukehren. Beachten Sie, dass die Liste die Indizes und nicht die Rownamen enthält (im Gegensatz zu cutree).

19
Matt Bannert

Zur Bestimmung des optimalen k-Clusters in Clustering-Methoden. Normalerweise verwende ich die Elbow -Methode zusammen mit der parallelen Verarbeitung, um Zeit zu sparen. Dieser Code kann beispielsweise so aussehen:

Ellbogenmethode

elbow.k <- function(mydata){
dist.obj <- dist(mydata)
hclust.obj <- hclust(dist.obj)
css.obj <- css.hclust(dist.obj,hclust.obj)
elbow.obj <- elbow.batch(css.obj)
k <- elbow.obj$k
return(k)
}

Laufender Ellbogen parallel

no_cores <- detectCores()
    cl<-makeCluster(no_cores)
    clusterEvalQ(cl, library(GMD))
    clusterExport(cl, list("data.clustering", "data.convert", "elbow.k", "clustering.kmeans"))
 start.time <- Sys.time()
 elbow.k.handle(data.clustering))
 k.clusters <- parSapply(cl, 1, function(x) elbow.k(data.clustering))
    end.time <- Sys.time()
    cat('Time to find k using Elbow method is',(end.time - start.time),'seconds with k value:', k.clusters)

Es funktioniert gut.

9
VanThaoNguyen

Diese Methoden sind großartig, aber wenn Sie versuchen, k für viel größere Datensätze zu finden, können diese in R verrückt langsam sein.

Eine gute Lösung, die ich gefunden habe, ist das "RWeka" -Paket, das eine effiziente Implementierung des X-Means-Algorithmus enthält - eine erweiterte Version von K-Means, die besser skaliert und die optimale Anzahl von Clustern für Sie bestimmt.

Zuerst möchten Sie sicherstellen, dass Weka auf Ihrem System installiert ist und XMeans über das Paketmanager-Tool von Weka installiert wurde.

library(RWeka)

# Print a list of available options for the X-Means algorithm
WOW("XMeans")

# Create a Weka_control object which will specify our parameters
weka_ctrl <- Weka_control(
    I = 1000,                          # max no. of overall iterations
    M = 1000,                          # max no. of iterations in the kMeans loop
    L = 20,                            # min no. of clusters
    H = 150,                           # max no. of clusters
    D = "weka.core.EuclideanDistance", # distance metric Euclidean
    C = 0.4,                           # cutoff factor ???
    S = 12                             # random number seed (for reproducibility)
)

# Run the algorithm on your data, d
x_means <- XMeans(d, control = weka_ctrl)

# Assign cluster IDs to original data set
d$xmeans.cluster <- x_means$class_ids
5
RDRR

Herrliche Antwort von Ben. Ich bin jedoch überrascht, dass hier die Affinity Propagation (AP) -Methode vorgeschlagen wurde, um nur die Anzahl der Cluster für die k-means-Methode zu ermitteln, bei der AP die Daten im Allgemeinen besser gruppiert. Das wissenschaftliche Dokument, das diese Methode unterstützt, finden Sie hier in Science:

Frey, Brendan J. und Delbert Dueck. "Clustering durch Weiterleiten von Nachrichten zwischen Datenpunkten." Science 315.5814 (2007): 972-976.

Wenn Sie also nicht auf k-means eingestellt sind, empfehle ich, AP direkt zu verwenden, um die Daten zu gruppieren, ohne die Anzahl der Cluster zu kennen:

library(apcluster)
apclus = apcluster(negDistMat(r=2), data)
show(apclus)

Wenn negative euklidische Abstände nicht geeignet sind, können Sie andere Ähnlichkeitsmaße verwenden, die im selben Paket enthalten sind. Für Ähnlichkeiten, die auf Spearman-Korrelationen basieren, benötigen Sie beispielsweise Folgendes:

sim = corSimMat(data, method="spearman")
apclus = apcluster(s=sim)

Bitte beachten Sie, dass diese Funktionen für Ähnlichkeiten im AP-Paket nur zur Vereinfachung bereitgestellt werden. Tatsächlich akzeptiert die Funktion apcluster () in R jede Korrelationsmatrix. Dasselbe kann vorher mit corSimMat () gemacht werden:

sim = cor(data, method="spearman")

oder

sim = cor(t(data), method="spearman")

je nachdem, was Sie in Ihrer Matrix gruppieren möchten (Zeilen oder Spalten).

5
zsram

Eine einfache Lösung ist die Bibliothek factoextra. Sie können die Clustering-Methode und die Methode zur Berechnung der besten Anzahl von Gruppen ändern. Zum Beispiel, wenn Sie die beste Anzahl von Clustern für ein k-Mittel wissen möchten:

Daten: mtcars

library(factoextra)   
fviz_nbclust(mtcars, kmeans, method = "wss") +
      geom_vline(xintercept = 3, linetype = 2)+
      labs(subtitle = "Elbow method")

Schließlich erhalten wir eine Grafik wie:

enter image description here

3
Cro-Magnon

Die Antworten sind großartig. Wenn Sie einer anderen Clustering-Methode eine Chance geben möchten, können Sie hierarchisches Clustering verwenden und sehen, wie Daten aufgeteilt werden.

> set.seed(2)
> x=matrix(rnorm(50*2), ncol=2)
> hc.complete = hclust(dist(x), method="complete")
> plot(hc.complete)

enter image description here

Je nachdem, wie viele Klassen Sie benötigen, können Sie Ihr Dendrogramm wie folgt schneiden:

> cutree(hc.complete,k = 2)
 [1] 1 1 1 2 1 1 1 1 1 1 1 1 1 2 1 2 1 1 1 1 1 2 1 1 1
[26] 2 1 1 1 1 1 1 1 1 1 1 2 2 1 1 1 2 1 1 1 1 1 1 1 2

Wenn Sie ?cutree eingeben, werden die Definitionen angezeigt. Wenn Ihr Datensatz drei Klassen hat, ist es einfach cutree(hc.complete, k = 3). Das Äquivalent für cutree(hc.complete,k = 2) ist cutree(hc.complete,h = 4.9).

1
boyaronur