Reordenación de los elementos de matriz para reflejar la columna y la fila de agrupación en pitón naiive

StackOverflow https://stackoverflow.com/questions/2455761

Pregunta

Estoy buscando una forma de realizar la agrupación por separado en las filas de la matriz y que en sus columnas, cambiar el orden de los datos en la matriz para reflejar el agrupamiento y ponerlo todo junto. El problema de agrupamiento es fácilmente soluble, por lo que es la creación dendrograma (por ejemplo en este blog o en " Programación de inteligencia colectiva "). Sin embargo, la forma de reordenar los datos aún no está claro para mí.

Con el tiempo, estoy buscando una manera de crear gráficos similares a la de abajo usando Python ingenua (con cualquier biblioteca "estándar" como numpy, matplotlib etc, pero sin usando R u otras herramientas externas).

dendrograma
(fuente: Warwick. ac.uk )

Aclaraciones

Me preguntaron qué quería decir con reordenamiento. Cuando clúster de datos en una primera matriz por filas de la matriz, a continuación, por sus columnas, cada celda de la matriz puede ser identificado por la posición en los dos dendrogramas. Si reordena las filas y las columnas de la matriz original de tal manera que los elementos que están cerca cada uno a otro en los dendrogramas se convierten cerrar cada a otro en la matriz, y luego generar heatmap, la agrupación de los datos puede llegar a ser evidente para el espectador (como en la figura anterior)

¿Fue útil?

Solución

Vea mi reciente respuesta, copiados en parte a continuación, esta pregunta relacionada .

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')

dendrograma y la matriz de distancia
(fuente: stevetjoa.com )

Otros consejos

No estoy seguro de entender completamente, pero parece que está intentando volver a indexar cada eje de la matriz sobre la base de los índices del tipo de dendrograma. Supongo que se supone hay cierta lógica comparativa en cada delineación rama. Si este es el caso, entonces funcionaría esto (?):

>>> 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 y y_idxs son los índices del dendrograma. a es la matriz sin clasificar. xi y yi son sus nuevos índices del array de fila / columna. a2 es la matriz ordenada mientras x_idxs2 y y_idxs2 son los nuevos, indicies dendrograma según. Esto supone que cuando se creó el dendrograma que una rama 0 columna / fila siempre es comparativamente mayor / menor que una rama 1.

Si sus y_idxs y x_idxs no están listas, pero son matrices numpy, entonces se podría utilizar np.argsort de una manera similar.

Sé que esto es muy tarde para el juego, pero he hecho un objeto de trazado basado en el código del poste en esta página. Está registrada en el PIP, por lo que la instalación sólo tiene que llamar

pip install pydendroheatmap

echa un vistazo a la página GitHub del proyecto aquí: https://github.com/themantalope/pydendroheatmap

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top