python 實現網格聚類算法
聚類算法很多,包括基於劃分的聚類算法(如:kmeans),基於層次的聚類算法(如:BIRCH),基於密度的聚類算法(如:DBScan),基於網格的聚類算法等等。基於劃分和層次聚類方法都無法發現 非凸面形狀 的簇,真正能有效發現任意形狀簇的算法是基於密度的算法,但基於密度的算法一般時間複雜度較高,1996年到2000年間,研究數據挖掘的學者們提出了大量基於網格的聚類算法,網格方法可以有效減少算法的計算複雜度,且同樣對 密度參數 敏感。
一、基於網格聚類原理
-
基本思想:
基於網絡的方法:這類方法的原理就是將數據空間劃分爲網格單元,將數據對象集映射到網格單元中,並計算每個單元的密度。根據預設的 密度閾值 判斷每個網格單元是否爲 高密度單元,由鄰近的稠密單元組形成 “類”(簇)。
-
算法過程:
算法的核心步驟:- 劃分網格
- 使用網格單元內數據的統計信息對數據進行壓縮表達
- 基於這些統計信息判斷高密度網格單元
- 最後將相連的高密度網格單元識別爲簇
-
主要算法:
- STING:基於網格多分辨率,將空間劃分爲方形單元,對應不同分辨率
- CLIQUE:結合網格和密度聚類的思想,子空間聚類處理大規模高維度數據
- WaveCluster:用小波分析使簇的邊界變得更加清晰
二、算法實現
本渣渣在 github 上面找到了 python 的 pyclustering 模塊,裏面提供了絕大多數聚類算法的實現,比起 sklearn 的算法要全面一點,詳細文檔在:https://codedocs.xyz/annoviko/pyclustering/namespacepyclustering_1_1cluster_1_1clique.html
本人主要來進行 API 調用攻城獅的簡單說明:
1. CLIQUE 算法
CLUQUE算法過程:
因爲 CLIQUE 算法涉及對聚類的數據進行劃分網格單元,爲了讓大夥看到直觀效果,如下解釋性代碼部分暫時先不對數據進行標準化的預處理工作等。
算法核心調參:網格步長,和密度閾值
- 導入需要的模塊:
import numpy as np
# 選擇聚類方法:clique 類
from pyclustering.cluster.clique import clique
# clique 可視化
from pyclustering.cluster.clique import clique_visualizer
- 構建待聚類的數據:
# 構建訓練數據
f0 = np.array([37, 42, 49, 56, 61, 65]) # 體重
f1 = np.array([147, 154, 161, 165, 172, 177]) # 身高
f2 = np.array([9, 14, 20, 24, 30, 38]) # 年齡
data = np.array([f0, f1, f2])
data = data.T
data_M = np.array(data)
- 使用 clique 聚類方法進行聚類:
# 創建 CLIQUE 算法進行處理
# 定義每個維度中網格單元的數量
intervals = 5
# 密度閾值
threshold = 0
clique_instance = clique(data_M, intervals, threshold)
# 開始聚類過程並獲得結果
clique_instance.process()
clique_cluster = clique_instance.get_clusters() # allocated clusters
# 被認爲是異常值的點(噪點)
noise = clique_instance.get_noise()
# CLIQUE形成的網格單元
cells = clique_instance.get_cells()
print("Amount of clusters:", len(clique_cluster))
print(clique_cluster)
- 聚類結果可視化:
# 顯示由算法形成的網格
clique_visualizer.show_grid(cells, data_M)
# 顯示聚類結果
clique_visualizer.show_clusters(data_M, clique_cluster, noise) # show clustering results
運行結果:
程序運行結果如下:
Amount of clusters: 4
[[0, 1], [2], [3], [4, 5]]
下面結合網格聚類的 網格單元圖 來解釋聚類的過程:
補充一點:
CLIQUE還有一個重要的思想: 如在 3 維(f0,f1,f2)數據空間上的聚成的簇C1,在二維(f0,f1)空間上也可肯定也可以聚成簇C1。這對於子空間聚類結果組合成原空間很有幫助。
- 1.網格單元圖:
(1). 我們在算法 intervals = 5,對每一維的數據劃分成5個網格單元,可以看見上圖 x0 對應於數據集中的 f0 特徵,x1對應對數據集中的 f1 特徵,x2對應對數據集中的 f2 特徵。原始的 3 維數據便被劃分成了 125(5 * 5 *3)個網格單元,然後判斷每個網格是否爲高密度單元,最後將相連的高密度網格單元識別爲簇。
(2). 本demo爲了方便理解,將密度閾值設置爲 0,即網格單元中有點即爲高密度網格,將高密度單元和鄰接的 密度可達 的單元相連,直到沒有沒有可相連的網格單元,即爲 1 簇。
(3). 以上算法聚類使用的數據爲 3 維,3 三維的聚類結果是由 2 維聚類結果組合而成的。
二維特徵(f0,f1)的聚類結果見 x0-x1表格,該二維聚類結果爲:【0,1】,【2,3】,【4,5】
二維特徵(f0,f2)的聚類結果見 x0-x2表格,該二維聚類結果爲:【0,1】,【2】,【3】,【4,5】
二維特徵(f1,f2)的聚類結果見 x1-x2表格,該二維聚類結果爲:【0,1】,【2,3】,【4,5】
所以組合成原來 3 維數據的聚類結果爲:【0,1】【2】【3】【4,5】
組合策略: 2,3在二維(f0,f2)上已經無法聚成一類,所以在 3 維數據空間上肯定更無法聚成一類
- 2.聚類結果的散點圖:
爲了可視化方便,小夥伴們也可以對數據進行降維操作,將數據降爲二維,2D的散點圖可視化效果會好一點:
參考資料
-
算法原理:
https://segmentfault.com/p/1210000009787953/read
https://baijiahao.baidu.com/s?id=1630169398195387825&wfr=spider&for=pc -
pyclustering聚類包源碼:
https://github.com/annoviko/pyclustering -
pyclustering聚類包幫助文檔:
https://codedocs.xyz/annoviko/pyclustering/classpyclustering_1_1cluster_1_1clique_1_1clique.html