Réorganiser les éléments de matrice pour refléter le clustering de colonnes et de lignes dans naiive python

Je cherche un moyen d'effectuer le clustering séparément sur les lignes de la matrice et que sur ses colonnes, réorganiser les données dans la matrice pour refléter le clustering et tout mettre ensemble. Le problème de clustering est facilement résolu, tout comme la création de dendrogramme (par exemple dans ce blog ou dans "Programming collective intelligence" ). Cependant, comment réorganiser les données reste peu clair pour moi.

Finalement, je cherche un moyen de créer des graphiques similaires à celui ci-dessous en utilisant Python naïf (avec n'importe quelle bibliothèque "standard" telle que numpy, matplotlib etc, mais sans en utilisant R ou d'autres outils externes).

Dendogramme http://www2.warwick.ac.uk/fac/sci/moac/currentstudents/peter_cock/r/heatmap/no_scaling.png

Précisions

On m'a demandé ce que je voulais dire par réorganiser. Lorsque vous regroupez des données dans une matrice d'abord par des lignes de matrice, puis par ses colonnes, chaque cellule de matrice peut être identifiée par la position dans les deux dendrograms. Si vous réorganisez les lignes et les colonnes de la matrice d'origine de sorte que les éléments qui sont proches les uns des autres dans les dendrogrammes deviennent proches les uns des autres dans la matrice, puis génèrent heatmap, le clustering des données peut devenir évident pour le spectateur (comme dans la figure ci-dessus)

24
demandé sur Boris Gorelik 2010-03-16 18:39:32

3 réponses

Voir mon récente réponse, copié en partie ci-dessous, à cette question connexe.

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

# Generate 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 dendrogram.
fig = pylab.figure()
axdendro = fig.add_axes([0.09,0.1,0.2,0.8])
Y = sch.linkage(D, method='centroid')
Z = sch.dendrogram(Y, orientation='right')
axdendro.set_xticks([])
axdendro.set_yticks([])

# Plot distance matrix.
axmatrix = fig.add_axes([0.3,0.1,0.6,0.8])
index = Z['leaves']
D = D[index,:]
D = D[:,index]
im = axmatrix.matshow(D, aspect='auto', origin='lower')
axmatrix.set_xticks([])
axmatrix.set_yticks([])

# Plot colorbar.
axcolor = fig.add_axes([0.91,0.1,0.02,0.8])
pylab.colorbar(im, cax=axcolor)

# Display and save figure.
fig.show()
fig.savefig('dendrogram.png')

Dendrogramme et matrice de distance http://up.stevetjoa.com/dendrogram.png

39
répondu Steve Tjoa 2017-05-23 12:18:24

Je ne suis pas sûr de comprendre complètement, mais il semble que vous essayez de ré-indexer chaque axe du tableau en fonction des types d'indices dendrogramme. Je suppose que cela suppose qu'il y a une logique comparative dans chaque délimitation de branche. Si tel est le cas, cela fonctionnerait-il(?):

>>> x_idxs = [(0,1,0,0),(0,1,1,1),(0,1,1),(0,0,1),(1,1,1,1),(0,0,0,0)]
>>> y_idxs = [(1,1),(0,1),(1,0),(0,0)]
>>> a = np.random.random((len(x_idxs),len(y_idxs)))
>>> x_idxs2, xi = zip(*sorted(zip(x_idxs,range(len(x_idxs)))))
>>> y_idxs2, yi = zip(*sorted(zip(y_idxs,range(len(y_idxs)))))
>>> a2 = a[xi,:][:,yi]

x_idxs et y_idxs sont les indices dendrogrammes. {[3] } est la matrice non triée. xi et yi sont vos nouveaux indices de tableau de lignes / colonnes. a2 est la matrice triée tandis que x_idxs2 et y_idxs2 sont les nouveaux, indices dendrogrammes triés. Cela suppose que lorsque le dendrogramme a été créé, une colonne/ligne de branche 0 est toujours comparativement plus grande/plus petite qu'une branche 1.

Si vos y_idxs et x_idxs ne sont pas des listes mais des tableaux numpy, vous pouvez utiliser np.argsort de la même manière.

5
répondu Paul 2010-03-18 03:59:58

Je sais que c'est très tard pour le jeu, mais j'ai fait un objet de traçage basé sur le code du post sur cette page. Il est enregistré sur pip, donc pour installer, il vous suffit d'appeler

pip install pydendroheatmap

Consultez la page Github du projet ici: https://github.com/themantalope/pydendroheatmap

2
répondu themantalope 2015-07-14 04:20:11