web-dev-qa-db-fra.com

Utiliser la matrice de distance dans scipy.cluster.hierarchy.linkage ()?

J'ai une matrice de distance n * n MM_ij Est la distance entre object_i Et object_j. Donc, comme prévu, il prend la forme suivante:

   /  0     M_01    M_02    ...    M_0n\
   | M_10    0      M_12    ...    M_1n |
   | M_20   M_21     0      ...    M2_n |
   |                ...                 |
   \ M_n0   M_n2    M_n2    ...      0 / 

Maintenant, je souhaite regrouper ces n objets avec un regroupement hiérarchique. Python a une implémentation de cette appelée scipy.cluster.hierarchy.linkage(y, method='single', metric='euclidean').

Sa documentation dit:

y doit être un vecteur de taille {n\choose 2} où n est le nombre d'observations originales appariées dans la matrice de distance.

y: ndarray

Une matrice de distance condensée ou redondante. Une matrice de distance condensée est un réseau plat contenant la triangulaire supérieure de la matrice de distance. C'est la forme que retourne pdist. Alternativement, une collection de m vecteurs d'observation en n dimensions peut être passée sous la forme d'un tableau m par n.

Je suis confus par cette description de y. Puis-je alimenter directement mon M en entrée y?


Mise à jour

@ hongbo-zhu-cn a soulevé ce problème dans GitHub . C'est exactement ce qui me préoccupe. Cependant, en tant que novice de GitHub, je ne sais pas comment cela fonctionne et je n'ai donc aucune idée de la façon dont ce problème est traité.

38
Sibbs Gambling

Il semble qu'en effet, nous ne pouvons pas passer directement la matrice carrée redondante, bien que la documentation affirme que nous pouvons le faire.

Pour bénéficier à toute personne confrontée au même problème à l'avenir, j'écris ma solution comme réponse supplémentaire ici. Ainsi, les gars du copier-coller peuvent simplement procéder au clustering.

Utilisez l'extrait de code suivant pour condenser la matrice et continuer avec plaisir.

import scipy.spatial.distance as ssd
# convert the redundant n*n square matrix form into a condensed nC2 array
    distArray = ssd.squareform(distMatrix) # distArray[{n choose 2}-{n-i choose 2} + (j-i-1)] is the distance between points i and j

S'il vous plait corrigez moi si je me trompe.

41
Sibbs Gambling

Pour l'instant, vous devez passer dans la `` matrice de distance condensée '', c'est-à-dire juste le triangle supérieur de la matrice de distance sous forme vectorielle:

y = M[np.triu_indices(n,1)]

De la discussion de la requête pull de @ hongbo-zhu-cn il semble que la solution sera d'ajouter un argument de mot clé supplémentaire à la fonction linkage qui permettra à l'utilisateur de spécifier explicitement qu'ils passent dans une matrice de distance nxn plutôt qu'une observation mxn matrice.

10
ali_m