Warum deutet die Lückenstatistik für k-means auf einen Cluster hin, obwohl es offensichtlich zwei davon gibt?

18

Ich verwende K-means, um meine Daten zu gruppieren, und suche nach einer Möglichkeit, eine "optimale" Clusternummer vorzuschlagen. Gap-Statistiken scheinen ein gängiger Weg zu sein, um eine gute Clusternummer zu finden.

Aus irgendeinem Grund gibt es 1 als optimale Clusternummer zurück, aber wenn ich mir die Daten anschaue, ist es offensichtlich, dass es 2 Cluster gibt:

! [1] (http://i60.tinypic.com/28bdy6u.jpg)

So nenne ich Lücke in R:

gap <- clusGap(data, FUN=kmeans, K.max=10, B=500)
with(gap, maxSE(Tab[,"gap"], Tab[,"SE.sim"], method="firstSEmax"))

Die Ergebnismenge:

> Number of clusters (method 'firstSEmax', SE.factor=1): 1
          logW   E.logW           gap    SE.sim
[1,]  5.185578 5.085414 -0.1001632148 0.1102734
[2,]  4.438812 4.342562 -0.0962498606 0.1141643
[3,]  3.924028 3.884438 -0.0395891064 0.1231152
[4,]  3.564816 3.563931 -0.0008853886 0.1387907
[5,]  3.356504 3.327964 -0.0285393917 0.1486991
[6,]  3.245393 3.119016 -0.1263766015 0.1544081
[7,]  3.015978 2.914607 -0.1013708665 0.1815997
[8,]  2.812211 2.734495 -0.0777154881 0.1741944
[9,]  2.672545 2.561590 -0.1109558011 0.1775476
[10,] 2.656857 2.403220 -0.2536369287 0.1945162

Mache ich etwas falsch oder weiß jemand einen besseren Weg, um eine gute Clusternummer zu erhalten?

MikeHuber
quelle

Antworten:

37

Clustering hängt unter anderem von der Größe ab . Diskussionen zu diesem Thema finden Sie unter ( unter anderem ) Wann sollten Sie Daten zentrieren und standardisieren? und PCA zur Kovarianz oder Korrelation? .

Hier sehen Sie Ihre Daten mit einem Seitenverhältnis von 1: 1, aus dem hervorgeht, wie stark sich die Maßstäbe der beiden Variablen unterscheiden:

Abbildung 1

Rechts davon zeigt das Diagramm der Lückenstatistiken die Statistik nach Anzahl der Cluster ( ) mit Standardfehlern, die mit vertikalen Segmenten gezeichnet wurden, und dem optimalen Wert von der mit einer vertikalen gestrichelten blauen Linie markiert ist. Nach der Hilfe,kkclusGap

Die Standardmethode "firstSEmax" sucht nach dem kleinsten , sodass sein Wert nicht mehr als 1 Standardfehler vom ersten lokalen Maximum entfernt ist.kf(k)

Andere Methoden verhalten sich ähnlich. Dieses Kriterium lässt keine der Lückenstatistiken auffallen, was zu einer Schätzung von .k=1

Die Auswahl des Maßstabs hängt von der Anwendung ab. Ein vernünftiger Standardausgangspunkt ist jedoch ein Maß für die Streuung der Daten, z. B. die MAD oder die Standardabweichung. In diesem Diagramm wird die Analyse nach dem erneuten Zentrieren auf Null und dem erneuten Skalieren wiederholt, um eine Einheitsstandardabweichung für jede Komponente und :einb

Figur 2

Die K-Means-Lösung wird durch Variieren des Symboltyps und der Farbe im Streudiagramm der Daten auf der linken Seite angezeigt. Unter der Menge ist in der Darstellung der Lückenstatistik auf der rechten Seite eindeutig bevorzugt: Es ist das erste lokale Maximum und die Statistik für kleineres (das heißt, ) sind deutlich niedriger. Größere Werte für passen wahrscheinlich zu einem so kleinen Datensatz, und keiner ist signifikant besser als . Sie werden hier nur gezeigt, um die allgemeine Methode zu veranschaulichen. k { 1 , 2 , 3 , 4 , 5 } k = 2 k k = 1 k k = 2k=2k{1,2,3,4,5}k=2kk=1kk=2


Hier ist RCode, um diese Zahlen zu produzieren. Die Daten stimmen ungefähr mit den Angaben in der Frage überein.

library(cluster)
xy <- matrix(c(29,391, 31,402, 31,380, 32.5,391, 32.5,360, 33,382, 33,371,
        34,405, 34,400, 34.5,404, 36,343, 36,320, 36,303, 37,344,
        38,358, 38,356, 38,351, 39,318, 40,322, 40, 341), ncol=2, byrow=TRUE)
colnames(xy) <- c("a", "b")
title <- "Raw data"
par(mfrow=c(1,2))
for (i in 1:2) {
  #
  # Estimate optimal cluster count and perform K-means with it.
  #
  gap <- clusGap(xy, kmeans, K.max=10, B=500)
  k <- maxSE(gap$Tab[, "gap"], gap$Tab[, "SE.sim"], method="Tibs2001SEmax")
  fit <- kmeans(xy, k)
  #
  # Plot the results.
  #
  pch <- ifelse(fit$cluster==1,24,16); col <- ifelse(fit$cluster==1,"Red", "Black")
  plot(xy, asp=1, main=title, pch=pch, col=col)
  plot(gap, main=paste("Gap stats,", title))
  abline(v=k, lty=3, lwd=2, col="Blue")
  #
  # Prepare for the next step.
  #
  xy <- apply(xy, 2, scale)
  title <- "Standardized data"
}
whuber
quelle
Okay, danke für die Erklärung. Btw: Kennen Sie eine andere Cluster-Metrik wie die Gap-Statistik? Ich habe welche gefunden, weiß aber nicht, welche normalerweise mit k-means verwendet werden?
Mike Huber
+1. Sehr schöne Demonstration, und es ist beeindruckend, dass Sie die OP-Zahl scheinbar digitalisiert haben, um die gleichen Daten zu erhalten.
Amöbe sagt Reinstate Monica
3
@amoeba Ich musterte das Streudiagramm und tippte die Koordinaten genau so ein, wie Sie es hier sehen (das heißt, die betroffenen Ziffern waren meine eigenen Finger :-)). Manchmal ist der einfachste Ansatz effizient.
Whuber
Kann die Lückenstatistik zum Ermitteln der Anzahl von Clustern in einem einzelnen 1-d-Array numerischer Werte verwendet werden?
user1971988
@ user1971988 Warum nicht probieren? Ersetzen Sie xyden Code durch xy <- xy[, 1, drop=FALSE](um ein Array von erstellen). Wenn Sie nicht verwenden , betrachten Sie dieses kleine Gedankenexperiment: Jedes 1-D-Array kann als 2-D-Array ohne die Abstände zu ändern. Durch Clustering der letzteren werden die ersteren gruppiert. ( x i ) ( x i , 0 )n×1R(xich)(xich,0)
Whuber
9

Ich denke, Sie verstehen nichts Falsches an Ihrer Verwendung der GAP-Statistik. Ich glaube, dass Sie durch den Umfang der Daten in der Visualisierung teilweise irregeführt werden. Sie sehen zwei Cluster, aber tatsächlich ist die xRichtung im Vergleich zur yRichtung eher klein . Basierend darauf würden Sie zwei lange Cluster erwarten . Trotzdem sieht es so aus, als ob Ihre eine Varianz die andere dominiert. Da die GAP-Statistik ein Nullmodell mit einer einzelnen Komponente ( ) annimmt und dann versucht, dieses Modell für ein alternatives mit ; Was Sie beobachten, ist die Unfähigkeit, die Null abzulehnen. Bitte beachten Sie, dass die Unfähigkeit, die Nullhypothese abzulehnen, diese nicht erfülltK > 1K=1K>1. Das Methodenpapier zur Beschreibung der GAP-Statistik ist online verfügbar, wenn Sie die technischen Details genauer prüfen möchten.

Ich führe dein Modell mit einem Gaußschen Mischungsmodell aus (GMM - eine Verallgemeinerung von Mitteln, mehr dazu in diesem Thread ). Richtig, auch in diesem Fall deutete die GAP-Statistik auf einen einzelnen Cluster hin. Der BIC schlug auch einen einzelnen Cluster vor. AIC schlägt 4 Cluster (!) Vor, was ein klares Zeichen dafür ist, dass wir anfangen, uns zu übertreiben. Die verwendete Stichprobe ist nicht extrem groß; Sie haben 21 Punkte, bei denen ein Varianzmodus den anderen dominiert. Es ist ein bisschen schwierig, zwei 2-D-Cluster (dh zwei 2-D-Mittelwerte und zwei Kovarianz-Matrizen) mit nur 21 2-D-Punkten zu haben. :) (Im Fall von Means ist Ihre Kovarianzmatrix strukturierter (Sie betrachten keine Kovarianzen), aber ich würde mich hier nicht darauf konzentrieren.)2 × 2 kk2×2k

EDIT: Nur der Vollständigkeit halber: @whuber zeigte, dass zwei Cluster in Mitteln als optimal erscheinen würden, wenn man seine Daten standardisieren würde; Das auf die GMM-Anpassung angewendete GAP-Kriterium ergibt auch als die optimale Anzahl von Clustern, wenn man die Daten standardisiert.K = 2kK=2

usεr11852 sagt Reinstate Monic
quelle
+1 Sie haben das potenzielle Problem erkannt, indem Sie die Handlung sorgfältig gelesen haben: Gut gemacht! Der Link zu Hasties Artikel ist auch eine willkommene Unterstützung für Ihre Antwort.
whuber
@whuber: Wir hatten diese Diskussion über Skalen, nicht wahr? :)
usεr11852 sagt Reinstate Monic
Es war so ein anderer Kontext, dass ich die Verbindung nicht hergestellt habe.
whuber
Es war in der Tat ein anderer Kontext; Ich habe es Ihnen gegenüber erwähnt, nur weil es dort "Skalen" und hier "Skalen" waren.
usεr11852 sagt Reinstate Monic
0

Ich hatte das gleiche Problem wie das Originalplakat. Die R-Dokumentation besagt derzeit, dass die ursprüngliche und Standardeinstellung von d.power = 1 falsch war und durch d.power ersetzt werden sollte: "Die Standardeinstellung d.power = 1 entspricht der" historischen "R-Implementierung, wohingegen d.power = 2 entspricht dem, was Tibshirani et al vorgeschlagen hatten. Dies wurde von Juan Gonzalez in 2016-02 gefunden. "

Folglich löste das Ändern von d.power = 2 das Problem für mich.

https://www.rdocumentation.org/packages/cluster/versions/2.0.6/topics/clusGap

mikki
quelle