Riordino elementi di matrice per riflettere colonna e riga clustering in pitone naiive
-
20-09-2019 - |
Domanda
Sto cercando un modo per eseguire il clustering separatamente su righe della matrice e che sulle sue colonne, riordinare i dati nella matrice in modo da riflettere il clustering e mettere tutto insieme. Il problema di clustering è facilmente risolvibile, quindi è la creazione dendrogramma (per esempio in questo blog o in " Programmazione intelligenza collettiva "). Tuttavia, come per riordinare i dati ancora chiaro per me.
Alla fine, sto cercando un modo di creare grafici simili a quello di seguito utilizzando Python ingenuo (con qualsiasi libreria "standard", come NumPy, matplotlib ecc, ma senza utilizzando altri strumenti esterni R o).
(fonte: Warwick. ac.uk )
Chiarimenti
Mi è stato chiesto cosa intendevo per riordino. Quando si raggruppa i dati in una matrice per righe prima matrice, poi da colonne, ciascuna cella di matrice può essere identificato dalla posizione nelle due dendrogrammi. Se si riordinano le righe e le colonne della matrice originale in modo tale che gli elementi che sono vicino a ciascuno di loro nelle dendrogrammi diventano chiudere ciascuna all'altro nella matrice, e quindi generare heatmap, il raggruppamento dei dati può verificarsi al visualizzatore (come nella figura precedente)
Soluzione
Vedere il mio recente risposta, copiato in parte sottostante, questa domanda relativa .
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')
(fonte: stevetjoa.com )
Altri suggerimenti
Non sono sicuro di capire completamente, ma sembra che si sta cercando di ri-index ogni asse della matrice in base a una serie dei indicies Dendrogram. Credo che assume c'è una logica comparativa in ogni ramo delineazione. Se questo è il caso, allora sarebbe questo lavoro (?):
>>> 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
e y_idxs
sono i indicies Dendrogram. a
è la matrice non ordinato. xi
e yi
sono i tuoi nuovi indicies matrice riga / colonna. a2
è la matrice ordinata mentre x_idxs2
e y_idxs2
sono i nuovi, indicies Dendrogram filtrate. Questo presuppone che quando il dendrogramma che è stato creato un ramo 0
colonna / riga è sempre comparativamente maggiore / minore di un ramo 1
.
Se i vostri y_idxs e x_idxs non sono liste, ma sono array NumPy, allora si potrebbe utilizzare np.argsort
in un modo simile.
So che questo è molto in ritardo al gioco, ma ho fatto un oggetto di tracciare in base al codice del post su questa pagina. E 'iscritto sulla pip, in modo da installare basta chiamare
pip install pydendroheatmap
controllare la pagina GitHub del progetto qui: https://github.com/themantalope/pydendroheatmap