Python機器學習——Agglomerative層次聚類
阿新 • • 發佈:2018-07-01
條件 分享圖片 n-2 mov unique ber and 兩個 its
層次聚類(hierarchical clustering)可在不同層次上對數據集進行劃分,形成樹狀的聚類結構。AggregativeClustering是一種常用的層次聚類算法。
??其原理是:最初將每個對象看成一個簇,然後將這些簇根據某種規則被一步步合並,就這樣不斷合並直到達到預設的簇類個數。這裏的關鍵在於:如何計算聚類簇之間的距離?
??由於每個簇就是一個集合,因此需要給出集合之間的距離。給定聚類簇Ci,CjCi,Cj,有如下三種距離:
- 最小距離:
dmin(Ci,Cj)=minx? i∈Ci,x? j∈Cjdistance(x? i,x? j)dmin(Ci,Cj)=minx→i∈Ci,x→j∈Cjdistance(x→i,x→j)
- 最大距離: dmax(Ci,Cj)=maxx? i∈Ci,x? j∈Cjdistance(x? i,x? j)dmax(Ci,Cj)=maxx→i∈Ci,x→j∈Cjdistance(x→i,x→j) 它是兩個簇的樣本對之間距離的最大值。
- 平均距離: davg(Ci,Cj)=1|Ci||Cj|∑x? i∈Ci∑x? j∈Cjdistance(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的峰值最大
Python機器學習——Agglomerative層次聚類