51 votes

tracer les résultats d'un clustering hiérarchique au-dessus d'une matrice de données en python

Comment puis-je tracer un dendrogramme juste au-dessus d'une matrice de valeurs, réordonnée de manière appropriée pour refléter le regroupement, en Python ? Un exemple se trouve en bas de la figure suivante :

http://www.coriell.org/images/microarray.gif

J'utilise scipy.cluster.dendrogram pour créer mon dendrogramme et effectuer un clustering hiérarchique sur une matrice de données. Comment puis-je ensuite tracer les données sous la forme d'une matrice dont les lignes ont été réorganisées pour refléter un regroupement induit par la coupure du dendrogramme à un seuil particulier, et avoir le dendrogramme tracé à côté de la matrice ? Je sais comment tracer le dendrogramme dans scipy, mais pas comment tracer la matrice d'intensité des données avec la bonne barre d'échelle à côté.

Toute aide à ce sujet serait grandement appréciée.

98voto

Steve Tjoa Points 15116

La question ne définit pas matrice très bien : "matrice de valeurs", "matrice de données". Je suppose que vous voulez dire une matrice de distance . En d'autres termes, l'élément D_ij dans le modèle symétrique non négatif N-by-N matrice de distance D représente la distance entre deux vecteurs de caractéristiques, x_i et x_j. Est-ce correct ?

Si oui, essayez ceci (édité le 13 juin 2010, pour refléter deux dendrogrammes différents) :

import scipy
import pylab
import scipy.cluster.hierarchy as sch

# Generate random features and distance matrix.
x = scipy.rand(40)
D = scipy.zeros([40,40])
for i in range(40):
    for j in range(40):
        D[i,j] = abs(x[i] - x[j])

# Compute and plot first dendrogram.
fig = pylab.figure(figsize=(8,8))
ax1 = fig.add_axes([0.09,0.1,0.2,0.6])
Y = sch.linkage(D, method='centroid')
Z1 = sch.dendrogram(Y, orientation='right')
ax1.set_xticks([])
ax1.set_yticks([])

# Compute and plot second dendrogram.
ax2 = fig.add_axes([0.3,0.71,0.6,0.2])
Y = sch.linkage(D, method='single')
Z2 = sch.dendrogram(Y)
ax2.set_xticks([])
ax2.set_yticks([])

# Plot distance matrix.
axmatrix = fig.add_axes([0.3,0.1,0.6,0.6])
idx1 = Z1['leaves']
idx2 = Z2['leaves']
D = D[idx1,:]
D = D[:,idx2]
im = axmatrix.matshow(D, aspect='auto', origin='lower', cmap=pylab.cm.YlGnBu)
axmatrix.set_xticks([])
axmatrix.set_yticks([])

# Plot colorbar.
axcolor = fig.add_axes([0.91,0.1,0.02,0.6])
pylab.colorbar(im, cax=axcolor)
fig.show()
fig.savefig('dendrogram.png')

Dendrogram and distance matrix

Bonne chance ! Faites-moi savoir si vous avez besoin d'aide supplémentaire.


Edit : Pour des couleurs différentes, ajustez le cmap l'attribut dans imshow . Voir le docs scipy/matplotlib par exemple. Cette page décrit également comment créer votre propre carte de couleurs. Pour des raisons pratiques, je recommande d'utiliser une carte de couleurs préexistante. Dans mon exemple, j'ai utilisé YlGnBu .


Edit : add_axes ( voir la documentation ici ) accepte une liste ou un tuple : (left, bottom, width, height) . Par exemple, (0.5,0,0.5,1) ajoute un Axes sur la moitié droite de la figure. (0,0.5,1,0.5) ajoute un Axes sur la moitié supérieure de la figure.

La plupart des gens utilisent probablement add_subplot pour sa commodité. J'aime add_axes pour son contrôle.

Pour supprimer la bordure, utilisez add_axes([left,bottom,width,height], frame_on=False) . Voir l'exemple ici.

9voto

Picarus Points 298

Si en plus de la matrice et du dendrogramme il est nécessaire de montrer les étiquettes des éléments, le code suivant peut être utilisé, qui montre toutes les étiquettes en faisant tourner les étiquettes x et en changeant la taille de la police pour éviter le chevauchement sur l'axe x. Il faut déplacer la barre de couleur pour avoir de la place pour les étiquettes y :

axmatrix.set_xticks(range(40))
axmatrix.set_xticklabels(idx1, minor=False)
axmatrix.xaxis.set_label_position('bottom')
axmatrix.xaxis.tick_bottom()

pylab.xticks(rotation=-90, fontsize=8)

axmatrix.set_yticks(range(40))
axmatrix.set_yticklabels(idx2, minor=False)
axmatrix.yaxis.set_label_position('right')
axmatrix.yaxis.tick_right()

axcolor = fig.add_axes([0.94,0.1,0.02,0.6])

Le résultat obtenu est le suivant (avec une carte de couleurs différente) :

The result obtained is this:

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X