Le calcul du pourcentage de la variance mesure pour k-means?
Sur le Page Wikipedia, un coude de la méthode est décrite pour déterminer le nombre de clusters à k-means. La méthode intégrée de scipy fournit une mise en œuvre, mais je ne suis pas sûr de comprendre comment la distorsion comme ils l'appellent, est calculée.
Plus précisément, si vous graphique le pourcentage de la variance expliquée par
les clusters en fonction du nombre de clusters, la première clusters
ajouter beaucoup d'informations (expliquer une grande partie de la variance), mais à un certain point
le gain marginal chute, donnant un angle dans le graphique.
En supposant que j'ai les points suivants avec leurs centroïdes, ce qui est un bon moyen de calcul de cette mesure?
points = numpy.array([[ 0, 0],
[ 0, 1],
[ 0, -1],
[ 1, 0],
[-1, 0],
[ 9, 9],
[ 9, 10],
[ 9, 8],
[10, 9],
[10, 8]])
kmeans(pp,2)
(array([[9, 8],
[0, 0]]), 0.9414213562373096)
Que je recherche précisément au calcul de l'0.94.. mesure de simplement les points et les centroïdes. Je ne suis pas sûr si l'un des intégré les méthodes de scipy peut être utilisé ou je dois écrire mon propre. Toutes les suggestions sur la façon de le faire efficacement pour un grand nombre de points?
En bref, mes questions (toutes relatives) sont les suivantes:
- Donnée d'une matrice de distance et une cartographie de ce qui appartient à quel point
cluster, ce qui est un bon moyen de calcul d'une mesure qui peut être utilisée
pour tirer le coude de la parcelle? - Comment la méthodologie de changer si une autre fonction de distance tels que la similarité cosinus est utilisée?
EDIT 2: Distorsion
from scipy.spatial.distance import cdist
D = cdist(points, centroids, 'euclidean')
sum(numpy.min(D, axis=1))
La sortie pour le premier ensemble de points de est fidèle. Cependant, quand j'essaye un autre jeu:
>>> pp = numpy.array([[1,2], [2,1], [2,2], [1,3], [6,7], [6,5], [7,8], [8,8]])
>>> kmeans(pp, 2)
(array([[6, 7],
[1, 2]]), 1.1330618877807475)
>>> centroids = numpy.array([[6,7], [1,2]])
>>> D = cdist(points, centroids, 'euclidean')
>>> sum(numpy.min(D, axis=1))
9.0644951022459797
Je suppose que la dernière valeur ne correspond pas à cause kmeans
semble être la plongée de la valeur par le nombre total de points dans le jeu de données.
EDIT 1: Pourcentage de la Variance
Mon code jusqu'à présent (ce qui devrait être ajouté à Denis K-moyens de mise en œuvre):
centres, xtoc, dist = kmeanssample( points, 2, nsample=2,
delta=kmdelta, maxiter=kmiter, metric=metric, verbose=0 )
print "Unique clusters: ", set(xtoc)
print ""
cluster_vars = []
for cluster in set(xtoc):
print "Cluster: ", cluster
truthcondition = ([x == cluster for x in xtoc])
distances_inside_cluster = (truthcondition * dist)
indices = [i for i,x in enumerate(truthcondition) if x == True]
final_distances = [distances_inside_cluster[k] for k in indices]
print final_distances
print np.array(final_distances).var()
cluster_vars.append(np.array(final_distances).var())
print ""
print "Sum of variances: ", sum(cluster_vars)
print "Total Variance: ", points.var()
print "Percent: ", (100 * sum(cluster_vars) / points.var())
Et voici le résultat pour k=2:
Unique clusters: set([0, 1])
Cluster: 0
[1.0, 2.0, 0.0, 1.4142135623730951, 1.0]
0.427451660041
Cluster: 1
[0.0, 1.0, 1.0, 1.0, 1.0]
0.16
Sum of variances: 0.587451660041
Total Variance: 21.1475
Percent: 2.77787757437
Sur mon dataset (ne pas regarder à droite pour moi!):
Sum of variances: 0.0188124746402
Total Variance: 0.00313754329764
Percent: 599.592510943
Unique clusters: set([0, 1, 2, 3])
Sum of variances: 0.0255808508714
Total Variance: 0.00313754329764
Percent: 815.314672809
Unique clusters: set([0, 1, 2, 3, 4])
Sum of variances: 0.0588210052519
Total Variance: 0.00313754329764
Percent: 1874.74720416
Unique clusters: set([0, 1, 2, 3, 4, 5])
Sum of variances: 0.0672406353655
Total Variance: 0.00313754329764
Percent: 2143.09824556
Unique clusters: set([0, 1, 2, 3, 4, 5, 6])
Sum of variances: 0.0646291452839
Total Variance: 0.00313754329764
Percent: 2059.86465055
Unique clusters: set([0, 1, 2, 3, 4, 5, 6, 7])
Sum of variances: 0.0817517362176
Total Variance: 0.00313754329764
Percent: 2605.5970695
Unique clusters: set([0, 1, 2, 3, 4, 5, 6, 7, 8])
Sum of variances: 0.0912820650486
Total Variance: 0.00313754329764
Percent: 2909.34837831
Unique clusters: set([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
Sum of variances: 0.102119601368
Total Variance: 0.00313754329764
Percent: 3254.76309585
Unique clusters: set([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
Sum of variances: 0.125549475536
Total Variance: 0.00313754329764
Percent: 4001.52168834
Unique clusters: set([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
Sum of variances: 0.138469402779
Total Variance: 0.00313754329764
Percent: 4413.30651542
Unique clusters: set([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
- Je vais essayer de répondre à cette soirée 🙂
- Merci 🙂
Vous devez vous connecter pour publier un commentaire.
La distorsion, dans la mesure du Kmeans est concerné, est utilisé comme un critère d'arrêt (si le changement entre deux itérations est inférieur à un certain seuil, nous supposons convergence)
Si vous voulez calculer à partir d'un ensemble de points et les centroïdes, vous pouvez effectuer les opérations suivantes (le code est dans MATLAB à l'aide de
pdist2
fonction, mais il devrait être très simple à réécrire en Python/Numpy/Scipy):le résultat:
EDIT#1:
J'ai eu un peu de temps pour jouer avec cela.. Voici un exemple de KMeans l'agrégation est appliquée sur la 'Fisher Iris Dataset' (4 fonctions, 150 cas). Nous itérer sur
k=1..10
, le terrain, le coude de la courbe, choisissezK=3
que le nombre de clusters et de montrer un nuage de points de la suite.Remarque que j'ai inclus un certain nombre de manières de calculer l'intérieur du cluster écarts (distorsions), étant donné les points et les centroïdes. Le
scipy.cluster.vq.kmeans
fonction renvoie cette mesure par défaut (calculée avec Euclidienne comme une mesure de distance). Vous pouvez également utiliser lescipy.spatiales.distance.cdist
fonction pour calculer les distances avec la fonction de votre choix (à condition d'avoir obtenu le cluster des centroïdes en utilisant la même mesure de la distance: @Denis avez une solution pour ça), puis calculer la distorsion de que.EDIT#2:
En réponse aux commentaires, je donne ci-dessous un autre exemple complet à l'aide de la NIST écrites à la main, chiffres dataset: il a 1797 images de chiffres de 0 à 9, chacun de la taille de 8 par 8 pixels. Je répète l'expérience ci-dessus légèrement modifiée: L'Analyse En Composantes Principales est appliqué afin de réduire la dimensionnalité de 64 à 2:
Vous pouvez voir comment certains clusters correspondent en fait à distinguer les chiffres, tandis que d'autres ne correspond pas à un numéro unique.
Remarque: Une mise en œuvre de K-means est inclus dans
scikit-learn
(ainsi que de nombreux autres algorithmes de clustering et de divers clustering métriques). Ici est un autre exemple similaire.k
. Dans le post ici: stats.stackexchange.com/questions/9850/... l'auteur utilise directement distorsion, mais je ne pouvais pas vraiment comprendre pourquoi il a fait ça. Auriez-vous des idées sur ce point?Un simple cluster de mesure:
1) tirage au sort "sunburst" rayons à partir de chaque point de son plus proche cluster centre,
2) regardez la longueur de la distance de l'( le point, le centre, la métrique=... ) — de tous les rayons.
Pour
metric="sqeuclidean"
et 1 cluster,la durée moyenne quadratique est la variance totale
X.var()
; pour les 2 groupes, il est de moins en moins ... jusqu'à la N des clusters, des longueurs de tous les 0."Le pourcentage de la variance expliquée" est à 100% à cette moyenne.
Code, sous est-il-possible-de-indiquez-votre-propre-distance-fonction-aide-scikits-apprendre-k-means:
Comme n'importe quel longue liste de chiffres, ces distances peuvent être regardé de diverses manières: np.moyenne(), np.histogramme() ... Tracé, la visualisation n'est pas facile.
Voir aussi stats.stackexchange.com/questions/tagged/clustering, en particulier
Comment savoir si les données sont “cluster” assez pour les algorithmes de clustering pour obtenir des résultats significatifs?