社區檢測與高密子圖挖掘(上)

前面我們說過圖的第二個優點是拉幫結派,在圖裏面是很容易形成團伙結構,近年來,研究這個問題的論文也是汗牛充棟。本章,我們就這一問題所衍生出來的兩個方向:社區檢測(Community Detection)和高密子圖挖掘(Dense Subgraph Mining)作相關講解。

本文,我們先講社區檢測的相關算法。社區檢測的任務是什麼呢?舉個例子,給定如下圖。

直觀印象告訴我們,該圖存在以下的社區結構:

像這樣,從給定圖中,將各節點劃分到相應社團的任務稱爲社區檢測。值得注意的一點是,一般當我們在說社區檢測的時候,節點都是同態的,類型都一樣。

 

本文會重點介紹三個最流行的社區檢測算法Louvain、Lpa、Infomap,最後對社區檢測作一些補充說明。

Louvain算法

Louvain算法是一種基於模塊度的社區檢測算法,由於其良好的效率與穩定性而廣受歡迎。網上也有基於Spark GraphX 的開源實現版本。

 

模塊度(Modularity)

同很多無監督的聚類算法一樣,衡量指標是一個至關重要的因素,很多時候,我們只需要定義好這個指標,然後選擇啓發式的更新方法去不斷優化這個值。一個算法的大概骨架也就出來了。當然一個好的社區衡量指標要符合基本邏輯:社區內聯繫緊密,社區間聯繫鬆散。在06年《Modularity and Community structure in networks 》一文中,作者Newman 給出瞭如下Modularity的定義:

m表示圖中邊的數量;

c表示某個社區;

Ec表示社區c內邊的數量;

 

表示社區c節點的度之和(包含與其他社區相連邊的度)

可以這樣去理解上面這個公式:

表示實際情況下,c社區內產生邊的概率

表示在一種理想情況下,給定任意節點i的的度ki,對節點i和節點j進行隨機連邊,邊屬於社區c的概率期望

於是上式就表示了社區內連邊數與隨機期望的一個差值。連邊數比隨機期望值越高,表明社區劃分的越好。

 

比如上圖中的:

有了上述模塊度的定義作爲鋪墊,Louvain算法就可以啓發式地去最大化Q值了。

 

Louvain算法步驟

  1. 初始化,將圖中的每個節點看成一個獨立的社區;
  2. 對每個節點,依次嘗試把節點i分配到其鄰居節點所在的這個社區計算分配之前與分配之後的模塊度變化△Q,並記錄△Q最大的社區,如果Max△Q>0,則將該節點分配到該社區;
  3. 重複第二步,直到所有節點的所屬社區不再變化。

 

我們看第2步,很像決策樹生長時計算信息熵取最大增益一樣,假設節點i移動到社區c;

移動前模塊度

移動後模塊度

可以看到,△Q的計算只與節點i和社區c的連邊有關,所以這個計算是非常快的,並且也比較容易並行處理。

 

最後,Louvain算法也可以分層進行,將每一次Louvain算法檢測出來的社區進行壓縮處理成一個新的節點,重新構圖,繼續跑Louvain算法,這樣就可以得到層次化的社區標籤了。

 

LPA-Label Propagation Algorithm

LPA算法是一個極其簡單的圖傳播算法,其經驗假設是以節點爲中心,進行投票制,十分高效。

算法過程

  1. 初始化,將圖中的每個節點看成一個獨立的社區;
  2. While所有節點的社區標籤不再變化;
  3. 統計每個節點鄰居的社區,將出現最多次的社區賦給該節點,如果出現最多次的社區有多個,隨機選擇一個社區賦給該節點。

 

算法本身很簡單,分佈式實現也很容易。但是這個算法也存在很大的問題:由於存在隨機選擇的情況,所以算法很容易出現振盪。但這個算法的運行開銷很低,拿來做baseline,作爲參考也是可以的。另外,對於一個帶權重的圖,亦可以考慮帶權重的投票機制。

 

Infomap算法

這個算法又稱map equation,是個思路十分清奇的算法。從信息論的角度出發,假設一個random worker 在圖上進行隨機遊走,那麼怎麼用最少的編碼長度來表示其路徑呢?也即最小平均比特(minimize bits per step)。一個基本的經驗是:

 

◻如果節點沒有社區結構,那麼直接根據每個節點的到達概率,調用香農信息熵公式,就可以得到理論上的最小平均比特;

 

◻如果節點存在社區結構,那麼社區內的節點就可以共享社區的bit位碼,這相當於其本身可以用更少的位碼來表示,所以相比沒有社區結構的情況,可以得到更小的平均比特;

 

社區劃分的越好,那麼表示任意一條隨機遊走的路徑所需的平均比特就越小。

 

OK,現在的問題就可以轉化爲如何在數學上量化這個平均比特,如果我們能量化這個衡量標準,那麼整個算法的框架就跟前面 Louvain 算法幾乎一致,不斷改變節點的社區劃分,啓發式地去最小化平均比特。

 

那麼首先我們來看看最簡單的情況,所有節點都屬一個社區的時候怎麼去量化平均比特?

 

由於節點都在一個社區,所以隨機遊走每一步都只能是在節點之間行走,不存在進出其他社區的事件發生,如果我們能夠計算出每個節點的到達概率,就可以依據信息熵的公式來量化平均比特了:

 

這裏pα表示節點α的到達概率:

給定一個有向權重圖,節點的到達概率怎麼計算呢?

 

一個暴力的辦法是在圖上進行長時間的隨機遊走,最後統計每個節點的出現概率。這個方法很好理解,但是在實際應用中,如果圖很大,那就很難奏效了。

 

其實我們在第二章講到PageRank算法時,就已經計算出了這個值。這裏我們簡單回顧下,假設節點 α 指向 節點 β 的邊的權重爲:

那麼節點 α 到 節點 β轉移概率:

節點 α 的到達概率:

那麼只要我們初始化了每個節點的到達概率之後,就可以依據上述兩式不斷交替迭代式地更新每個節點的到達概率,這個結果會很快趨於收斂。

 

跟PageRank 算法一樣考慮到 DeadEnds和Spider traps的問題,需要一個假想的在整個圖上的隨機跳轉概率,所以實際上節點α 達到概率的更新公式爲:

τ 是一個超參數,表示發生隨機跳轉的概率,一般取0.15。

 

這樣對計算完的

進行歸一化處理,然後帶到上面信息熵的公式,就可以計算出理論上同屬一個社區時的最小平均比特了。

 

現在我們來看一般情況,假設圖被劃分成 m 個社區,那麼每走一步就可能是以下三種事件中的一種情況:進入某個社區、從某個社區中出來、在社區內部節點間轉移。現在我們來定義這三個事件發生的概率:

在社區內從節點α 轉移到節點 β 的概率:

 

 

進入某個社區 i 的概率:

從某個社區 i 中出來的概率:

有了上面三種事件的概率定義,結合信息熵公式,我們一樣可以計算出平均比特了。下面我們直接給出計算公式並給出相關參數的意義解釋:

 

將圖劃分成 m 個社區,編碼隨機遊走路徑時的平均比特;

產生進入社區這種事件的總概率;

進入社區事件發生的信息熵;

random worker在社區 i 內部的概率,這裏包括了在社區內跳轉和離開該社區兩類事件;

random worker 下一步事件發生在社區 i 內部的信息熵;

上面的這個式子就是Infomap算法的核心,亦稱之爲 map equation。其本質就是從信息論的角度出發,定義清楚各類事件的發生概率,依據信息熵公式,就可以得到此時編碼所需的平均比特了。

上面這個圖就是在不同劃分時候的平均比特的值了,可以看到,同屬一個社區的時候,編碼需要的平均比特爲 4.53 bits, 如果按照左下圖所示,將圖劃分成4個社區,編碼所需的平均比特只需要3.09bits。值得注意的是,這裏依據概率和Huffman編碼算法給出了各節點具體的code,實際我們在使用Infomap的時候,並不需要顯式地把每類事件都編碼出來,只需要將各種概率帶入公式計算出平均比特,就知道此時劃分的效果好壞了。

 

Infomap算法的迭代過程

  1. 初始化,對每個節點都視作獨立的社區;
  2. while 平均比特的值不再下降;
  3. 對圖裏的節點隨機採樣出一個序列,按順序依次嘗試將每個節點賦給鄰居節點所在的社區,取平均比特下降最大時的社區賦給該節點,如果沒有下降,該節點的社區不變。
Infomap 算法是一個十分優秀的算法,同樣支持層次化的社區劃分,也是三個算法裏面唯一支持有向圖的,論文作者也開源了C++ 版本的實現代碼:
http://www.mapequation.org/code.html 

另外作者也設計了一個動態展示demo:
http://www.mapequation.org/apps/MapDemo.html 

demo的相關說明 :
http://www.mapequation.org/assets/publications/mapequationtutorial.pdf

 

總結

關於社區檢測的算法,上面已經介紹了三類。其中Louvain 和Infomap 算法都是基於一個合理的全局衡量指標對社區的劃分不斷進行啓發式的優化。如果從聚類的角度去看待社區檢測,那麼一個基本的範式就是首先得到每個節點的特徵表達,然後基於各種聚類算法進行聚類從而得到社區的劃分。這裏,節點的特徵表達可以從圖的拉普拉斯矩陣獲得,這類方法稱爲譜方法;也可以由 graph embedding 的方式習得每個節點的向量表達,這些相關的方法我們會在後續的相關章節進行講解。

歡迎關注我們的微信公衆號:geetest_jy 添加技術助理,一起分享交流:geetest1024

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章