1.分層聚類的介紹
分層聚類法(hierarchical cluster method)一譯“系統聚類法”。聚類分析的一種方法。其做法是開始時把每個樣品作為一類,然后把最靠近的樣品(即距離最小的群品)首先聚為小類,再將已聚合的小類按其類間距離再合並,不斷繼續下去,最后把一切子類都聚合到一個大類。
一般來說,當考慮聚類效率時,我們選擇平面聚類,當平面聚類的潛在問題(不夠結構化,預定數量的聚類,非確定性)成為關注點時,我們選擇層次聚類。 此外,許多研究人員認為,層次聚類比平面聚類產生更好的聚類.
層次聚類(Hierarchical Clustering)是聚類算法的一種,通過計算不同類別數據點間的相似度來創建一棵有層次的嵌套聚類樹。在聚類樹中,不同類別的原始數據點是樹的最低層,樹的頂層是一個聚類的根節點。創建聚類樹有自下而上合並和自上而下分裂兩種方法。
層次聚類方法對給定的數據集進行層次的分解,知道某種條件滿足為止,具體又可分為:
凝聚的層次聚類:AGNES算法
一種自底向上的策略,首先將每一個對象作為一個簇,然后合並這些原子簇為越來越大的簇,直到某個終止條件被滿足.
分層的層次聚類:DIANA算法
采用自頂向下的策略,他首先將所有對象置於一個簇中,然后逐漸細分為越來越小的簇,直到達到某個終止條件.
舉例:
由上圖可知,給定不同的距離,可以得到不同的分類,比如,23,則分為兩類,中國和其他國家和地區;17,則可分成三類,中國單獨一類,菲律賓和日本一類,其余國家和地區為一類。
自底向上的合並算法:
2.兩個組合數據點之間的距離:
(1)Single Linkage 最小距離
方法是將兩個組合數據點中距離最近的兩個數據點間的距離作為這兩個組合數據點的距離。
這種方法容易受到極端值的影響。兩個很相似的組合數據點可能由於其中的某個極端的數據點距離較近而組合在一起。
(2)Complete Linkage 最遠距離
complete Linkage的計算方法與Single Linkage相反,將兩個組合數據點中距離最遠的兩個數據點間的距離作為這兩個組合數據點的距離。
Complete Linkage的問題也與Single Linkage相反,兩個相似的組合數據點可能由於其中的極端值距離較遠而無法組合在一起。
(3)Average Linkage 平均距離
Average Linkage的計算方法是計算兩個組合數據點中的每個數據點與其他所有數據點的距離。
將所有距離的均值作為兩個組合數據點間的距離。
這種方法計算量比較大,但結果比前兩種方法更合理。
我們使用Average Linkage計算組合數據點間的距離。下面是計算組合數據點(A,F)到(B,C)的距離,這里分別計算了(A,F)和(B,C)兩兩間距離的均值。
(4)ward linkage 離差平方和
其實這個也算是平均距離中的一種
兩個集合中樣本間兩兩距離的平方和
參考以下文章:
http://blog.sciencenet.cn/blog-2827057-921772.html
3.分層聚類的案例
瑞士卷案例
1 import warnings 2 warnings.filterwarnings('ignore') 3 import numpy as np 4 import matplotlib.pyplot as plt 5 %matplotlib inline 6 from sklearn import datasets 7 # 凝聚聚類:自下而上聚類 8 from sklearn.cluster import AgglomerativeClustering,KMeans 9 from mpl_toolkits.mplot3d.axes3d import Axes3D 10 11 # 加載數據 12 X,t = datasets.make_swiss_roll(n_samples=1500,noise = 0.05) 13 # 縱坐標變‘薄’,離的更近 14 X[:,1]*=0.5 15 # (1500, 3) (1500,)三維的 16 display(X.shape,t.shape) 17 18 # 畫圖 19 fig = plt.figure(figsize=(9,6)) 20 axes3D = Axes3D(fig) 21 axes3D.scatter(X[:,0],X[:,1],X[:,2],c =t) 22 # 調整角度 23 axes3D.view_init(7,-80)
1 # 使用kmeans 2 kmeans = KMeans(6) 3 kmeans.fit(X) 4 y_ = kmeans.predict(X) 5 6 fig = plt.figure(figsize=(9,6)) 7 axes3D = Axes3D(fig) 8 axes3D.scatter(X[:,0],X[:,1],X[:,2],c = y_) 9 axes3D.view_init(7,-80)
kmeans效果不好,和上圖比較一下就好
1 from sklearn.neighbors import kneighbors_graph 2 3 # linkage : {"ward", "complete", "average", "single"} 4 conn = kneighbors_graph(X,5) 5 agg = AgglomerativeClustering(n_clusters=6,linkage='ward',connectivity=conn) 6 7 agg.fit(X) 8 9 y_ = agg.labels_ 10 11 fig = plt.figure(figsize=(9,6)) 12 axes3D = Axes3D(fig) 13 14 axes3D.scatter(X[:,0],X[:,1],X[:,2],c = y_) 15 16 axes3D.view_init(7,-80)
分層聚類,也需要選擇合適的參數,距離方法
沒有連接性約束的忽視其數據本身的結構,會形成了跨越流形的不同褶皺
添加connectivity便可以得到很好的結果
該圖為不加connectivity的結果