基于社區(qū)發(fā)現(xiàn)算法和圖分析Neo4j解讀《權力的游戲》下篇

其中的分析和可視化是用Gephi做的,Gephi是非常流行的圖分析工具。但作者覺得使用Neo4j來實現(xiàn)更有趣。

節(jié)點中心度
節(jié)點中心度給出網(wǎng)絡中節(jié)點的重要性的相對度量。有許多不同的方式來度量中心度,每種方式都代表不同類型的“重要性”。

度中心性(Degree Centrality)
度中心性是最簡單度量,即為某個節(jié)點在網(wǎng)絡中的聯(lián)結數(shù)。在《權力的游戲》的圖中,某個角色的度中心性是指該角色接觸的其他角色數(shù)。作者使用Cypher計算度中心性:
MATCH (c:Character)-[:INTERACTS]- RETURN c.name AS character, count(*) AS degree ORDER BY degree DESC

character
degree

Tyrion
36

Jon
26

Sansa
26

Robb
25

Jaime
24

Tywin
22

Cersei
20

Arya
19

Joffrey
18

Robert
18

從上面可以發(fā)現(xiàn),在《權力的游戲》網(wǎng)絡中提利昂·蘭尼斯特(Tyrion)和最多的角色有接觸。鑒于他的心計,我們覺得這是有道理的。

加權度中心性(Weighted Degree Centrality)
作者存儲一對角色接觸的次數(shù)作為INTERACTS關系的weight屬性。對該角色的INTERACTS關系的所有weight相加得到加權度中心性。作者使用Cypher計算所有角色的這個度量:
MATCH (c:Character)-[r:INTERACTS]- RETURN c.name AS character, sum(r.weight) AS weightedDegree ORDER BY weightedDegree DESC

character
weightedDegree

Tyrion
551

Jon
442

Sansa
383

Jaime
372

Bran
344

Robb
342

Samwell
282

Arya
269

Joffrey
255

Daenerys
232

介數(shù)中心性(Betweenness Centrality)
介數(shù)中心性:在網(wǎng)絡中,一個節(jié)點的介數(shù)中心性是指其它兩個節(jié)點的所有最短路徑都經(jīng)過這個節(jié)點,則這些所有最短路徑數(shù)即為此節(jié)點的介數(shù)中心性。介數(shù)中心性是一種重要的度量,因為它可以鑒別出網(wǎng)絡中的“信息中間人”或者網(wǎng)絡聚類后的聯(lián)結點。


基于社區(qū)發(fā)現(xiàn)算法和圖分析Neo4j解讀《權力的游戲》下篇

圖6中紅色節(jié)點是具有高的介數(shù)中心性,網(wǎng)絡聚類的聯(lián)結點。
為了計算介數(shù)中心性,作者使用Neo4j 3.x或者apoc庫。安裝apoc后能用Cypher調(diào)用其170+的程序:
MATCH (c:Character) WITH collect(c) AS charactersCALL apoc.algo.betweenness(['INTERACTS'], characters, 'BOTH') YIELD node, scoreSET node.betweenness = scoreRETURN node.name AS name, score ORDER BY score DESC

name
score

Jon
1279.7533534055322

Robert
1165.6025171231624

Tyrion
1101.3849724234349

Daenerys
874.8372110508583

Robb
706.5572832464792

Sansa
705.1985623519137

Stannis
571.5247305125714

Jaime
556.1852522889822

Arya
443.01358430043337

Tywin
364.7212195528086

緊度中心性(Closeness centrality)
緊度中心性是指到網(wǎng)絡中所有其他角色的平均距離的倒數(shù)。在圖中,具有高緊度中心性的節(jié)點在聚類社區(qū)之間被高度聯(lián)結,但在社區(qū)之外不一定是高度聯(lián)結的。


基于社區(qū)發(fā)現(xiàn)算法和圖分析Neo4j解讀《權力的游戲》下篇

圖7 :網(wǎng)絡中具有高緊度中心性的節(jié)點被其它節(jié)點高度聯(lián)結
MATCH (c:Character) WITH collect(c) AS charactersCALL apoc.algo.closeness(['INTERACTS'], characters, 'BOTH') YIELD node, scoreRETURN node.name AS name, score ORDER BY score DESC

name
score

Tyrion
0.004830917874396135

Sansa
0.004807692307692308

Robert
0.0047169811320754715

Robb
0.004608294930875576

Arya
0.0045871559633027525

Jaime
0.004524886877828055

Stannis
0.004524886877828055

Jon
0.004524886877828055

Tywin
0.004424778761061947

Eddard
0.004347826086956522

使用python-igraph
Neo4j與其它工具(比如,R和Python數(shù)據(jù)科學工具)完美結合。我們繼續(xù)使用apoc運行 PageRank和社區(qū)發(fā)現(xiàn)(community detection)算法。這里接著使用python-igraph計算分析。Python-igraph移植自R的igraph圖形分析庫。 使用pip install python-igraph安裝它。

從Neo4j構建一個igraph實例
為了在《權力的游戲》的數(shù)據(jù)的圖分析中使用igraph,首先需要從Neo4j拉取數(shù)據(jù),用Python建立igraph實例。作者使用 Neo4j 的Python驅(qū)動庫py2neo。我們能直接傳入Py2neo查詢結果對象到igraph的TupleList構造器,創(chuàng)建igraph實例:
from py2neo import Graphfrom igraph import Graph as IGraph graph = Graph query = ''' MATCH (c1:Character)-[r:INTERACTS]->(c2:Character) RETURN c1.name, c2.name, r.weight AS weight '''ig = IGraph.TupleList(graph.run(query), weights=True)

現(xiàn)在有了igraph對象,可以運行igraph實現(xiàn)的各種圖算法來。

PageRank
作者使用igraph運行的第一個算法是PageRank。PageRank算法源自Google的網(wǎng)頁排名。它是一種特征向量中心性(eigenvector centrality)算法。
在igraph實例中運行PageRank算法,然后把結果寫回Neo4j,在角色節(jié)點創(chuàng)建一個pagerank屬性存儲igraph計算的值:
pg = ig.pagerank pgvs = for p in zip(ig.vs, pg): print(p) pgvs.append({"name": p[0]["name"], "pg": p[1]}) pgvs write_clusters_query = ''' UNWIND {nodes} AS n MATCH (c:Character) WHERE c.name = n.name SET c.pagerank = n.pg '''graph.run(write_clusters_query, nodes=pgvs)

現(xiàn)在可以在Neo4j的圖中查詢最高PageRank值的節(jié)點:
MATCH (n:Character) RETURN n.name AS name, n.pagerank AS pagerank ORDER BY pagerank DESC LIMIT 10

name
pagerank

Tyrion
0.042884981999963316

Jon
0.03582869669163558

Robb
0.03017114665594764

Sansa
0.030009716660108578

Daenerys
0.02881425425830273

Jaime
0.028727587587471206

Tywin
0.02570016262642541

Robert
0.022292016521362864

Cersei
0.022287327589773507

Arya
0.022050209663844467

社區(qū)發(fā)現(xiàn)(Community detection)


基于社區(qū)發(fā)現(xiàn)算法和圖分析Neo4j解讀《權力的游戲》下篇

圖8
社區(qū)發(fā)現(xiàn)算法用來找出圖中的社區(qū)聚類。作者使用igraph實現(xiàn)的隨機游走算法( walktrap)來找到在社區(qū)中頻繁有接觸的角色社區(qū),在社區(qū)之外角色不怎么接觸。
在igraph中運行隨機游走的社區(qū)發(fā)現(xiàn)算法,然后把社區(qū)發(fā)現(xiàn)的結果導入Neo4j,其中每個角色所屬的社區(qū)用一個整數(shù)來表示:
clusters = IGraph.community_walktrap(ig, weights="weight").as_clustering nodes = [{"name": node["name"]} for node in ig.vs]for node in nodes: idx = ig.vs.find(name=node["name"]).index node["community"] = clusters.membership[idx] write_clusters_query = ''' UNWIND {nodes} AS n MATCH (c:Character) WHERE c.name = n.name SET c.community = toInt(n.community) '''graph.run(write_clusters_query, nodes=nodes)

我們能在Neo4j中查詢有多少個社區(qū)以及每個社區(qū)的成員數(shù):
MATCH (c:Character) WITH c.community AS cluster, collect(c.name) AS members RETURN cluster, members ORDER BY cluster ASC

cluster
members

0
[Aemon, Alliser, Craster, Eddison, Gilly, Janos, Jon, Mance, Rattleshirt, Samwell, Val, Ygritte, Grenn, Karl, Bowen, Dalla, Orell, Qhorin, Styr]

1
[Aerys, Amory, Balon, Brienne, Bronn, Cersei, Gregor, Jaime, Joffrey, Jon Arryn, Kevan, Loras, Lysa, Meryn, Myrcella, Oberyn, Podrick, Renly, Robert, Robert Arryn, Sansa, Shae, Tommen, Tyrion, Tywin, Varys, Walton, Petyr, Elia, Ilyn, Pycelle, Qyburn, Margaery, Olenna, Marillion, Ellaria, Mace, Chataya, Doran]

2
[Arya, Beric, Eddard, Gendry, Sandor, Anguy, Thoros]

3
[Brynden, Catelyn, Edmure, Hoster, Lothar, Rickard, Robb, Roose, Walder, Jeyne, Roslin, Ramsay]

4
[Bran, Hodor, Jojen, Luwin, Meera, Rickon, Nan, Theon]

5
[Belwas, Daario, Daenerys, Irri, Jorah, Missandei, Rhaegar, Viserys, Barristan, Illyrio, Drogo, Aegon, Kraznys, Rakharo, Worm]

6
[Davos, Melisandre, Shireen, Stannis, Cressen, Salladhor]

7
[Lancel]

角色“大合影”
《權力的游戲》的權力圖。節(jié)點的大小正比于介數(shù)中心性,顏色表示社區(qū)(由隨機游走算法獲得),邊的厚度正比于兩節(jié)點接觸的次數(shù)。現(xiàn)在已經(jīng)計算好這些圖的分析數(shù)據(jù),讓我們對其進行可視化,讓數(shù)據(jù)看起來更有意義。
Neo4j自帶瀏覽器可以對Cypher查詢的結果進行很好的可視化,但如果我們想把可視化好的圖嵌入到其它應用中,可以使用Javascript可視化庫Vis.js。從Neo4j拉取數(shù)據(jù),用Vis.js的neovis.js構建可視化圖。Neovis.js提供簡單的API配置,例如:
var config = { container_id: "viz", server_url: "localhost", labels: { "Character": "name" }, label_size: { "Character": "betweenness" }, relationships: { "INTERACTS": }, relationship_thickness: { "INTERACTS": "weight" }, cluster_labels: { "Character": "community" } }; var viz = new NeoVis(config); viz.render;

其中:
節(jié)點帶有標簽Character,屬性name;

節(jié)點的大小正比于betweenness屬性;

可視化中包括INTERACTS關系;

關系的厚度正比于weight屬性;

節(jié)點的顏色是根據(jù)網(wǎng)絡中社區(qū)community屬性決定;

從本地服務器localhost拉取Neo4j的數(shù)據(jù);

在一個id為viz的DOM元素中展示可視化。

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,908評論 6 541
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,324評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,018評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,675評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,417評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,783評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,779評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,960評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,522評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 41,267評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,471評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,009評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,698評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,099評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,386評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,204評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,436評論 2 378

推薦閱讀更多精彩內(nèi)容