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