Como plotar a saída de dados do clustering?

15

Tentei agrupar um conjunto de dados (um conjunto de marcas) e obtive 2 clusters. Eu gostaria de representá-lo graficamente. Um pouco confuso sobre a representação, já que não tenho as coordenadas (x, y).

Também procurando pela função MATLAB / Python para fazer isso.

EDITAR

Acho que a publicação de dados torna a pergunta mais clara. Eu tenho dois clusters que criei usando o kmeans em Python (sem usar o scipy). Eles são

class 1: a=[3222403552.0, 3222493472.0, 3222491808.0, 3222489152.0, 3222413632.0, 
3222394528.0, 3222414976.0, 3222522768.0, 3222403552.0, 3222498896.0, 3222541408.0, 
3222403552.0, 3222402816.0, 3222588192.0, 3222403552.0, 3222410272.0, 3222394560.0, 
3222402704.0, 3222298192.0, 3222409264.0, 3222414688.0, 3222522512.0, 3222404096.0, 
3222486720.0, 3222403968.0, 3222486368.0, 3222376320.0, 3222522896.0, 3222403552.0, 
3222374480.0, 3222491648.0, 3222543024.0, 3222376848.0, 3222403552.0, 3222591616.0, 
3222376944.0, 3222325568.0, 3222488864.0, 3222548416.0, 3222424176.0, 3222415024.0, 
3222403552.0, 3222407504.0, 3222489584.0, 3222407872.0, 3222402736.0, 3222402032.0, 
3222410208.0, 3222414816.0, 3222523024.0, 3222552656.0, 3222487168.0, 3222403728.0, 
3222319440.0, 3222375840.0, 3222325136.0, 3222311568.0, 3222491984.0, 3222542032.0, 
3222539984.0, 3222522256.0, 3222588336.0, 3222316784.0, 3222488304.0, 3222351360.0, 
3222545536.0, 3222323728.0, 3222413824.0, 3222415120.0, 3222403552.0, 3222514624.0, 
3222408000.0, 3222413856.0, 3222408640.0, 3222377072.0, 3222324304.0, 3222524016.0, 
3222324000.0, 3222489808.0, 3222403552.0, 3223571920.0, 3222522384.0, 3222319712.0, 
3222374512.0, 3222375456.0, 3222489968.0, 3222492752.0, 3222413920.0, 3222394448.0, 
3222403552.0, 3222403552.0, 3222540576.0, 3222407408.0, 3222415072.0, 3222388272.0, 
3222549264.0, 3222325280.0, 3222548208.0, 3222298608.0, 3222413760.0, 3222409408.0, 
3222542528.0, 3222473296.0, 3222428384.0, 3222413696.0, 3222486224.0, 3222361280.0, 
3222522640.0, 3222492080.0, 3222472144.0, 3222376560.0, 3222378736.0, 3222364544.0, 
3222407776.0, 3222359872.0, 3222492928.0, 3222440496.0, 3222499408.0, 3222450272.0, 
3222351904.0, 3222352480.0, 3222413952.0, 3222556416.0, 3222410304.0, 3222399984.0, 
3222494736.0, 3222388288.0, 3222403552.0, 3222323824.0, 3222523616.0, 3222394656.0, 
3222404672.0, 3222405984.0, 3222490432.0, 3222407296.0, 3222394720.0, 3222596624.0, 
3222597520.0, 3222598048.0, 3222403552.0, 3222403552.0, 3222403552.0, 3222324448.0, 
3222408976.0, 3222448160.0, 3222366320.0, 3222489344.0, 3222403552.0, 3222494480.0, 
3222382032.0, 3222450432.0, 3222352000.0, 3222352528.0, 3222414032.0, 3222728448.0, 
3222299456.0, 3222400016.0, 3222495056.0, 3222388848.0, 3222403552.0, 3222487568.0, 
3222523744.0, 3222394624.0, 3222408112.0, 3222406496.0, 3222405616.0, 3222592160.0, 
3222549360.0, 3222438560.0, 3222597024.0, 3222597616.0, 3222598128.0, 3222403552.0, 
3222403552.0, 3222403552.0, 3222499056.0, 3222408512.0, 3222402064.0, 3222368992.0, 
3222511376.0, 3222414624.0, 3222554816.0, 3222494608.0, 3222449792.0, 3222351952.0, 
3222352272.0, 3222394736.0, 3222311856.0, 3222414288.0, 3222402448.0, 3222401056.0, 
3222413568.0, 3222298848.0, 3222297184.0, 3222488000.0, 3222490528.0, 3222394688.0, 
3222408224.0, 3222406672.0, 3222404896.0, 3222443120.0, 3222403552.0, 3222596400.0, 
3222597120.0, 3222597712.0, 3222400896.0, 3222403552.0, 3222403552.0, 3222403552.0, 
3222299200.0, 3222321296.0, 3222364176.0, 3222602208.0, 3222513040.0, 3222414656.0, 
3222564864.0, 3222407904.0, 3222449984.0, 3222352096.0, 3222352432.0, 3222452832.0, 
3222368560.0, 3222414368.0, 3222399376.0, 3222298352.0, 3222573152.0, 3222438080.0, 
3222409168.0, 3222523488.0, 3222394592.0, 3222405136.0, 3222490624.0, 3222406928.0, 
3222407104.0, 3222442464.0, 3222403552.0, 3222596512.0, 3222597216.0, 3222597968.0, 
3222438208.0, 3222403552.0, 3222403552.0, 3222403552.0]

class 2: b=[3498543128.0, 3498542920.0, 3498543252.0, 3498543752.0, 3498544872.0, 
3498544528.0, 3498543024.0, 3498542548.0, 3498542232.0]

Eu gostaria de traçar isso. Tentei o seguinte e obtive o seguinte resultado ao plotar ae b.

pylab.plot(a,'x')
pylab.plot(b,'o')
pylab.show()

insira a descrição da imagem aqui

posso obter uma melhor visualização do cluster?

user2721
fonte
1
Isso realmente depende do que você tenha feito o agrupamento :) Se você mostrar um pequeno exemplo dos dados que você tem eu tenho certeza que você vai obter uma resposta
david w
1
Usar cores e marcadores diferentes tende a ser o mais simples / mais fácil de ler. Se tudo o que você tem são dois clusters, é possível imprimir 0/1 ou O / X para os diferentes valores.
22611 Marcin
Por favor, diga o que você quer dizer com "um conjunto de marcas". Quantas variáveis ​​você possui para caracterizar os clusters? Além disso, você tem certeza de que 2 é o melhor número de clusters para usar? Muitas vezes é preciso usar programas de análise de cluster de forma iterativa; no início, pode-se obter apenas 2, mas com alguns ajustes, pode-se obter um número mais interessante e informativo.
Rolando2
Eu costumava kmeans onde eu tenho que dar o número de clusters explicitamente
user2721
@ user2721, você poderia nos mostrar como usa kmeans?
Sigur

Respostas:

30

Geralmente, você plota os valores originais em um gráfico de dispersão (ou uma matriz de gráficos de dispersão, se houver muitos deles) e usa cores para mostrar seus grupos.

Você pediu uma resposta em python e, na verdade, faz todo o agrupamento e plotagem com scipy, numpy e matplotlib:

Comece criando alguns dados

import numpy as np
from scipy import cluster
from matplotlib import pyplot

np.random.seed(123)
tests = np.reshape( np.random.uniform(0,100,60), (30,2) )
#tests[1:4]
#array([[ 22.68514536,  55.13147691],
#       [ 71.94689698,  42.31064601],
#       [ 98.07641984,  68.48297386]])

Quantos clusters?

Essa é a coisa mais difícil do k-means, e existem muitos métodos. Vamos usar o método do cotovelo

#plot variance for each value for 'k' between 1,10
initial = [cluster.vq.kmeans(tests,i) for i in range(1,10)]
pyplot.plot([var for (cent,var) in initial])
pyplot.show()

Gráfico de cotovelo

Atribua suas observações às classes e plote-as

Eu acho que o índice 3 (ou seja, 4 clusters) é tão bom quanto qualquer outro

cent, var = initial[3]
#use vq() to get as assignment for each obs.
assignment,cdist = cluster.vq.vq(tests,cent)
pyplot.scatter(tests[:,0], tests[:,1], c=assignment)
pyplot.show()

gráfico de dispersão

Apenas descubra onde você pode colocar o que já fez nesse fluxo de trabalho (e espero que os clusters sejam um pouco melhores do que os aleatórios!)

david w
fonte
Sua resposta está ótima. Posso usá-lo eficientemente para meus dados. Não foi possível obter tempo para experimentá-lo.
user2721
@ David David: Esta é uma das melhores respostas que eu já vi! Muito obrigado por postar um exemplo independente. Pelo menos, eu entendo o cerne da sua resposta :) Obrigado mais uma vez!
Legend
@ David David: A única questão que tive é o método do cotovelo mostra valores crescentes e seu gráfico mostra diminuição. Isso ocorre porque você está usando os valores de distorção diretamente dos kmeans? Como posso converter isso para parecer o gráfico de cotovelo da Wikipedia? E como última pergunta, você saberia como fazer isso para kmeans2 em vez de kmeans?
Legend
Você descobriu o índice 3 apenas olhando para o primeiro gráfico?
Sigur
2

Talvez tente algo como o Fastmap para plotar seu conjunto de marcas usando suas distâncias relativas.

(ainda) nada inteligente escreveu o Fastmap em python para plotar seqüências de caracteres e pode ser facilmente atualizado para lidar com listas de atributos se você escrever sua própria métrica de distância.

Abaixo está uma distância euclidiana padrão que utilizo que usa duas listas de atributos como parâmetros. Se suas listas tiverem um valor de classe, não o utilize no cálculo da distância.

def distance(vecone, vectwo, d=0.0):
    for i in range(len(vecone)):
        if isnumeric(vecone[i]):
            d = d + (vecone[i] - vectwo[i])**2
        elif vecone[i] is not vectwo[i]:
            d += 1.0
    return math.sqrt(d)

def isnumeric(s):
    try:
        float(s)
        return True
    except ValueError:
        return False
um açougueiro
fonte
0

Não sou especialista em python, mas é extremamente útil plotar os 2 primeiros componentes principais um contra o outro nos eixos x, y.

Não tenho certeza dos pacotes que você está usando, mas aqui está um link de exemplo:

http://pyrorobotics.org/?page=PyroModuleAnalysis

Ralph Winters
fonte
Eu não sou especialista em estatística. Poderia explicar mais sobre a ideia de plotagem?
usar o seguinte comando
A idéia básica é que muitas variáveis ​​são correlacionadas entre si e tudo pode ser reduzido a apenas duas variáveis ​​que não são correlacionadas entre si e explicam "a maioria" da variação nos dados. Você precisa ler a análise dos componentes principais e aplicar um pacote que permita implementá-lo. en.wikipedia.org/wiki/Principal_component_analysis
Ralph Winters