2012-03-23 21 views
8

¿Cómo funciona la salida de parcela de kmeans en Python? Estoy usando el paquete PyCluster. allUserVector es un vector n por m dimensonal, básicamente n usuarios con m funciones.Trazado de la salida de kmeans (PyCluster impl)

import Pycluster as pc 
import numpy as np 

clusterid,error,nfound = pc.kcluster(allUserVector, nclusters=3, transpose=0,npass=1,method='a',dist='e') 
    clustermap, _, _ = pc.kcluster(allUserVector, nclusters=3,         transpose=0,npass=1,method='a',dist='e',) 

centroids, _ = pc.clustercentroids(allUserVector, clusterid=clustermap) 
print centroids 
print clusterid 
print nfound 

Quiero imprimir los racimos muy bien en un gráfico que muestra los racimos claramente qué usuarios están en el que cluster.Each usuario es un vector dimensional m Cualquier entrada?

Respuesta

15

Es un poco difícil trazar m -datos dimensionales. Una forma de hacerlo es mapear en un espacio 2d a través de Principal Component Analysis (PCA). Una vez que hayamos hecho eso, podemos lanzarlos a un argumento con matplotlib (basado en this answer).

import numpy as np 
import matplotlib.pyplot as plt 
from matplotlib import mlab 
import Pycluster as pc 

# make fake user data 
users = np.random.normal(0, 10, (20, 5)) 

# cluster 
clusterid, error, nfound = pc.kcluster(users, nclusters=3, transpose=0, 
             npass=10, method='a', dist='e') 
centroids, _ = pc.clustercentroids(users, clusterid=clusterid) 

# reduce dimensionality 
users_pca = mlab.PCA(users) 
cutoff = users_pca.fracs[1] 
users_2d = users_pca.project(users, minfrac=cutoff) 
centroids_2d = users_pca.project(centroids, minfrac=cutoff) 

# make a plot 
colors = ['red', 'green', 'blue'] 
plt.figure() 
plt.xlim([users_2d[:,0].min() - .5, users_2d[:,0].max() + .5]) 
plt.ylim([users_2d[:,1].min() - .5, users_2d[:,1].max() + .5]) 
plt.xticks([], []); plt.yticks([], []) # numbers aren't meaningful 

# show the centroids 
plt.scatter(centroids_2d[:,0], centroids_2d[:,1], marker='o', c=colors, s=100) 

# show user numbers, colored by their cluster id 
for i, ((x,y), kls) in enumerate(zip(users_2d, clusterid)): 
    plt.annotate(str(i), xy=(x,y), xytext=(0,0), textcoords='offset points', 
       color=colors[kls]) 

Si desea representar algo más que números, basta con cambiar el primer argumento de annotate. Es posible que pueda hacer nombres de usuario o algo así, por ejemplo.

Tenga en cuenta que los clústeres pueden parecer un poco "incorrectos" en este espacio (por ejemplo 15 parece más rojo que verde), porque no es el espacio real donde ocurrió la agrupación. En este caso, los dos primeros componentes pricipales preservan 61% de la varianza:

>>> np.cumsum(users_pca.fracs) 
array([ 0.36920636, 0.61313708, 0.81661401, 0.95360623, 1.  ]) 
Cuestiones relacionadas