Update: spark版本的實現在這裏。
說明:該實現參照了SCAN作者的另一篇論文 :
Zhao, W., Martha, V., & Xu, X. (2013, March). PSCAN: a parallel Structural clustering algorithm for big networks in MapReduce. In Advanced Information Networking and Applications (AINA), 2013 IEEE 27th International Conference on (pp. 862-869). IEEE
可以實現在億級別節點的圖的聚類。
實現代碼在這裏下載。
Paper: 《SCAN: A Structural Clustering Algorithm for Networks》
Auther: Xiaowei Xu, Nurcan Yuruk, Zhidan Feng, Thomas A. J. Schweiger
Conference: SIGKDD 2007
一:SCAN算法簡介
SCAN算法是由機器學習裏的基於密度的聚類算法DBSCAN改進而來的一種非重疊社團發現算法,具有線性時間複雜度。其一大亮點在於能發現社團中橋節點(hub)和離羣點(outlier)。
主要思想在於,在考慮兩點之間的關係的時候,不僅考慮它們的直接鏈接,而是利用它們的鄰居節點來作爲聚類的標準。也就是說,節點根據它們共享鄰居方式而聚類。
由圖可知,節點0、5共享了4個節點,節點9、13只共享了2個節點,顯然它們在聚類是應採取不同的聚類方式。
二、主要概念介紹
1. 節點相似度
節點相似度定義爲兩個節點共同鄰居的數目與兩個節點鄰居數目的幾何平均數的比值(這裏的鄰居均包含節點自身)。
其中 表示節點 及其相鄰節點所組成的集合。
2. - 鄰居
節點的 - 鄰居定義爲與其相似度不小於 的節點所組成的集合。
3. 核節點
核節點是指 鄰居的數目大於 的節點。
4. 直接可達
節點 是核節點 的 鄰居,那麼稱從 直接可達 .
5. 可達
節點 可達 ,當且僅當存在一個節點鏈 ,使得 是 從 直接可達的。
6. 相連
若核節點u可達節點v和節點w,則稱節點v和節點w相連.
7.相連聚類
如果一個非空子圖C中的所有節點是相連的,並且C是滿足可達的最大子圖,那麼稱C是一個相連聚類。
8. 橋節點(hub)
與至少兩個聚類相鄰的孤立節點.
9. 離羣點(outlier)
只與一個聚類相鄰或不與任何聚類相鄰的孤立節點.
10. 引理:
如果 是一個核節點,那麼從 可達的節點集是一個結構相連聚類
11. 引理:
是一個結構相連聚類, 是 中的一個核節點。那麼 等於從 結構可達的節點集。
三、具體算法
1、對於每個未分配社團的節點 ,檢查 是否是核節點,是核節點則將其直接可達節點分配到一個社團中(社團標號記爲該節點),並將其 -鄰居放進隊列中,重複進行1步驟(類似於對直接可達節點進行DFS)。
2、若 不是核節點則將其標誌爲non-member。
3、最後檢查所有的non-menber節點,若其相鄰節點存在於兩個及以上的社團中,則將其標爲hub節點,否則標爲outlier。
ALGORITHM SCAN(G=<V, E>, ε, μ)
// all vertices in V are labeled as unclassified;
for each unclassified vertex v ∈ V do
// STEP 1. check whether v is a core;
if COREε,μ(v) then
// STEP 2.1. if v is a core, a new cluster is expanded;
generate new clusterID;
insert all x ∈ Nε (v) into queue Q;
while Q ≠ 0 do
y = first vertex in Q;
R = {x ∈ V | DirREACHε,μ(y, x)};
for each x ∈ R do
if x is unclassified or non-member then
assign current clusterID to x;
if x is unclassified then
insert x into queue Q;
remove y from Q;
else
// STEP 2.2. if v is not a core, it is labeled as non-member
label v as non-member;
end for.
// STEP 3. further classifies non-members
for each non-member vertex v do
if (∃ x, y ∈ Γ(v) ( x.clusterID ≠ y.clusterID) then
label v as hub
else
label v as outlier;
end for.
end SCAN.