Como você testa uma implementação de k-means?

11

Isenção de responsabilidade: postei esta pergunta no Stackoverflow, mas achei que talvez isso seja mais adequado para esta plataforma.

Como você testa sua própria implementação de k-means para conjuntos de dados multidimensionais?

Eu estava pensando em executar uma implementação já existente (ou seja, Matlab) nos dados e comparar os resultados com meu algoritmo. Mas isso exigiria que ambos os algoritmos funcionassem mais do que aproximadamente o mesmo, e o mapeamento entre os dois resultados provavelmente não é fácil.

Você tem uma ideia melhor?

Framester
fonte

Respostas:

10

O k-means inclui um componente estocástico, portanto, é muito improvável que você obtenha o mesmo resultado, a menos que tenha exatamente a mesma implementação e use a mesma configuração inicial. No entanto, você pode ver se seus resultados estão de acordo com implementações conhecidas (não conhece o Matlab, mas a implementação do algoritmo k-means em R é bem explicada, consulte Hartigan & Wong, 1979 ).

Quanto à comparação de duas séries de resultados, ainda há um problema com a troca de etiquetas, se ela for executada várias vezes. Novamente, no pacote e1071 R, existe uma função muito útil (; matchClasses()) que pode ser usada para encontrar o 'melhor' mapeamento entre duas categorias em uma tabela de classificação bidirecional. Basicamente, a idéia é reorganizar as linhas para maximizar sua concordância com as colunas, ou usar uma abordagem gananciosa e permutar linhas e colunas até que a soma da diagonal (concordância bruta) seja máxima. Também são fornecidos coeficientes de concordância, como a estatística Kappa .

Por fim, sobre como comparar sua implementação, existem muitos dados disponíveis gratuitamente ou você pode simular um conjunto de dados dedicado (por exemplo, através de um modelo de mistura finita, consulte o pacote MixSim ).

chl
fonte
oi chi, obrigado pela resposta. Quando você quiser, também pode responder à pergunta idêntica na SO e eu a aceitaria lá também. => stackoverflow.com/questions/4280371/…
Framester
(+1) O primeiro parágrafo chega rapidamente ao cerne da questão.
whuber
6

É fácil calcular o mapeamento entre dois conjuntos de resultados, porque as informações obtidas em um teste podem ser representadas como um conjunto de três tuplas: o primeiro componente é um ponto (multidimensional), o segundo é um rótulo de cluster (arbitrário) fornecido pelo seu algoritmo e o terceiro é um rótulo de cluster (arbitrário) fornecido por um algoritmo de referência. Construa o porkktabela de classificação para os pares de rótulos: se os resultados concordarem, será um múltiplo de uma matriz de permutação. Ou seja, cada linha e cada coluna deve ter exatamente uma célula diferente de zero. Essa é uma verificação simples para programar. Também é fácil rastrear pequenos desvios desse ideal de volta aos pontos de dados individuais, para que você possa ver com precisão como as duas respostas diferem, se são diferentes. Eu não me incomodaria em calcular medidas estatísticas de concordância: ou há concordância perfeita (até a permutação) ou não, e no último caso, você precisa rastrear todos os pontos de discordância para entender como eles ocorrem. Os resultados concordam ou não; qualquer desacordo, mesmo em um ponto, precisa ser verificado.

Você pode usar vários tipos de conjuntos de dados para testar: (1) conjuntos de dados publicados com resultados de médias k publicados; (2) conjuntos de dados sintéticos com agrupamentos fortes óbvios; (3) conjuntos de dados sintéticos sem agrupamento óbvio. (1) é uma boa disciplina a ser usada sempre que você escrever qualquer programa de matemática ou estatística. (2) é fácil de fazer de várias maneiras, como gerar alguns pontos aleatórios para servir como centros de agrupamentos e depois gerar nuvens de pontos deslocando aleatoriamente os centros de agrupamentos em quantidades relativamente pequenas. (3) fornece algumas verificações aleatórias que potencialmente descobrem comportamentos inesperados; Novamente, essa é uma boa disciplina geral de teste.

Além disso, considere a criação de conjuntos de dados que enfatizam o algoritmo, apenas nos limites entre soluções extremas. Isso exigirá criatividade e um profundo entendimento do seu algoritmo (o que você provavelmente tem!). Um exemplo que gostaria de verificar em qualquer caso, seria conjuntos de vetores da forma onde é um vetor sem componentes de zero e assume valores sequenciais integrais . Eu também gostaria de verificar o algoritmo em conjuntos de vetores que formam polígonos equilaterais. Em qualquer uma das situações, os casos em que não é um múltiplo de são particularmente interessantes, incluindo ondeivvi0,1,2,,n1nkné menor que . O que é comum a essas situações é que (a) eles usam todas as dimensões do problema, mas (b) as soluções corretas são geometricamente óbvias e (c) existem várias soluções corretas.k

(Forme polígonos equilaterais aleatórios nas dimensões , começando com dois vetores diferentes de zero e escolhidos aleatoriamente. (Uma boa maneira é permitir que seus componentes sejam variáveis ​​normais padrão independentes). eles têm tamanho unitário; vamos chamá-los de e . Remova o componente de por meio da fórmulad2uv2dxzxz

w=z(zx)x.

Obtenha redimensionando para ter o tamanho da unidade. Se quiser, redimensione uniformemente e aleatoriamente. Os vetores e formam uma base ortogonal para um subespaço 2D aleatório em dimensões. Um polígono equilátero de vértices é obtido como o conjunto de pois o número inteiro varia de até .)w x y x y d n cos ( 2 π k / n ) x + sen ( 2 π k / n ) y k 0 n - 1ywxyxydncos(2πk/n)x+sin(2πk/n)yk0n1

whuber
fonte
(+1) Seus comentários sobre as possíveis maneiras de gerar dados sintéticos relevantes são muito bem-vindos.
chl
2

Uma abordagem "ingênua" muito simples seria usar dados sintéticos simples, pois cada implementação deve resultar nos mesmos clusters.

Exemplo em Python com import numpy as np:

test_data = np.zeros((40000, 4))
test_data[0:10000, :] = 30.0
test_data[10000:20000, :] = 60.0
test_data[20000:30000, :] = 90.0
test_data[30000:, :] = 120.0

Pois n_clusters = 4isso deve lhe dar uma permutação de[30, 60, 90, 120]

Framester
fonte
0

Como o k-means contém decisões que são escolhidas aleatoriamente (apenas a parte de inicialização), acho que a melhor maneira de testar seu algoritmo é selecionar os pontos iniciais e deixá-los fixados no seu algoritmo primeiro e depois escolher outro código-fonte do algoritmo e fixe os pontos da mesma maneira. Então você pode comparar os resultados reais.

mariana soffer
fonte