1. 程式人生 > >利用譜聚類算法解決非完全圖的聚類

利用譜聚類算法解決非完全圖的聚類

out img 通過 ctr 技術 href 是我 sta 選擇

  在處理非完全圖的聚類時候,很難找到一個有效的聚類算法去做聚類。

  對於下圖來說,10號點和15號點的位置相隔並不是那麽近,如用普通聚類算法對下圖做聚類,通常會把10號點和15號點聚在一個類上,所以一般的聚類效果並沒有那麽好。

  技術分享

  而譜聚類,就很能很好的處理這類問題。  

  下面我們來重點介紹譜聚類

  譜聚類(SpectralClustering),就是要把樣本合理地分成兩份或者K份。從圖論的角度來說,譜聚類的問題就相當於一個圖的分割問題。即給定一個圖G = (V, E),頂點集V表示各個樣本,帶權的邊表示各個樣本之間的相似度,譜聚類的目的便是要找到一種合理的分割圖的方法,使得分割後形成若幹個子圖,連接不同子圖的邊的權重(相似度)盡可能低,同子圖內的邊的權重(相似度)盡可能高。物以類聚,人以群分。

(一) 算法步驟

  1. 根據數據構造一個Graph,Graph的每一個節點對應一個數據點,將各個點連接起來(隨後將那些已經被連接起來但並不怎麽相似的點,通過cut/RatioCut/NCut 的方式剪開),並 且邊的權重用於表示數據之間的相似度。把這個Graph用鄰接矩陣的形式表示出來,記為 W
  2. W的每一列元素加起來得到N個數,把它們放在對角線上(其他地方都是零),組成一個的對角矩陣,記為度矩陣D,並把的結果記為拉普拉斯矩陣。
  3. 求出L的前k個特征值(前k個指按照特征值的大小從小到大排序得到),以及對應的特征向量。
  4. 把這k個特征(列)向量排列在一起組成一個的矩陣,將其中每一行看作k維空間中的一個向量,並使用 K-means 算法進行聚類。聚類的結果中每一行所屬的類別就是原 來 Graph 中的,因此節點亦即最初的N
    個數據點分別所屬的類別。

(二) 譜聚類的實現

python編程,利用sklearn.cluster 下的 SpectralClustering可以很輕易的實現

from sklearn.cluster import SpectralClustering
labels=SpectralClustering(affinity=nearest_neighbors,n_clusters=20, n_neighbors=3).fit_predict(route)

#labels=

[ 3,  3,  5,  7,  8,  8,  9,  4,  4, 15, 15,  2,  2, 15, 16, 17, 18,
13, 1, 12, 2, 2, 2, 2, 2, 15, 15, 16, 16, 9, 4, 4, 4, 4,
17, 17, 17, 14, 14, 14, 18, 18, 3, 5, 4, 4, 9, 9, 8, 8, 8,
8, 8, 5, 5, 8, 19, 19, 8, 19, 8, 7, 7, 6, 6, 6, 6, 11,
3, 3, 3, 3, 3, 3, 11, 11, 11, 1, 1, 1, 13, 13, 13, 10, 12,
12, 0, 0, 10, 10, 0, 0]


其中:

1)n_clusters:代表我們在對譜聚類切圖時降維到的維數。如分為20個聚類簇,n_clusters=20。

2) affinity: 也就是我們的相似矩陣的建立方式。可以選擇的方式有三類,第一類是 ‘nearest_neighbors‘,即K鄰近法;第二類是‘precomputed‘,即自定義相似矩陣;第三類是全連接法,可以使用各種核函數來定義相似矩陣,還可以自定義核函數。基於對有向圖的聚類,本文的參數選擇是,affinity=‘nearest_neighbors‘, n_neighbors=3。

再把圖畫出來,完美解決類似於10號和15號坐標分成一類的問題。結果如下圖

技術分享

這個例子的實現所需要的數據和代碼已經上傳到github:https://github.com/yjx7/-SpectralClustering.git 有用給個star謝謝啦

利用譜聚類算法解決非完全圖的聚類