462 Stimmen

Clusteranalyse in R: Bestimmen der optimalen Anzahl von Clustern

Wie kann ich die beste Anzahl von Clustern für eine k-Means-Analyse wählen? Nachdem ich eine Teilmenge der unten stehenden Daten geplottet habe, wie viele Cluster wären angemessen? 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 )

24voto

Matt Bannert Punkte 26347

Es ist schwer, etwas zu einer so ausführlichen Antwort hinzuzufügen. Ich glaube aber, dass wir hier identify erwähnen sollten, insbesondere weil @Ben viele Dendrogramm-Beispiele zeigt.

d_dist <- dist(as.matrix(d))   # Finde Distanzmatrix
plot(hclust(d_dist)) 
clusters <- identify(hclust(d_dist))

identify ermöglicht es Ihnen, interaktiv Cluster aus einem Dendrogramm auszuwählen und speichert Ihre Auswahl in einer Liste. Drücken Sie Esc, um den Interaktionsmodus zu verlassen und zum R-Konsolenmodus zurückzukehren. Beachten Sie, dass die Liste die Indizes und nicht die Zeilennamen enthält (im Gegensatz zu cutree).

13voto

VanThaoNguyen Punkte 716

Um den optimalen k-Cluster in Clustering-Methoden zu bestimmen, verwende ich normalerweise die Elbow-Methode in Kombination mit paralleler Verarbeitung, um zeitaufwändige Prozesse zu vermeiden. Dieser Code könnte so aussehen:

Elbow-Methode

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)
}

Ausführen von Elbow 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('Die Zeit, um k mit der Elbow-Methode zu finden beträgt',(end.time - start.time),'Sekunden mit dem Wert von k:', k.clusters)

Es funktioniert gut.

10voto

RRuiz Punkte 1890

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. Wenn Sie beispielsweise die beste Anzahl von Clustern für ein K-Means-Verfahren wissen möchten:

Daten: mtcars

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

Zum Schluss erhalten wir ein Diagramm wie:

Bildbeschreibung hier eingeben

9voto

zsram Punkte 356

Prächtige Antwort von Ben. Ich bin jedoch überrascht, dass die Affinity Propagation (AP)-Methode hier vorgeschlagen wurde, um nur die Anzahl der Cluster für die k-Means-Methode zu finden, während AP im Allgemeinen eine bessere Arbeit beim Clustern der Daten leistet. Bitte sehen Sie das wissenschaftliche Papier, das diese Methode in Science unterstützt, hier:

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

Also, wenn Sie nicht voreingenommen gegen k-Means sind, empfehle ich, AP direkt zu verwenden, das die Daten clustert, 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 bereitgestellt werden. Zum Beispiel benötigen Sie für Ähnlichkeiten basierend auf Spearman-Korrelationen dies:

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 Matrix von Korrelationen. Das Gleiche wie zuvor mit corSimMat() kann mit diesem gemacht werden:

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

oder

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

abhängig davon, was Sie in Ihrer Matrix clustern möchten (Zeilen oder Spalten).

8voto

RDRR Punkte 800

Diese Methoden sind großartig, aber wenn man versucht, k für viel größere Datensätze zu finden, können sie in R wahnsinnig 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.

Zunächst möchten Sie sicherstellen, dass Weka auf Ihrem System installiert ist und XMeans über das Paketverwaltungstool von Weka installiert ist.

library(RWeka)

# Drucken Sie eine Liste der verfügbaren Optionen für den X-Means Algorithmus
WOW("XMeans")

# Erstellen Sie ein Weka_control Objekt, das unsere Parameter spezifiziert
weka_ctrl <- Weka_control(
    I = 1000,                          # max. Anzahl insgesamt Iterationen
    M = 1000,                          # max. Anzahl von Iterationen im kMeans-Loop
    L = 20,                            # min. Anzahl von Clustern
    H = 150,                           # max. Anzahl von Clustern
    D = "weka.core.EuclideanDistance", # Distanzmetrik: euklidisch
    C = 0.4,                           # Cutoff-Faktor ???
    S = 12                             # Zufallszahlensaat (für Reproduzierbarkeit)
)

# Führen Sie den Algorithmus auf Ihren Daten, d, aus
x_means <- XMeans(d, control = weka_ctrl)

# Weisen Sie Cluster-IDs dem Originaldatensatz zu
d$xmeans.cluster <- x_means$class_ids

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X