Como usar variáveis ​​binárias e contínuas juntas no clustering?

27

Preciso usar variáveis ​​binárias (valores 0 e 1) em médias k. Mas k-means funciona apenas com variáveis ​​contínuas. Eu sei que algumas pessoas ainda usam essas variáveis ​​binárias em k-means, ignorando o fato de que k-means é projetado apenas para variáveis ​​contínuas. Isso é inaceitável para mim.

Questões:

  1. Então, qual é a maneira estatisticamente / matematicamente correta de usar variáveis ​​binárias no k-means / cluster hierárquico?
  2. Como implementar a solução em SAS / R?
GeorgeOfTheRF
fonte
11
Estou curioso sobre a fonte de suas informações que "K significa é projetado apenas para variáveis ​​contínuas". Você poderia citar uma referência?
whuber
2
jmp.com/support/help/K-Means_Clustering.shtml "O cluster K-Means suporta apenas colunas numéricas. O cluster K-Means ignora os tipos de modelo (nominal e ordinal) e trata todas as colunas numéricas como colunas contínuas." Eu apenas pesquisei no Google e consegui isso. O ponto em que a média é definida para variáveis ​​contínuas e não para binárias, portanto, k significa que não é possível usar variáveis ​​binárias.
GeorgeOfTheRF
11
Pode usá-los, tratando-os como contínuos; mas interpretar o resultado será difícil, porque os centros de cluster não terão mais um valor binário; e IMHO é quase claro se o resultado é muito significativo - por que faz sentido minimizar a variação de uma variável binária? Em vez disso, considere, por exemplo, mineração de conjuntos de itens frequentes em variáveis ​​binárias se elas corresponderem a presente / ausente para descobrir padrões em seus dados.
Anony-Mousse
Precisa de mais alguma coisa além das respostas abaixo? Isso já existe há muito tempo, e é altamente visualizado e votado, mas não está claro se sua pergunta foi resolvida com satisfação, e também não há indicação do que você ainda pode estar perdendo.
gung - Restabelecer Monica

Respostas:

31

Você está certo de que o cluster k-means não deve ser feito com dados de tipos mistos. Como o k-means é essencialmente um algoritmo de busca simples para encontrar uma partição que minimiza as distâncias euclidianas quadradas dentro do cluster entre as observações em cluster e o centróide do cluster, ela só deve ser usada com dados em que as distâncias euclidianas quadradas seriam significativas.

Quando seus dados consistem em variáveis ​​de tipos mistos, você precisa usar a distância de Gower. O usuário do CV @ttnphns tem uma ótima visão geral da distância de Gower aqui . Em essência, você calcula uma matriz de distância para suas linhas para cada variável, por sua vez, usando um tipo de distância apropriado para esse tipo de variável (por exemplo, Euclidiano para dados contínuos, etc.); a distância final da linha a i ' é a média (possivelmente ponderada) das distâncias para cada variável. Uma coisa a ter em atenção é que a distância de Gower não é realmente uma métrica . No entanto, com dados mistos, a distância de Gower é em grande parte o único jogo na cidade. EuEu

Nesse ponto, você pode usar qualquer método de cluster que possa operar sobre uma matriz de distância em vez de precisar da matriz de dados original. (Observe que o k-means precisa do último.) As opções mais populares são a partição em torno do medoids (PAM, que é essencialmente o mesmo que o k-means, mas usa a observação mais central em vez do centróide), várias abordagens hierárquicas de agrupamento (por exemplo, , mediana, ligação única e ligação completa; com cluster hierárquico, você precisará decidir onde ' cortar a árvore ' para obter as atribuições finais do cluster) e o DBSCAN, que permite formas de cluster muito mais flexíveis.

Aqui está uma Rdemonstração simples (nb, na verdade, existem 3 clusters, mas os dados geralmente se parecem com 2 clusters):

library(cluster)  # we'll use these packages
library(fpc)

  # here we're generating 45 data in 3 clusters:
set.seed(3296)    # this makes the example exactly reproducible
n      = 15
cont   = c(rnorm(n, mean=0, sd=1),
           rnorm(n, mean=1, sd=1),
           rnorm(n, mean=2, sd=1) )
bin    = c(rbinom(n, size=1, prob=.2),
           rbinom(n, size=1, prob=.5),
           rbinom(n, size=1, prob=.8) )
ord    = c(rbinom(n, size=5, prob=.2),
           rbinom(n, size=5, prob=.5),
           rbinom(n, size=5, prob=.8) )
data   = data.frame(cont=cont, bin=bin, ord=factor(ord, ordered=TRUE))
  # this returns the distance matrix with Gower's distance:  
g.dist = daisy(data, metric="gower", type=list(symm=2))

Podemos começar pesquisando diferentes números de clusters com o PAM:

  # we can start by searching over different numbers of clusters with PAM:
pc = pamk(g.dist, krange=1:5, criterion="asw")
pc[2:3]
# $nc
# [1] 2                 # 2 clusters maximize the average silhouette width
# 
# $crit
# [1] 0.0000000 0.6227580 0.5593053 0.5011497 0.4294626
pc = pc$pamobject;  pc  # this is the optimal PAM clustering
# Medoids:
#      ID       
# [1,] "29" "29"
# [2,] "33" "33"
# Clustering vector:
#  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 
#  1  1  1  1  1  2  1  1  1  1  1  2  1  2  1  2  2  1  1  1  2  1  2  1  2  2 
# 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 
#  1  2  1  2  2  1  2  2  2  2  1  2  1  2  2  2  2  2  2 
# Objective function:
#     build      swap 
# 0.1500934 0.1461762 
# 
# Available components:
# [1] "medoids"    "id.med"     "clustering" "objective"  "isolation" 
# [6] "clusinfo"   "silinfo"    "diss"       "call" 

Esses resultados podem ser comparados aos resultados do armazenamento em cluster hierárquico:

hc.m = hclust(g.dist, method="median")
hc.s = hclust(g.dist, method="single")
hc.c = hclust(g.dist, method="complete")
windows(height=3.5, width=9)
  layout(matrix(1:3, nrow=1))
  plot(hc.m)
  plot(hc.s)
  plot(hc.c)

insira a descrição da imagem aqui

O método mediano sugere 2 (possivelmente 3) grupos, o único suporta apenas 2, mas o método completo pode sugerir 2, 3 ou 4 ao meu olho.

Finalmente, podemos tentar o DBSCAN. Isso requer a especificação de dois parâmetros: eps, a 'distância de alcançabilidade' (a que distância duas observações devem ser conectadas) e minPts (o número mínimo de pontos que precisam ser conectados um ao outro antes que você queira chamá-los de 'grupo'). Uma regra prática para minPts é usar uma a mais que o número de dimensões (no nosso caso 3 + 1 = 4), mas não é recomendável ter um número muito pequeno. O valor padrão para dbscané 5; nós vamos ficar com isso. Uma maneira de pensar sobre a distância de alcance é ver qual porcentagem das distâncias é menor que qualquer valor. Podemos fazer isso examinando a distribuição das distâncias:

windows()
  layout(matrix(1:2, nrow=1))
  plot(density(na.omit(g.dist[upper.tri(g.dist)])), main="kernel density")
  plot(ecdf(g.dist[upper.tri(g.dist)]), main="ECDF")

insira a descrição da imagem aqui

As próprias distâncias parecem agrupar-se em grupos visualmente discerníveis de 'mais perto' e 'mais longe'. Um valor de .3 parece distinguir mais claramente entre os dois grupos de distâncias. Para explorar a sensibilidade da saída a diferentes opções de eps, também podemos tentar .2 e .4:

dbc3 = dbscan(g.dist, eps=.3, MinPts=5, method="dist");  dbc3
# dbscan Pts=45 MinPts=5 eps=0.3
#        1  2
# seed  22 23
# total 22 23
dbc2 = dbscan(g.dist, eps=.2, MinPts=5, method="dist");  dbc2
# dbscan Pts=45 MinPts=5 eps=0.2
#         1  2
# border  2  1
# seed   20 22
# total  22 23
dbc4 = dbscan(g.dist, eps=.4, MinPts=5, method="dist");  dbc4
# dbscan Pts=45 MinPts=5 eps=0.4
#        1
# seed  45
# total 45

O uso eps=.3fornece uma solução muito limpa, que (pelo menos qualitativamente) concorda com o que vimos nos outros métodos acima.

Como não existe um cluster 1-ness significativo , devemos ter o cuidado de tentar corresponder quais observações são chamadas 'cluster 1' de diferentes agrupamentos. Em vez disso, podemos formar tabelas e se a maioria das observações chamadas 'cluster 1' em um ajuste for chamada 'cluster 2' em outro, veríamos que os resultados ainda são substancialmente semelhantes. No nosso caso, os diferentes agrupamentos são geralmente muito estáveis ​​e colocam as mesmas observações nos mesmos agrupamentos de cada vez; somente o cluster hierárquico de ligação completo difere:

  # comparing the clusterings
table(cutree(hc.m, k=2), cutree(hc.s, k=2))
#    1  2
# 1 22  0
# 2  0 23
table(cutree(hc.m, k=2), pc$clustering)
#    1  2
# 1 22  0
# 2  0 23
table(pc$clustering, dbc3$cluster)
#    1  2
# 1 22  0
# 2  0 23
table(cutree(hc.m, k=2), cutree(hc.c, k=2))
#    1  2
# 1 14  8
# 2  7 16

Obviamente, não há garantia de que qualquer análise de cluster recupere os verdadeiros clusters latentes em seus dados. A ausência dos verdadeiros rótulos de cluster (que estariam disponíveis em, por exemplo, uma situação de regressão logística) significa que uma enorme quantidade de informações não está disponível. Mesmo com conjuntos de dados muito grandes, os clusters podem não estar suficientemente bem separados para serem perfeitamente recuperáveis. No nosso caso, como conhecemos a verdadeira associação de cluster, podemos compará-la com a saída para ver como ela se saiu. Como observei acima, na verdade existem 3 clusters latentes, mas os dados dão a aparência de 2 clusters:

pc$clustering[1:15]    # these were actually cluster 1 in the data generating process
# 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 
# 1  1  1  1  1  2  1  1  1  1  1  2  1  2  1 
pc$clustering[16:30]   # these were actually cluster 2 in the data generating process
# 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 
#  2  2  1  1  1  2  1  2  1  2  2  1  2  1  2 
pc$clustering[31:45]   # these were actually cluster 3 in the data generating process
# 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 
#  2  1  2  2  2  2  1  2  1  2  2  2  2  2  2 
- Reinstate Monica
fonte
na plotagem de cluster hierárquico que você menciona median method suggests 2 (possibly 3) clusters, the single only supports 2, but the complete method could suggest 2, 3 or 4.. como você chega a isso? usando uma altura de 0,3?
Lukeg
11
@ukuk, as alturas das junções no dendrograma representam o quão longe você precisa ir para mesclar 2 clusters. Você está procurando onde as distâncias se tornam ainda mais para continuar aglomerando. Pode ser útil ler os tópicos que discutem isso aqui e / ou aqui .
gung - Restabelece Monica
2

Veja este artigo de Finch, http://www.jds-online.com/files/JDS-192.pdf . Ele descreve tanto por que a aplicação de métodos contínuos a dados binários pode agrupar incorretamente os dados e, mais importante, quais são algumas opções nas funções de distância adequadas. Ele não responde como agrupar com k-means, mas como agrupar dados binários corretamente usando métricas não euclidianas e um método hierárquico como Ward.

Chris
fonte