python - ¿Cómo obtengo los subárboles de dendrograma hechos por scipy.cluster.hierarchy?
python-2.7 numpy (1)
Respondiendo a la parte de tu pregunta sobre la manipulación de árboles ...
Como se explica en otra respuesta , puede leer las coordenadas de las ramas que leen icoord
y dcoord
desde el objeto del árbol. Para cada rama los coordinados se dan de izquierda a derecha.
Si quieres trazar manualmente el árbol puedes usar algo como:
def plot_tree(P, pos=None):
plt.clf()
icoord = scipy.array(P[''icoord''])
dcoord = scipy.array(P[''dcoord''])
color_list = scipy.array(P[''color_list''])
xmin, xmax = icoord.min(), icoord.max()
ymin, ymax = dcoord.min(), dcoord.max()
if pos:
icoord = icoord[pos]
dcoord = dcoord[pos]
color_list = color_list[pos]
for xs, ys, color in zip(icoord, dcoord, color_list):
plt.plot(xs, ys, color)
plt.xlim(xmin-10, xmax + 0.1*abs(xmax))
plt.ylim(ymin, ymax + 0.1*abs(ymax))
plt.show()
Donde, en su código, plot_tree(P)
da:
La función le permite seleccionar sólo algunas ramas:
plot_tree(P, range(10))
Ahora tienes que saber qué ramas trazar. Tal vez la salida de fcluster()
sea un poco oscura y otra forma de encontrar qué ramas para trazar basadas en una tolerancia de distancia mínima y máxima sería usar la salida de linkage()
directamente ( Z
en el caso del OP):
dmin = 0.2
dmax = 0.3
pos = scipy.all( (Z[:,2] >= dmin, Z[:,2] <= dmax), axis=0 ).nonzero()
plot_tree( P, pos )
Referencias recomendadas:
- ¿Cómo funciona la matriz de distancia condensada? (pdist)
- cómo trazar y anotar dendrogramas de agrupamiento jerárquico en scipy / matplotlib
Tuve una confusión con respecto a este módulo (scipy.cluster.hierarchy) ... ¡y aún tengo algunos!
Por ejemplo tenemos el siguiente dendrograma:
Mi pregunta es ¿cómo puedo extraer los subárboles de color (cada uno representa un grupo) en un formato agradable, por ejemplo, formato SIF? Ahora el código para obtener el gráfico anterior es:
import scipy
import scipy.cluster.hierarchy as sch
import matplotlib.pylab as plt
scipy.randn(100,2)
d = sch.distance.pdist(X)
Z= sch.linkage(d,method=''complete'')
P =sch.dendrogram(Z)
plt.savefig(''plot_dendrogram.png'')
T = sch.fcluster(Z, 0.5*d.max(), ''distance'')
#array([4, 5, 3, 2, 2, 3, 5, 2, 2, 5, 2, 2, 2, 3, 2, 3, 2, 5, 4, 5, 2, 5, 2,
# 3, 3, 3, 1, 3, 4, 2, 2, 4, 2, 4, 3, 3, 2, 5, 5, 5, 3, 2, 2, 2, 5, 4,
# 2, 4, 2, 2, 5, 5, 1, 2, 3, 2, 2, 5, 4, 2, 5, 4, 3, 5, 4, 4, 2, 2, 2,
# 4, 2, 5, 2, 2, 3, 3, 2, 4, 5, 3, 4, 4, 2, 1, 5, 4, 2, 2, 5, 5, 2, 2,
# 5, 5, 5, 4, 3, 3, 2, 4], dtype=int32)
sch.leaders(Z,T)
# (array([190, 191, 182, 193, 194], dtype=int32),
# array([2, 3, 1, 4,5],dtype=int32))
Así que ahora, la salida de fcluster()
proporciona el agrupamiento de nodos (por su ID), y los leaders()
descritos here deben devolver 2 matrices:
el primero contiene los nodos líderes de los clústeres generados por Z, aquí podemos ver que tenemos 5 clústeres, así como en la gráfica
y el segundo el id de estos clusters.
Así que si este líderes () devuelve resp. L y M: L[2]=182
y M[2]=1
, luego el grupo 1 está liderado por el nodo id 182, que no existe en el conjunto de observaciones X, la documentación dice que "... entonces corresponde a un clúster no singleton ". Pero no lo consigo ...
Además, convertí la Z en un árbol mediante sch.to_tree(Z)
, que devolverá un objeto de árbol fácil de usar, que quiero visualizar, pero qué herramienta debería usar como plataforma gráfica que manipule este tipo de los objetos del arbol como entradas?