1. 程式人生 > >Python層次聚類sci.cluster.hierarchy.linkage函式詳解

Python層次聚類sci.cluster.hierarchy.linkage函式詳解

1 函式原型:

scipy.cluster.hierarchy.linkage(y, method='single', metric='euclidean', optimal_ordering=False)

函式功能:進行層次聚類/凝聚聚類。

引數:

y: 可以是1維壓縮向量(距離向量),也可以是2維觀測向量(座標矩陣)。若y是1維壓縮向量,則y必須是n個初始觀測值的組合,n是座標矩陣中成對的觀測值。

返回值:(n-1)*4的矩陣Z(後面會仔細的講解返回值各個欄位的含義)

linkage方法用於計算兩個聚類簇s和t之間的距離d(s,t),這個方法的使用在層次聚類之前。當s和t行程一個新的聚類簇u時,s和t被從森林(已經形成的聚類簇群)中移除,而用新的聚類簇u來代替。當森林中只有一個聚類簇時演算法停止。而這個聚類簇就成了聚類樹的根。

距離矩陣在每次迭代中都將被儲存,d[i,j]對應於第i個聚類簇與第j個聚類簇之間的距離。每次迭代必須更新新形成的聚類簇之間的距離矩陣。

假定現在有|u|個初始觀測值u[0],...,u[|u|-1]在聚類簇u中,有|v|個初始物件v[0],...,v[|v|-1]在聚類簇v中。回憶s和t合併成u。讓v成為森林中的聚類簇,而不是u。

下面是計算新形成的聚類簇u和v之間距離的方法:

  • method = ‘single’

            d(u,v) = min(dist(u[i],u[j]))

對於u中所有點i和v中所有點j。這被稱為最近鄰點演算法。

  • method = 'complete'

             d(u,v) = max(dist(u[i],u[j]))

  對於u中所有點i和v中所有點j。這被稱為最近鄰點演算法。

  • method = 'average'

                

|u|,|v|是聚類u和v中元素的的個數,這被稱為UPGMA演算法(非加權組平均)法。

  • method = 'weighted'

            d(u,v) = (dist(s,v) + dist(t,v))/2

u是由s和t形成的,而v是森林中剩餘的聚類簇,這被稱為WPGMA(加權分組平均)法。

  • method = 'centroid'

            

Cs和Ct分別為聚類簇s和t的聚類中心,當s和t形成一個新的聚類簇時,聚類中心centroid會在s和t上重新計算。這段聚類就變成了u的質心和剩下聚類簇v的質心之間的歐式距離。這杯稱為UPGMC演算法(採用質心的無加權paire-group方法)。

  • method = 'median'
  當兩個聚類簇s和t組合成一個新的聚類簇u時,s和t的質心的均值稱為u的質心。這被稱為WPGMC演算法。
  • method = 'ward' (沃德方差最小化演算法)

新的輸入d(u,v)通過下式計算得出,

        

u是s和t組成的新的聚類,v是森林中未使用的聚類。T = |v|+|s|+|t|,|*|是聚類簇中觀測值的個數。

注意:當最小距離在一個森林中成對存在時,即有多個最小距離的時候,具體的實現要看MATLAB的版本(因為這個函式是從matlab裡面copy過來的)。

2 引數:

y:nump.ndarry。是一個壓縮距離的平面上三角矩陣。或者n*m的觀測值。壓縮距離矩陣的所有元素必須是有限的,沒有NaNs或infs。

method:str,可選。

metric:str或function,可選。在y維觀測向量的情況下使用該引數,苟澤忽略。參照有效距離度量列表的pdist函式,還可以使用自定義距離函式。

optimal_ordering:bool。若為true,linkage矩陣則被重新排序,以便連續葉子間距最小。當資料視覺化時,這將使得樹結構更為直觀。預設為false,因為資料集非常大時,執行此操作計算量將非常大。

Note:上述演算法的時間複雜度如下:

上述演算法時間複雜度對比
演算法時間複雜度
singleO(n2)
completeO(n2)
averageO(n2)
weightedO(n2)
wardO(n2)
其他O(n2)
centroid、median、ward只能定義在歐氏距離計算中。如果預先將y計算的距離傳進來,那麼要確保是用歐式距離計算的,否則將會導致錯誤的計算結果。

3 返回值:

Z:numpy.ndarry。

層次聚類編碼為一個linkage矩陣。

Z共有四列組成,第一欄位與第二欄位分別為聚類簇的編號,在初始距離前每個初始值被從0~n-1進行標識,每生成一個新的聚類簇就在此基礎上增加一對新的聚類簇進行標識,第三個欄位表示前兩個聚類簇之間的距離,第四個欄位表示新生成聚類簇所包含的元素的個數。

下面舉個例子來說明一下:

#%%
from scipy.cluster.hierarchy import dendrogram, linkage,fcluster
from matplotlib import pyplot as plt
X = [[i] for i in [2, 8, 0, 4, 1, 9, 9, 0]]
# X = [[1,2],[3,2],[4,4],[1,2],[1,3]]
Z = linkage(X, 'ward')
f = fcluster(Z,4,'distance')
fig = plt.figure(figsize=(5, 3))
dn = dendrogram(Z)
plt.show()
下面是聚類結果的視覺化聚類樹:


下面是返回值的解析:


                                                                                                                                2018/2/25凌晨1點於中關村。