J'ai des données, pour lesquelles je crée un modèle de liaison, comme ceci:

model = sc.linkage(data, 'ward')

Où le modèle est le suivant:

Z = np.array([
   [  2.        ,   9.        ,  20.12172148,   2.        ],
   [  0.        ,   1.        ,  26.16772232,   2.        ],
   [ 11.        ,  12.        ,  29.40258214,   2.        ],
   [ 14.        ,  16.        ,  30.89332011,   3.        ],
   [  3.        ,   7.        ,  33.70695832,   2.        ],
   [  5.        ,  13.        ,  34.22180543,   2.        ],
   [  4.        ,  15.        ,  35.52080322,   3.        ],
   [ 17.        ,  21.        ,  45.3919152 ,   5.        ],
   [  6.        ,  20.        ,  45.56339627,   3.        ],
   [  8.        ,  23.        ,  66.42828305,   4.        ],
   [ 10.        ,  22.        ,  87.52531145,   6.        ],
   [ 18.        ,  24.        ,  93.78070161,   7.        ],
   [ 19.        ,  26.        , 124.09967826,   9.        ],
   [ 25.        ,  27.        , 160.11685636,  15.        ]])
   Z == model # returns true

Je peux ensuite tracer ce modèle de liaison en utilisant matplotlib:

# calculate full dendrogram
plt.figure(figsize=(25, 10))
plt.title('Hierarchical Clustering Dendrogram for signature data')
plt.xlabel('sample index')
plt.ylabel('distance')
sc.dendrogram(
    model,
    leaf_rotation=90.,  # rotates the x axis labels
    leaf_font_size=8.,  # font size for the x axis labels
)
plt.show()

enter image description here

Maintenant, cela trace le dendrogramme et définit les xticks sur l'index. Je voudrais remplacer cela par de véritables étiquettes, qui sont

labels = ['wood', 'stone', 'flora', 'liquid', 'food', 'metal', 'ceramic', 
          'sky', 'glass', 'paper', 'animal', 'skin', 'fabrics', 'gem', 'ground']

Comme dans, la première coche sur l'axe des abscisses indique 10. Ce serait des étiquettes [10]. Cependant, je ne peux pas savoir comment accéder à cet index.

0
Mitchell van Zuylen 18 mars 2019 à 13:13

2 réponses

Meilleure réponse

Il n'est pas nécessaire d'accéder à l'index. scipy.cluster.hierarchy.dendrogram fournit un argument labels que vous devez utiliser pour fournir vos étiquettes.

scipy.cluster.hierarchy.dendrogram(Z, labels=labels, ....)

Code complet:

import numpy as np
import scipy.cluster.hierarchy as sc
import matplotlib.pyplot as plt

Z = np.array([
   [  2.        ,   9.        ,  20.12172148,   2.        ],
   [  0.        ,   1.        ,  26.16772232,   2.        ],
   [ 11.        ,  12.        ,  29.40258214,   2.        ],
   [ 14.        ,  16.        ,  30.89332011,   3.        ],
   [  3.        ,   7.        ,  33.70695832,   2.        ],
   [  5.        ,  13.        ,  34.22180543,   2.        ],
   [  4.        ,  15.        ,  35.52080322,   3.        ],
   [ 17.        ,  21.        ,  45.3919152 ,   5.        ],
   [  6.        ,  20.        ,  45.56339627,   3.        ],
   [  8.        ,  23.        ,  66.42828305,   4.        ],
   [ 10.        ,  22.        ,  87.52531145,   6.        ],
   [ 18.        ,  24.        ,  93.78070161,   7.        ],
   [ 19.        ,  26.        , 124.09967826,   9.        ],
   [ 25.        ,  27.        , 160.11685636,  15.        ]])

labels = ['wood', 'stone', 'flora', 'liquid', 'food', 'metal', 'ceramic', 
          'sky', 'glass', 'paper', 'animal', 'skin', 'fabrics', 'gem', 'ground']

# calculate full dendrogram
plt.figure()
plt.title('Hierarchical Clustering Dendrogram for signature data')
plt.xlabel('sample index')
plt.ylabel('distance')
sc.dendrogram(
    Z,
    labels=labels,
    leaf_rotation=90.,  # rotates the x axis labels
    leaf_font_size=8.,  # font size for the x axis labels
)
plt.tight_layout()
plt.show()

enter image description here

2
ImportanceOfBeingErnest 18 mars 2019 à 11:19

Je n'ai pas de module de dendogramme mais ce qui suit devrait fonctionner pour vous. L'idée est:

  • Créez une instance d'axe ax et passez-la au tracé dendogram comme argument d'axe
  • Obtenez les x-ticklabels existants et convertissez-les en entiers. Utilisez ces entiers comme indices pour accéder aux valeurs de labels. C'est juste pour avoir les étiquettes dans l'ordre comme vous voulez qu'elles soient affichées sur l'axe des x
  • Définissez ces nouvelles étiquettes à l'aide de set_xticklabels

Voici le code pertinent que vous pouvez utiliser

fig, ax = plt.subplots(figsize=(25, 10))

sc.dendrogram(
    model,
    leaf_rotation=90.,  
    leaf_font_size=8.,  ax=ax)

fig.canvas.draw()

new_labels = [labels[int(i.get_text())] for i in ax.get_xticklabels()]
ax.set_xticklabels(new_labels)
0
Sheldore 18 mars 2019 à 10:45