2013-06-02 8 views
14

Ho avuto una confusione riguardo a questo modulo (scipy.cluster.hierarchy) ... e ne ho ancora un po '!come faccio a ottenere le sottostrutture del dendrogramma fatte da scipy.cluster.hierarchy

Per esempio abbiamo la seguente dendrogramma:

hierarchical clustering

mia domanda è come posso estrarre le sottostrutture colorate (ognuno rappresenta un cluster) in un bel formato, diciamo formato SIF? Ora il codice per ottenere la trama sopra è:

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

Così ora, l'uscita del fcluster() dà il raggruppamento dei nodi (dal loro id), e leaders() descritto here deve restituire 2 array:

  • primo contiene i nodi leader del cluster generati da Z, qui possiamo vedere che abbiamo 5 grappoli, così come nella trama

  • e la seconda i id di questi gruppi

Quindi se questo leader() restituisce resp. L e M: L[2]=182 e M[2]=1, quindi il cluster 1 è guidato dal nodo id 182, che non esiste nel set di osservazioni X, la documentazione dice "... quindi corrisponde a un cluster non singleton". Ma non riesco a ottenerlo ...

Inoltre, ho convertito la Z in un albero di sch.to_tree(Z), che restituirà un oggetto ad albero facile da usare, che voglio visualizzare, ma quale strumento dovrei usare come piattaforma grafica che manipola questo tipo di oggetti dell'albero come input?

risposta

19

Rispondendo alla parte della tua domanda per quanto riguarda la manipolazione albero ...

Come spiegato in aother answer, è possibile leggere le coordinate dei rami di lettura icoord e dcoord dall'oggetto albero. Per ogni ramo i coordinati sono dati da sinistra a destra.

Se si desidera tracciare manualmente l'albero si può usare qualcosa di simile a:

def plot_tree(P, pos=None): 
    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() 

Dove, nel codice, plot_tree(P) dà:

enter image description here

La funzione consente di selezionare solo alcuni rami:

plot_tree(P, range(10)) 

enter image description here

Ora devi sapere quali rami tracciare.Forse l'uscita fcluster() è un po 'oscura e un altro modo di trovare che si dirama per tracciare sulla base di una una tolleranza massima distanza minima e sarebbe utilizzando l'uscita di linkage() direttamente (Z nel caso del PO):

dmin = 0.2 
dmax = 0.3 
pos = scipy.all((Z[:,2] >= dmin, Z[:,2] <= dmax), axis=0).nonzero() 
plot_tree(P, pos) 

consigliati riferimenti:

+2

Questo risp mi ha aiutato ad arrivare dove avrei potuto tracciare sottoalberi del dendrogramma con osservazioni trovate all'interno di una data distanza fenetica (PD). Non ho trovato i metodi fcluster o fclusterdata utili per questo. Ho usato sch.to_tree (linkage) .pre_order(), quindi ho testato in sequenza gli elementi adiacenti in quell'elenco per essere all'interno del PD in riferimento alla matrice distanza pdist (vedi http://stackoverflow.com/a/17870926/1876324), poi ricalcolato distanza, linkage e dendrogramma per ogni gruppo che volevo tracciare. Un PD di 4, ad esempio, raggrupperebbe i dati OP nei 3 sottoalberi desiderati. –