强连通和连通算法在关联图谱中的应用

时间:2022-07-24
本文章向大家介绍强连通和连通算法在关联图谱中的应用,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

本文介绍社群发现算法在关联图谱中的应用。社群发现算法是图算法中的一种,图算法是图分析的工具之一。

图算法提供了一种最有效的分析连接数据的方法,它们描述了如何处理图以发现一些定性或者定量的结论。

图算法基于图论,利用节点之间的关系来推断复杂系统的结构和变化。我们可以使用这些算法来发现隐藏的信息,验证业务假设,并对行为进行预测。

一、图论中基本名词

  • 1. 连通图(Connected Graphs):图中任意两点之间都有路相连。
  • 2. 非连通图(Disconnected Graphs):图中存在两点之间没有路相连。
  • 3. 有向图(Directed Graphs):节点的关系指定了方向。
  • 4. 无向图(Undirected Graphs):节点的关系是双向的。
  • 5. 加权图(Weighted Graphs): 节点或边上赋予权重。
  • 6. 未加权图(Unweighted Graphs):节点和边上都没有权重。
  • 7. 循环图(Cyclic Graphs):图中存在一些特殊的路径,它们的起点和终点是同一个节点。注:有向图的路径须需遵循边的方向。
  • 8. 非循环图(Acyclic Graphs):图中不存在循环路径。
  • 9. 子图(Subgraph):一张图的一部分,指节点集和边集分别是某一图的节点集的子集和边集的子集的图。

二、导入数据

把点和关系数据放到import文件夹下,运行如下语句:

using periodic commit 10000 load csv with headers from "file:/node_gzh.csv" as line with line create (:gzh {item:line.item,  trans_amount_sum:line.trans_amount_sum,  trans_cnt:line.trans_cnt,  type:line.type});
CREATE INDEX ON :gzh(item)
using periodic commit 10000 load csv with headers from "file:/node_rela_gzh.csv" as line match (from:gzh {item: line.item_l}),(to:gzh {item:line.item_r}) merge (from)-[c:gzh{relation:line.relation}]-(to)

更详细的数据导入说明参见文章:neo4j中导入数据的两种常用方式(千万级和亿级)

接下来详细阐述社群发现算法在关联图中的应用。

三、强连通算法

1 名词解释

1.两个节点强连通:在有向图G中,若两个节点u和v间有一条从u到v的有向路径,同时还有一条从v到u的有向路径,则称两个节点强连通。

2.强连通图:若有向图G的每两个节点都强连通,则称图G是一个强连通图。

3.强连通分量(Strongly Connected Components,简称SCC):有向图的极大强连通子图。

2 在图中找强连通分量的具体算法

在neo4j中运行如下语句,即可找出图中所有的强连通分量。

CALL algo.scc.stream("gzh","gzh")
YIELD nodeId, partition
MATCH (u:gzh) WHERE id(u) = nodeId
RETURN u.item AS item, partition

注:使用社群发现算法需要在neo4j中安装algo模块,可自行到网上搜寻教程安装。

参数说明:

scc:强连通分量的缩写,代表算法的类型。

gzh:第一个gzh代表节点的标签,第二个gzh代码关系的类型,我在导入数据时都写成了gzh所以是一样的,可根据具体数据调整。

(u:gzh):填入节点标签。

u.item:返回节点的属性,可根据需要自行调整。

得到结果如下:

3 数据分析与查询

对下载(页面中下载箭头)的数据用透视表进行分析排序,得到每一强连通分量中商户的数量,具体结果如下:

为了让大家更清晰地理解这个算法,从结果中挑一个(partition为8634)强连通分量进行回查展示。

在neo4j中运行如下语句:

WITH ['8635',
'8671',
'8698',
'16995',
'17808',
'18121',
'18622',
'18626',
'18688',
'18976',
'24924'
] AS arr
MATCH p=(n)-[]->(m)
WHERE n.item IN arr or m.item IN arr
RETURN p

with中的数据是partition为8634(11个点)组别中的item(商户编号),该语句查找这些节点所有对外的关系构成的子图。

得到结果如下:

图中总计13个点,红框中是11个点构成的强连通分量,任意两个节点之间都强连通。

由于查询的是这个强连通分量中所有点对外关系构成的子图,查到了item为61886的节点还有两个对外的关系。

虽然这11个点有到这两个点的路径,但是这两个点没有11个点的路径,所有这两个点不是这个强连通分量中的一员。

四、连通算法

顾名思义,连通算法是在全量图中寻找连通的子图,其中同一子图中的所有节点构成一个连通的组件。

1 一个通俗易懂的小例子

小胖、小华、小明、小雪、小红、小芳是同班同学,由于疫情好久都没有见面了。

小胖给小华打了3分钟电话,小胖给小明打了10分钟电话。小雪给小红打了11分钟电话,小红给小芳打了5分钟电话。

由上面的描述知小胖、小华、小明三人联系过,小雪、小红、小芳三人联系过。在neo4j中把如上关系转成关联图。

具体语句如下:

create (xiaopang:Person {name:'小胖'})
create (xiaohua:Person {name:'小华'})
create (xiaoming:Person {name:'小明'})
create (xiaoxue:Person {name:'小雪'})
create (xiaohong:Person {name:'小红'})
create (xiaofang:Person {name:'小芳'})

CREATE (xiaopang)-[:LINK {weight: 3}]->(xiaohua)
CREATE (xiaopang)-[:LINK {weight: 10}]->(xiaoming)
CREATE (xiaoxue)-[:LINK {weight: 11}]->(xiaohong)
CREATE (xiaohong)-[:LINK {weight: 5}]->(xiaofang);

先创建点,再创建关系,把通话时长作为关系的权重。

创建好的图如下(有向图):

下面用连通算法寻找大图中的子连通图。

2 未加权连通图算法

不考虑边的权重,在整个图中寻找连通子图,具体语句如下:

CALL algo.unionFind.stream('Person', 'LINK')
YIELD nodeId, setId
RETURN algo.asNode(nodeId).name AS Name, setId AS ComponentId
ORDER BY ComponentId, Name

参数说明:

unionFind:连通分量的英文,代表算法的类型。

Person代表节点标签,LINK代表关系类型。如果不写代表在所有标签和关系中寻找连通子图。

最后返回了组别id和对应节点的名称,并对组别进行排序展示。

注:如果只有一种节点和一种关系可以省略('Person', 'LINK')括号中的内容,直接写一个括号即可。

得到结果:

可以发现小胖、小华、小明三人分在一组,小雪、小红、小芳分在一组。

说明连通不考虑关系的方向,可以理解成把图当成无向图处理,两个点之间只要有边就连通。

那么这个算法有什么用呢?

如果一个犯罪团伙之间有相互转账的关联关系,可以通过连通算法把所有有关联的人员放到一个组别(一张子图)中进行分析。

3 加权连通图算法

在官网中给出了加权连通图算法,可以通边和边的权重对连通图进行一个更细的划分。

具体语句如下:

CALL algo.unionFind.stream('Person', 'LINK', {weightProperty: 'weight',threshold: 4,concurrency:1})
YIELD nodeId, setId
RETURN algo.asNode(nodeId).name AS Name, setId AS ComponentId
ORDER BY ComponentId, Name

如果把threshold设为4,由于小胖和小华的关系weight为3,会把小华单独列为一类。

但是我在运行该代码时一直在报错,欢迎大家在研究过程中和我探讨。

接下来会研究标签传播算法和模块度算法在知识图谱中的具体应用,欢迎大家持续关注。

参考文献

https://blog.csdn.net/Revjie/article/details/100151420
https://blog.csdn.net/qq_42712462/article/details/81409208
https://neo4j.com/docs/graph-algorithms/current/algorithms/wcc/#algorithms-wcc-syntax
https://baike.baidu.com/item/%E5%BC%BA%E8%BF%9E%E9%80%9A%E5%88%86%E9%87%8F/7448759?fr=aladdin