A. gephi中有根據實際距離劃分進行社區劃分的演算法嗎
直接新建文件或打開Gephi文件,初次使用可以打開內置的例子。也可以在菜單欄的「文件(F)」打開或新建文件。Gephi支持gefx/GraphML/Pajek NET/GDF/GML/Tulip TLP/CSV/Compressed ZIP格式。 打開例子LesMiserable.gexf,有一個導入報告。
B. 基於社區發現演算法和圖分析Neo4j解讀《權力的游戲》下篇
其中的分析和可視化是用Gephi做的,Gephi是非常流行的圖分析工具。但作者覺得使用Neo4j來實現更有趣。
節點中心度
節點中心度給出網路中節點的重要性的相對度量。有許多不同的方式來度量中心度,每種方式都代表不同類型的「重要性」。
度中心性(Degree Centrality)
度中心性是最簡單度量,即為某個節點在網路中的聯結數。在《權力的游戲》的圖中,某個角色的度中心性是指該角色接觸的其他角色數。作者使用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
從上面可以發現,在《權力的游戲》網路中提利昂·蘭尼斯特(Tyrion)和最多的角色有接觸。鑒於他的心計,我們覺得這是有道理的。
加權度中心性(Weighted Degree Centrality)
作者存儲一對角色接觸的次數作為 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
介數中心性(Betweenness Centrality)
介數中心性:在網路中,一個節點的介數中心性是指其它兩個節點的所有最短路徑都經過這個節點,則這些所有最短路徑數即為此節點的介數中心性。介數中心性是一種重要的度量,因為它可以鑒別出網路中的「信息中間人」或者網路聚類後的聯結點。
圖6中紅色節點是具有高的介數中心性,網路聚類的聯結點。
為了計算介數中心性,作者使用Neo4j 3.x或者apoc庫。安裝apoc後能用Cypher調用其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)
緊度中心性是指到網路中所有其他角色的平均距離的倒數。在圖中,具有高緊度中心性的節點在聚類社區之間被高度聯結,但在社區之外不一定是高度聯結的。
圖7 :網路中具有高緊度中心性的節點被其它節點高度聯結
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數據科學工具)完美結合。我們繼續使用apoc運行 PageRank和社區發現(community detection)演算法。這里接著使用python-igraph計算分析。Python-igraph移植自R的igraph圖形分析庫。 使用 pip install python-igraph 安裝它。
從Neo4j構建一個igraph實例
為了在《權力的游戲》的數據的圖分析中使用igraph,首先需要從Neo4j拉取數據,用Python建立igraph實例。作者使用 Neo4j 的Python驅動庫py2neo。我們能直接傳入Py2neo查詢結果對象到igraph的 TupleList 構造器,創建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)
現在有了igraph對象,可以運行igraph實現的各種圖演算法來。
PageRank
作者使用igraph運行的第一個演算法是PageRank。PageRank演算法源自Google的網頁排名。它是一種特徵向量中心性(eigenvector centrality)演算法。
在igraph實例中運行PageRank演算法,然後把結果寫回Neo4j,在角色節點創建一個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)
現在可以在Neo4j的圖中查詢最高PageRank值的節點:
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
社區發現(Community detection)
圖8
社區發現演算法用來找出圖中的社區聚類。作者使用igraph實現的隨機遊走演算法( walktrap)來找到在社區中頻繁有接觸的角色社區,在社區之外角色不怎麼接觸。
在igraph中運行隨機遊走的社區發現演算法,然後把社區發現的結果導入Neo4j,其中每個角色所屬的社區用一個整數來表示:
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中查詢有多少個社區以及每個社區的成員數:
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]
角色「大合影」
《權力的游戲》的權力圖。節點的大小正比於介數中心性,顏色表示社區(由隨機遊走演算法獲得),邊的厚度正比於兩節點接觸的次數。現在已經計算好這些圖的分析數據,讓我們對其進行可視化,讓數據看起來更有意義。
Neo4j自帶瀏覽器可以對Cypher查詢的結果進行很好的可視化,但如果我們想把可視化好的圖嵌入到其它應用中,可以使用Javascript可視化庫Vis.js。從Neo4j拉取數據,用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;
其中:
節點帶有標簽Character,屬性name;
節點的大小正比於betweenness屬性;
可視化中包括INTERACTS關系;
關系的厚度正比於weight屬性;
節點的顏色是根據網路中社區community屬性決定;
從本地伺服器localhost拉取Neo4j的數據;
在一個id為viz的DOM元素中展示可視化。
C. 淺談文本分析分詞及關系圖
在文本分析中,我們需要對其文本進行分詞,並對這些分詞統計分析,基於 python , jieba 是很受歡迎的一種分詞庫,而後對分詞之間的關系,當然Python Matplotlib 基於networkx畫關系網路圖也是可以的,但是這里我們將藉助 Gephi 來製作,這個軟體容易上手,這里我們並對其中個別方法進行解釋。
jieba庫是Python中一個重要的第三方中文分詞函數庫,能夠將一段中文文本分隔成中文詞語序列。
jieba庫分詞所用的原理就是把分詞的內容與分詞的中文詞庫進行對比,通過圖結構和動態規劃方法找到最大概率的片語。
支持四種分詞模式:
四種模式分隔舉例:
結果:
由上我們可以發現,我們想要把生態環境、污水處理、有限公司都分開,精確模式和Paddle模式,未分開,全模式和搜索引擎模式雖分開了,但卻也含有未分的片語。所以這里我們可以採用自定義詞典,使用load_userdict(),不過注意的是需要給自定義詞做詞頻,否則自定義詞典不起作用,因為,當自定義詞詞頻低於默認詞典的詞頻時,它還是採用默認分詞,所以我們設定詞頻大於默認詞詞頻時,就會採用自定義詞典的詞分詞。
具體怎麼設置自定義詞典的詞頻數,還沒有具體的公式,越大當然概率越大,只要超過默認詞典即可,但也不宜過大。 默認詞典
自定義詞典
其中 user_dict 定義如下:
jieba簡單介紹及使用介紹到這里,更深層理論及使用可學習這個地址: jieba-github參考
在 圖論 中, 集聚系數 (也稱 群聚系數 、 集群系數 )是用來描述一個 圖 中的 頂點 之間結集成團的程度的系數。具體來說,是一個點的鄰接點之間相互連接的程度。例如生活社交網路中,你的朋友之間相互認識的程度【 基於復雜網路理論的代謝網路結構研究進展 】。有證據表明,在各類反映真實世界的網路結構,特別是 社交網路 結構中,各個結點之間傾向於形成密度相對較高的網群【 TRANSITIVITY IN STRUCTURAL MODELS OF SMALL GROUPS 、 Collective dynamics of 'small-world' networks 】。也就是說,相對於在兩個節點之間隨機連接而得到的網路,真實世界網路的集聚系數更高。
假設圖中有一部分點是兩兩相連的,那麼可以找出很多個「三角形」,其對應的三點兩兩相連,稱為閉三點組。除此以外還有開三點組,也就是之間連有兩條邊的三點(缺一條邊的三角形)。
Clustering coefficient 的定義有兩種; 全局 的和 局部 的。
全局的演算法:
局部的演算法:
平均系數:
下面即分析其系數求解:
接下來我們就以一個實例來分析聚類系數應用,這里我們用到的工具是 Gephi ,數據也是使用其內置的數據。
在上面分析中,我們提到節點大小,代表自身權重,但是有時由於我們的節點范圍導致有些需要辨別的節點不易分析,這時我們可以考慮從顏色入手,即權重從小到大以顏色的變化老判定,當然也可以用同一種顏色通過漸變來判定,這里我是使用了三種顏色變化范圍來分析。如下圖選擇及展示:
由上圖,從顏色上我們選擇了紅黃藍的依次變化情況,右圖我們從節點大小加上顏色更方便判定節點自身的權重了,即自身出現次數越多顏色越靠近藍色,反之靠近紅色。
由上倆個圖的變化可察覺出它們的布局分布是一樣的,那它是什麼原因呢?
如圖結構可分析形成聚合的簇團,是相互之間彈簧吸引的強烈的,也就是說關系比較密切些。
在數據中,我們關系圖是由節點和邊組成,上面都簡要分析了節點的處理,那麼邊怎麼分析呢?其實邊由圖中是可以以線的粗細來判斷倆個詞之間的關系,即出現的次數。如下圖:
由於次數范圍太廣,我們把它們轉化成0--1之間的范圍,以最高權重為1,其它數據以此為基準做轉化。
即為所轉化後的佔比值, 為每個權重值, 為最大權重值
jieba-github參考
Clustering coefficient
ForceAtlas2, A Continuous Graph Layout Algorithm for Handy Network Visualization