本文首發於 Nebula Graph Community 公眾號
在圖論中,介數(Betweenness)反應節點在整個網路中的作用和影響力。而本文主要介紹如何基於 Nebula Graph 圖資料庫實現 Betweenness Centrality 介數中心性的計算。
1. 演算法介紹
中心性是用來衡量一個節點在整個網路圖中所在中心程度的概念,包括度中心性、接近中心性、中介中心性等。 其中度中心性通過節點的度數(即關聯的邊數)來刻畫節點的受歡迎程度,接近中心性是通過計算每個節點到全圖其他所有節點的路徑和來刻畫節點與其他所有節點的關係密切程度。
中介中心性則用於衡量一個頂點出現在其他任意兩個頂點對之間最短路徑上的次數,從而來刻畫節點的重要性。
節點介數中心性的定義是:在所有最短路徑中經過該節點的路徑數目佔最短路徑總數的佔比。
計算圖中節點的介數中心性分為兩種情況:有權圖上的介數中心性和無權圖上的介數中心性。兩者的區別在於求最短路徑時使用的方法不同,對於無權圖採用 BFS(寬度優先遍歷)求最短路徑,對於有權圖採用 Dijkstra 演算法求最短路徑。
下面所介紹的演算法都是針對無向圖的。
2. 應用場景
介數反應節點在整個網路中的作用和影響力,主要用於衡量一個頂點在圖或網路中承擔“橋樑”角色的程度,圖中節點 C 就是一個重要的橋樑節點。
中心性可用於金融風控領域中反欺詐場景裡中介實體的識別。也可用於醫藥領域中特定疾病控制基因的識別,用以改進藥品的靶點。
3. 介數中心性公式
節點介數中心性的計算公式如下:
(公式 1)
其中
:經過節點 v 的 s 到 t 的最短路徑條數;
:節點s到節點t的所有最短路徑條數;
s 和 t 是屬於節點集合的任意一個節點對。
為方便計算,將每對頂點的介數計算定義為:
(公式 2)
所以上面的公式 1 可以用公式 2 代替,即
(公式 3)
4. 求解思路
求節點 v 的介數中心性,即計算,需要知道節點 v 是否在 s 到 t 的路徑上。
(1)求節點 v 是否在 s 到 t 的最短路徑上,採用下面公式判斷表示兩點之間的最短路徑長度):
當 v 位於 s 到 t 的最短路徑上時,有
(公式 4)
又因為 和是互相獨立的,根據數學組合知識得知 s 到 t 的最短路徑總數是 s 到 v 的最短路徑數與 v 到 t 的最短路徑數的乘積。
所以有下面公式:
(公式 5)
(2)根據上面公式可得:
節點 s 到節點 t 的經過 w 的最短路徑條數為 ,在圖中節點 v 是 w 的前置節點,所以 st 之間經過節點 v 和 w 的最短路徑條數計算公式為:
(公式 6)
下面分為兩種情況:分別是 和
(一)
(公式 7)
(二) 時
(公式 8)
(3)所以將上面兩種情況加起來,得到經過 v 的 s 到所有頂點的最短路徑數佔 s 到所有頂點的最短路徑數的比值。
(公式 9)
其中 即 v 是 s 到 w 路徑中 w 的前驅節點。
(4)根據上面的求 的公式,下面給出論文中求解無權圖時的演算法流程,如下所示。
對於無權圖實現根據上面流程實現。
有權圖的介數中心性計算需要將求解最短路徑的方法改成採用 Dijkstra 方法,即改動第一個 while 迴圈內的程式碼。
基於 Nebula Graph 的 Betweenness Centrality 實現了針對有權圖和無權圖的計算,實現程式碼見 https://github.com/vesoft-inc/nebula-algorithm/blob/master/nebula-algorithm/src/main/scala/com/vesoft/nebula/algorithm/lib/BetweennessCentralityAlgo.scala。
5. 計算示例
首先讀取 Nebula Graph 中的圖資料,可以指定其邊資料進行資料讀取。
其次針對 Nebula Graph 的邊資料構造拓撲圖,執行中心性計算。
讀取的 Nebula Graph 圖資料以該無權圖為例:
計算節點 1 的 BC:
經過1節點的最短路徑節點對 | 節點對之間的最短路徑總數 | 佔通過 1 節點的最短路徑數 |
---|---|---|
2-4 | 3 (2-3-4,2-5-4,2-1-4) | 1 |
節點 1 的 BC: | 1/3 |
計算節點 2 的 BC:
經過 2 節點的最短路徑節點對 | 節點對之間的最短路徑總數 | 佔通過 1 節點的最短路徑數 |
---|---|---|
1-3 | 2 (1-2-3,1-4-3) | 1 |
3-5 | 2(3-2-5,3-4-5) | 1 |
節點 2 的 BC: | 1 |
計算節點 3 的 BC:
經過 3 節點的最短路徑節點對 | 節點對之間的最短路徑總數 | 佔通過 1 節點的最短路徑數 |
---|---|---|
2-4 | 3 (2-3-4,2-5-4,2-1-4) | 1 |
節點 3 的 BC: | 1/3 |
計算節點 4 的 BC:
經過 4 節點的最短路徑節點對 | 節點對之間的最短路徑總數 | 佔通過 1 節點的最短路徑數 |
---|---|---|
1-3 | 2 (1-4-3,1-2-3) | 1 |
3-5 | 2(3-4-5.3-2-5) | 1 |
節點 4 的 BC: | 1 |
計算節點 5 的 BC:
經過 5 節點的最短路徑節點對 | 節點對之間的最短路徑總數 | 佔通過 1 節點的最短路徑數的百分比 |
---|---|---|
2-4 | 3 (2-3-4,2-5-4,2-1-4) | 1 |
節點 5 的 BC: | 1/3 |
所以每個節點的 BC 值是:
1: 1/3
2: 1
3: 1/3
4: 1
5: 1/3
6. 演算法結果示例
資料:讀取 Nebula Graph test 中的邊資料,以 srcId、dstId 和 rank 分別作為拓撲圖中的邊的三元組(起點、重點、權重)
(root@nebula) [test]> match (v:node) -[e:relation] -> () return e
+------------------------------------+
| e |
+------------------------------------+
| [:relation "3"->"4" @1 {col: "f"}] |
+------------------------------------+
| [:relation "2"->"3" @2 {col: "d"}] |
+------------------------------------+
| [:relation "2"->"5" @4 {col: "e"}] |
+------------------------------------+
| [:relation "4"->"5" @2 {col: "g"}] |
+------------------------------------+
| [:relation "1"->"5" @1 {col: "a"}] |
+------------------------------------+
| [:relation "1"->"2" @3 {col: "b"}] |
+------------------------------------+
| [:relation "1"->"4" @5 {col: "c"}] |
+------------------------------------+
讀取 Nebula Graph 邊資料,設定無權重並執行 BC 演算法,輸出結果如下:
vid: 4 BC: 1.0
vid: 1 BC: 0.3333333333333333
vid: 3 BC: 0.3333333333333333
vid: 5 BC: 0.3333333333333333
vid: 2 BC: 1.0
讀取 Nebula Graph 邊資料,設定有權重並執行 BC 演算法,輸出結果如下:
vid: 4 BC: 2.0
vid: 1 BC: 0.5
vid: 3 BC: 1.0
vid: 5 BC: 2.0
vid: 2 BC: 0.0
7. 參考資料
- 論文《A Faster Algorithm for Betweenness Centrality》
- Python 的 NetworkX 實現介數中心性的原始碼:https://github.com/networkx/networkx/blob/master/networkx/algorithms/centrality
本文中如有任何錯誤或疏漏,歡迎去 GitHub:https://github.com/vesoft-inc/nebula issue 區向我們提 issue 或者前往官方論壇:https://discuss.nebula-graph.com.cn/ 的 建議反饋
分類下提建議 ?;交流圖資料庫技術?加入 Nebula 交流群請先填寫下你的 Nebula 名片,Nebula 小助手會拉你進群~~