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. ])