Por que a estatística de gap para k-means sugere um cluster, mesmo que obviamente haja dois deles?

18

Estou usando o K-means para agrupar meus dados e estava procurando uma maneira de sugerir um número de cluster "ideal". As estatísticas de gap parecem ser uma maneira comum de encontrar um bom número de cluster.

Por alguma razão, ele retorna 1 como o número ideal do cluster, mas quando olho para os dados, é óbvio que existem 2 clusters:

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

É assim que chamo de gap no R:

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

O conjunto de resultados:

> 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

Estou fazendo algo errado ou alguém conhece uma maneira melhor de obter um bom número de cluster?

MikeHuber
fonte

Respostas:

37

O agrupamento depende da escala , entre outras coisas. Para discussões sobre esta questão, consulte ( inter alia ) Quando você deve centralizar e padronizar os dados? e PCA em covariância ou correlação?.

Aqui estão seus dados desenhados com uma proporção de 1: 1, revelando o quanto as escalas das duas variáveis ​​diferem:

figura 1

kkclusGap

kf(k) não esteja mais do que 1 erro padrão longe do primeiro máximo local.

k=1 .

ab

Figura 2

k=2k{1,2,3,4,5}k=2kk=1kk=2. Eles são mostrados aqui apenas para ilustrar o método geral.


Aqui está o Rcódigo para produzir esses números. Os dados correspondem aproximadamente aos mostrados na pergunta.

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
fonte
tudo bem obrigado pela explicação. Btw: Você conhece alguma outra métrica de cluster, como estatísticas de gap? Encontrei alguns, mas não sei qual deles é normalmente usado com k-means?
MikeHuber
+1. Demonstração muito boa, e é impressionante que você pareça ter digitado o número do OP para obter os mesmos dados.
Ameba diz Reinstate Monica
3
@amoeba Observei o gráfico de dispersão e digitei as coordenadas exatamente como você vê aqui (ou seja, os dígitos envolvidos eram meus próprios dedos :-)). Às vezes, a abordagem mais simples é eficiente.
whuber
A estatística de gap pode ser usada para encontrar o número de clusters em uma única matriz 1-d de valores numéricos?
user1971988
xyxy <- xy[, 1, drop=FALSE]n×1R(xi)(xi,0)
9

xyK=1K>1a incapacidade de rejeitar a hipótese nula não a torna verdadeira . O artigo metodológico que descreve a estatística GAP está disponível on-line se você quiser verificar mais os detalhes técnicos.

k2×2k significa que sua matriz de covariância é mais estruturada (você não olha para covariâncias), mas eu não focaria nesse assunto aqui.)

kK=2

usεr11852 diz Reinstate Monic
fonte
+1 Você viu o problema em potencial lendo atentamente o enredo: muito bem! O link para o artigo de Hastie também é um suporte bem-vindo à sua resposta.
whuber
@whuber: Tivemos essa discussão sobre escalas, não tivemos? :)
usεr11852 diz Reinstate Monic
Era um contexto tão diferente que eu não fiz a conexão ....
whuber
Era realmente um contexto diferente; Eu mencionei isso para você apenas porque eram "escalas" lá e "escalas" aqui.
usεr11852 diz Reinstate Monic
0

Eu tive o mesmo problema que o pôster original. Atualmente, a documentação R diz que a configuração original e padrão de d.power = 1 estava incorreta e deve ser substituída por d.power: "O padrão, d.power = 1, corresponde à implementação R" histórica ", enquanto que d.power = 2 corresponde ao que Tibshirani et al propuseram. Foi encontrado por Juan Gonzalez em 02/02/2016 ".

Conseqüentemente, mudar d.power = 2 resolveu o problema para mim.

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

mikki
fonte