2016-07-15 51 views
0

我現在正在做python集羣使用from scipy.cluster.hierarchy import linkage 從手冊我知道,它給這種形式的結果 - > [A,B,長度,#] 其中A和B是要去的元素的索引在這個階段(?)中合併,但是我可以獲得關於已經合併但不參與此階段的集羣的任何信息嗎?如何在使用單個連接算法時列出當前所有的羣集?

例如,我的數據集是

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

,並在其上

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.]] 

這裏我選擇5是在集羣的距離限制申請單鏈接算法,所以我得到

[ 28. 33. 5. 10.]

然後我追查28和33返回到原始索引

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

,發現

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

這意味着「28」代表點[10,1],[10,2],[10,3],[10,4],[10,5]和「33」代表點[15,1],[15,2],[15,3],[15,4],[15,5],這顯然意味着該集羣由[10,x]組成,並且由[15,x]組成的集羣將在此階段合併。

但顯然[1,1],[1,2],[1,3],[1,4],[1,5][30,1],[30,2],[30,3],[30,4],[30,5]必須在早期階段,已經形成了另外兩個集羣,所以此刻的前[10,X]和[15,X]合併,目前有4類

所以結果我想要就像

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

我應該怎麼做才能得到後面的兩個簇T^T? 感謝高級QQ

回答

1

the documentation,linkage中所述,給出了簇之間的距離,這與簇中元素之間的複合距離相同。如other documentation中所述,fcluster將爲您提供平面簇,並且如果您指定'distance'作爲標準,則會根據共同距離來切割樹形圖。

所以你可以通過使用fcluster來獲得你想要的值,以便在你選擇的距離上對簇進行閾值。然而,一個小小的摺痕是,fcluster將閾值視爲最大距離,而不是最低距離,所以如果您使用5作爲閾值,它會加入您所指的兩個羣集,並只給出三個羣集。你必須選擇一個略低於5的閾值才能得到你想要的。例如:

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

這是告訴你每個項目在哪個羣集中。把這一回在每個簇索引列表,你可以使用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]] 

總之,這個想法是看你所說的「距離限制」,並使用fclust獲得與平板集羣該距離(或者說,稍小的距離)作爲閾值。這將爲您提供每個索引的集羣編號,然後您可以使用np.where獲取每個集羣的列表。

+0

非常感謝!!!!!!這就是我正在尋找T^T 順便說一句,這不是一個問題,只是我很好奇,你最後輸出的那些L是什麼?我在結果中沒有得到這些L(但這很好) – Chu

+0

@Xiadan:那些表示「長整數」。當我將numpy數組轉換爲列表時,這只是一些垃圾信息。如果您使用的是Python 3,它可能不會顯示,也可能不會顯示,具體取決於其他平臺的詳細信息(如64位與32位)。但是,正如你發現的那樣,它對結果沒有影響;它看起來很奇怪。 – BrenBarn

+0

也感謝np.where部分T^T我知道必須有一種更聰明的方式將其轉換回索引列表。 – Chu

相關問題