2016-07-15 13 views
0

Ich mache jetzt Clustering auf Python mit from scipy.cluster.hierarchy import linkage Aus dem Handbuch weiß ich, dass es Ergebnis in dieser Form gibt -> [A, B, Länge, #] welche A und B ist die Indizes der Elemente, die gehen in dieser ... Stufe (?) zu verschmelzen, aber kann ich Informationen über Cluster erhalten, die bereits verschmolzen sind, aber nicht in dieser Phase teilnehmen?Wie kann ich alle aktuellen Cluster auflisten, wenn Sie einen einzigen Verknüpfungsalgorithmus verwenden?

Zum Beispiel mein Dataset

A=[[1,1],[1,2],[1,3],[1,4],[1,5], [10,1],[10,2],[10,3],[10,4],[10,5], [15,1],[15,2],[15,3],[15,4],[15,5], [30,1],[30,2],[30,3],[30,4],[30,5]]

und Single-Linkage-Algorithmus anwenden auf sie

Z = linkage(A, 'single') 

Z=[[ 0. 4. 1. 2.] 
    [ 1. 20. 1. 3.] 
    [ 2. 21. 1. 4.] 
    [ 3. 22. 1. 5.] 
    [ 17. 19. 1. 2.] 
    [ 5. 9. 1. 2.] 
    [ 6. 25. 1. 3.] 
    [ 7. 26. 1. 4.] 
    [ 8. 27. 1. 5.] 
    [ 18. 24. 1. 3.] 
    [ 10. 14. 1. 2.] 
    [ 11. 30. 1. 3.] 
    [ 12. 31. 1. 4.] 
    [ 13. 32. 1. 5.] 
    [ 16. 29. 1. 4.] 
    [ 15. 34. 1. 5.] 
    [ 28. 33. 5. 10.] 
    [ 23. 36. 9. 15.] 
    [ 35. 37. 15. 20.]] 

hier I 5 wählen die Entfernungsbeschränkung in Clustern zu sein, so dass ich

[ 28. 33. 5. 10.]

dann zurückverfolgt I 28 und 33 wieder auf die ursprünglichen Indizes

cut = 5 
temp1 = [] 
temp2 = [] 
for i in range(len(Z)): 
if Z[i][2] >= cut: 
    temp1.append(Z[i]) 
for i in range(2): 
    temp2[i].append(int(temp1[0][i])) 
for j in range(0, len(temp2)): 
try: 
    g = max(temp2[j]) 
except: 
    continue 
G = int(g - len(A)) 
while g >= len(A): 
    ind = temp2[j].index(g) 
    temp2[j].append(int(Z[G][0])) 
    temp2[j].append(int(Z[G][1])) 
    del temp2[j][ind] 
    g = max(temp2[j]) 
    G = int(g - len(A)) 

und stellte fest, dass

temp2 = [[8, 7, 6, 5, 9], [13, 12, 11, 10, 14]] 

was bedeutet, ‚28‘ steht für Punkte [10,1],[10,2],[10,3],[10,4],[10,5] und ‚33‘ steht für Punkte [15,1],[15,2],[15,3],[15,4],[15,5], was klar bedeutet, dass der Cluster aus [10, x] besteht und der Cluster aus [15, x] in dieser Phase zusammengeführt wird.

Aber offensichtlich [1,1],[1,2],[1,3],[1,4],[1,5] und [30,1],[30,2],[30,3],[30,4],[30,5] müssen zwei weitere Cluster in früheren Stufe gebildet haben, so im Moment vor [10, x] und [15, x] fusionieren, zur Zeit gibt es 4 Cluster

So das Ergebnis I Wollen ist wie

temp2 = [[8, 7, 6, 5, 9], [13, 12, 11, 10, 14], [0, 1, 2, 3, 4], [15, 16, 17, 18, 19]] 

Was soll ich tun, um die späteren zwei Cluster T^T ?? Vielen Dank im fortgeschrittenen QQ

Antwort

1

Wie in the documentation beschrieben, linkage gibt Ihnen den Abstand zwischen den Clustern, die zwischen den Elementen in diesen Clustern gleich den cophenetic Abstand ist. Wie in other documentation beschrieben, gibt fcluster flache Cluster, und wenn Sie 'distance' als Kriterium angeben, wird das Dendrogramm entsprechend der koptilene Entfernung geschnitten.

So können Sie bekommen, was Sie wollen, indem Sie fcluster verwenden, um die Cluster in der gewählten Entfernung zu schwellen. Eine leichte Falte ist jedoch, dass fcluster die Schwelle als die höchste Entfernung zu Klumpen behandelt, nicht die niedrigste zu teilende Distanz. Wenn Sie also 5 als Schwelle verwenden, wird sie den beiden Clustern, auf die Sie sich beziehen, und nur drei Clustern zugeordnet . Sie müssen einen Schwellenwert etwas weniger als 5 wählen, um zu bekommen, was Sie wollen. Zum Beispiel:

from scipy.cluster import hierarchy as clust 
>>> clust.fcluster(Z, 4.99999, criterion='distance') 
array([2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 1, 1, 1, 1, 1]) 

Hier erfahren Sie, in welchem ​​Cluster sich jedes Element befindet.Zu übersetzen, die zurück in den Listen des Indizes in jedem Cluster, könnten Sie np.where:

>>> clusters = clust.fcluster(Z, 4.99999, criterion='distance') 
>>> [np.where(clusters==k)[0].tolist() for k in np.unique(clusters)] 
[[15L, 16L, 17L, 18L, 19L], 
[0L, 1L, 2L, 3L, 4L], 
[5L, 6L, 7L, 8L, 9L], 
[10L, 11L, 12L, 13L, 14L]] 

In Summe, die Idee zu sehen ist, was Sie nennen die „Entfernungsbeschränkung“ und verwenden fclust zu flache Cluster erhalten mit diese Entfernung (oder eher eine etwas kleinere Entfernung) als die Schwelle. Dadurch erhalten Sie die Clusternummer jedes Indexes, und Sie können np.where verwenden, um eine Liste für jeden Cluster abzurufen.

+0

Vielen Dank !!!!!! Das ist genau was ich suche T^T BTW, es ist keine Frage nur ich bin neugierig, was sind diese L in Ihrer letzten Ausgabe für? Ich habe diese L in meinem Ergebnis nicht bekommen (und es ist gut, aber) – Chu

+0

@Xiadan: Diese zeigen eine "lange ganze Zahl" an. Es ist nur ein Haufen Müll, der hineingeworfen wird, wenn ich das numpy Array in eine Liste umwandle. Es wird wahrscheinlich nicht für Sie angezeigt, wenn Sie auf Python 3 sind und auch nicht abhängig von anderen Plattformdetails (wie 64- vs 32-Bit) erscheinen. Wie Sie jedoch festgestellt haben, hat dies keine Auswirkungen auf das Ergebnis. es sieht einfach komisch aus. – BrenBarn

+0

Und auch danke für den np.where Teil T^T Ich wusste, dass es eine schlauere Art geben muss, das zurück in Listen der Indizes zu übersetzen. – Chu