Python機器學習——Agglomerative層次聚類


層次聚類(hierarchical clustering)可在不同層次上對數據集進行划分,形成樹狀的聚類結構。AggregativeClustering是一種常用的層次聚類算法。 
  其原理是:最初將每個對象看成一個簇,然后將這些簇根據某種規則被一步步合並,就這樣不斷合並直到達到預設的簇類個數。這里的關鍵在於:如何計算聚類簇之間的距離? 
  由於每個簇就是一個集合,因此需要給出集合之間的距離。給定聚類簇Ci,CjCi,Cj,有如下三種距離:

  • 最小距離:
     
    dmin(Ci,Cj)=minx⃗ iCi,x⃗ jCjdistance(x⃗ i,x⃗ j)dmin(Ci,Cj)=minx→i∈Ci,x→j∈Cjdistance(x→i,x→j)
    它是兩個簇的樣本對之間距離的最小值。
  • 最大距離:
     
    dmax(Ci,Cj)=maxx⃗ iCi,x⃗ jCjdistance(x⃗ i,x⃗ j)dmax(Ci,Cj)=maxx→i∈Ci,x→j∈Cjdistance(x→i,x→j)
    它是兩個簇的樣本對之間距離的最大值。
  • 平均距離:
     
    davg(Ci,Cj)=1|Ci||Cj|x⃗ iCix⃗ jCjdistance(x⃗ i,x⃗ j)davg(Ci,Cj)=1|Ci||Cj|∑x→i∈Ci∑x→j∈Cjdistance(x→i,x→j)
    它是兩個簇的樣本對之間距離的平均值。

  當該算法的聚類簇采用dmindmin時,稱為單鏈接single-linkage算法,當該算法的聚類簇采用dmaxdmax時,稱為單鏈接complete-linkage算法,當該算法的聚類簇采用davgdavg時,稱為單鏈接average-linkage算法。

  下面給出算法:

  • 輸入: 
    • 數據集D=D={x⃗ 1,x⃗ 2,...,x⃗ Nx→1,x→2,...,x→N}
    • 聚類簇距離度量函數
    • 聚類簇數量KK
  • 輸出:簇划分C=C={C1,C2,...,CKC1,C2,...,CK}
  • 算法步驟如下:

    • 初始化:將每個樣本都作為一個簇
       
      Ci=[x⃗ i],i=1,2,...,NCi=[x→i],i=1,2,...,N
    • 迭代:終止條件為聚類簇的數量為K。迭代過程如下: 
      • 計算聚類簇之間的距離,找出距離最近的兩個簇,將這兩個簇合並。 

     

    Python實戰

     


      AgglomerativeClustering是scikit-learn提供的層級聚類算法模型,其原型為:

class sklearn.cluster.AgglomerativeClustering(n_clusters=2, affinity=’euclidean’, memory=None, connectivity=None, compute_full_tree=’auto’, linkage=’ward’, pooling_func=<function mean>)
  • 1

參數

  • n_clusters:一個整數,指定分類簇的數量
  • connectivity:一個數組或者可調用對象或者None,用於指定連接矩陣
  • affinity:一個字符串或者可調用對象,用於計算距離。可以為:’euclidean’,’l1’,’l2’,’mantattan’,’cosine’,’precomputed’,如果linkage=’ward’,則affinity必須為’euclidean’
  • memory:用於緩存輸出的結果,默認為不緩存
  • n_components:在 v-0.18中移除
  • compute_full_tree:通常當訓練了n_clusters后,訓練過程就會停止,但是如果compute_full_tree=True,則會繼續訓練從而生成一顆完整的樹
  • linkage:一個字符串,用於指定鏈接算法 
    • ‘ward’:單鏈接single-linkage,采用dmindmin
    • ‘complete’:全鏈接complete-linkage算法,采用dmaxdmax
    • ‘average’:均連接average-linkage算法,采用davgdavg
  • pooling_func:一個可調用對象,它的輸入是一組特征的值,輸出是一個數

屬性

  • labels:每個樣本的簇標記
  • n_leaves_:分層樹的葉節點數量
  • n_components:連接圖中連通分量的估計值
  • children:一個數組,給出了每個非節點數量

方法

  • fit(X[,y]):訓練樣本
  • fit_predict(X[,y]):訓練模型並預測每個樣本的簇標記


from sklearn import cluster from sklearn.metrics import adjusted_rand_score import numpy as np import matplotlib.pyplot as plt from sklearn.datasets.samples_generator import make_blobs """ 產生數據 """ def create_data(centers,num=100,std=0.7): X,labels_true = make_blobs(n_samples=num,centers=centers, cluster_std=std) return X,labels_true """ 數據作圖 """ def plot_data(*data): X,labels_true=data labels=np.unique(labels_true) fig=plt.figure() ax=fig.add_subplot(1,1,1) colors='rgbycm' for i,label in enumerate(labels): position=labels_true==label ax.scatter(X[position,0],X[position,1],label="cluster %d"%label), color=colors[i%len(colors)] ax.legend(loc="best",framealpha=0.5) ax.set_xlabel("X[0]") ax.set_ylabel("Y[1]") ax.set_title("data") plt.show()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

這里寫圖片描述

這里寫代碼片
""" 測試函數 """ def test_AgglomerativeClustering(*data): X,labels_true=data clst=cluster.AgglomerativeClustering() predicted_labels=clst.fit_predict(X) print("ARI:%s"% adjusted_rand_score(labels_true, predicted_labels)) """ 考察簇的數量對於聚類效果的影響 """ def test_AgglomerativeClustering_nclusters(*data): X,labels_true=data nums=range(1,50) ARIS=[] for num in nums: clst=cluster.AgglomerativeClustering(n_clusters=num) predicted_lables=clst.fit_predict(X) ARIS.append(adjusted_rand_score(labels_true, predicted_lables)) fig=plt.figure() ax=fig.add_subplot(1,1,1) ax.plot(nums,ARIS,marker="+") ax.set_xlabel("n_clusters") ax.set_ylabel("ARI") fig.suptitle("AgglomerativeClustering") plt.show() """ 考察鏈接方式對聚類結果的影響 """ def test_agglomerativeClustering_linkage(*data): X,labels_true=data nums=range(1,50) fig=plt.figure() ax=fig.add_subplot(1,1,1) linkages=['ward','complete','average'] markers="+o*" for i,linkage in enumerate(linkages): ARIs=[] for num in nums: clst=cluster.AgglomerativeClustering(n_clusters=num,linkage=linkage) predicted_labels=clst.fit_predict(X) ARIs.append(adjusted_rand_score(labels_true, predicted_labels)) ax.plot(nums,ARIs,marker=markers[i],label="linkage:%s"%linkage) ax.set_xlabel("n_clusters") ax.set_ylabel("ARI") ax.legend(loc="best") fig.suptitle("AgglomerativeClustering") plt.show() centers=[[1,1],[2,2],[1,2],[10,20]] X,labels_true=create_data(centers, 1000, 0.5) test_AgglomerativeClustering(X,labels_true) plot_data(X,labels_true) test_AgglomerativeClustering_nclusters(X,labels_true) test_agglomerativeClustering_linkage(X,labels_true)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59

這里寫圖片描述

可以看到當n_clusters=4時,ARI指數最大,因為確實是從四個中心點產生的四個簇。
  • 1
  • 2

這里寫圖片描述

 可以看到,三種鏈接方式隨分類簇的數量的總體趨勢相差無幾。但是單鏈接方式ward的峰值最大


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM