È un po 'difficile da plasmare dati m
-dimensionali. Un modo per farlo è mappare in uno spazio 2D tramite Principal Component Analysis (PCA). Una volta fatto, possiamo lanciarli su una trama con matplotlib (basato su 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])
Se si desidera tracciare qualcosa di diverso da numeri, basta cambiare il primo argomento di annotate
. Potresti essere in grado di fare nomi utente o qualcosa del genere, per esempio.
Si noti che i cluster potrebbero sembrare leggermente "sbagliati" in questo spazio (ad esempio 15 sembra più vicino al rosso che verde in basso), perché non è lo spazio effettivo in cui si è verificato il clustering. In questo caso, i primi due componenti pricipali preservano 61% della varianza:
>>> np.cumsum(users_pca.fracs)
array([ 0.36920636, 0.61313708, 0.81661401, 0.95360623, 1. ])