如何更好的分析潜在人脉?聊聊华为云图引擎GES的Cypher子查询

摘要:本文以华为云图引擎 GES 为例,来介绍如何使用图查询语言 Cypher 表达一些需要做数据局部遍历的场景。

本文分享自华为云社区《使用 Cypher 子查询进行图探索 -- 以华为云图引擎 GES 为例》,作者:蜉蝣与海。

在图数据库/图计算领域,很多查询可以使用图查询语言Cypher、Gremlin或者指令式API进行表达,如多跳过滤、全局检索以及对过滤后的结果进行聚集排序等操作。然而有些查询不是那么容易表达,常常需要对图中的一组数据去做局部遍历,例如在社交网络(人-人,人-兴趣的关联网络)场景中,常常涉及以下场景:

  • 朋友推荐:看看小明的朋友的朋友中,哪些不是小明的朋友,进而推荐给小明。
  • 潜在二度人脉分析:选取一组点,每个点代表一个人,在他们朋友的朋友中,统计他们各自有多少不认识的男性朋友和女性朋友。
  • 兴趣推荐A:兴趣爱好也是社交网络中的点,看看小明的朋友有哪些兴趣爱好(人-INTEREST-兴趣),从每个朋友的兴趣爱好中选取至多N个兴趣爱好推荐给小明。
  • 兴趣推荐B:看小明有哪些朋友还没有录入兴趣爱好,允许小明把自己的兴趣爱好推荐给他们。

这些查询往往只关注图中的某个局部,对局部进行多跳查询,且局部上往往有类似下列限制:

  • 数量限制:例如兴趣推荐A场景中,限制了每个朋友的兴趣数目,而不是总数目。
  • 条件限制:例如朋友推荐场景中,“哪些不是小明的朋友”需要先查询小明和朋友的朋友间有没有边,并将结果作为查询条件输入用来过滤。

在查询语言Cypher中,常常使用子查询来解决这类问题。本文会以华为云图引擎GES为例(图引擎版本>=2.3.6),来介绍如何使用Cypher表达上述场景。

注: 本文同步发布至华为云AI Gallery,文中所有代码皆可以在AI Gallery上运行:【AI Gallery】使用Cypher子查询进行图探索 – 以华为云图引擎GES为例。

阅读前准备

基础知识

阅读前需要了解如下基础知识

  • Cypher查询语言的基本结构
    • 关于Cypher样例语句,可以参考:图引擎服务帮助文档-业务面API-Cypher-基本操作和兼容性
    • 关于Cypher的文法说明,可以参考openCypher 9官方页面。
  • Cypher的列表表达式
    • 华为云图引擎GES支持的列表表达式,可以参考图引擎服务帮助文档-业务面API-Cypher-支持的表达式,函数及过程
    • Neo4j 3.5 Cypher Manual - Lists - List Comprehension
    • 对本文中使用到的列表表达式,提前做下述解释:

下方三个小节会指导如何配置一个GES实例并使用notebook连接GES服务进而做查询演示。如果你只想了解如何编写查询语句,对输入的Cypher查询获取返回结果没有需求,可以直接跳过下方三个小节。

本文使用的数据集

本教程使用LDBC-SF0.1社交数据集中截选的人物关系数据集,数据集可以从此处下载。下载后需要在GES中创建图并导入数据集,详细指导流程可参见华为图引擎文档-快速入门和华为云图引擎服务 GES 实战——创图。

如何调用GES的Cypher API

GES官网帮助文档上有GES Cypher的API,为了方便用户调用,API设计为基于http/https请求,响应体的设计也兼容的neo4j的json格式。这里放置一下链接执行Cypher查询。调用API时需要将Token输入请求头中进行鉴权,有关Token的获取问题请参考业务面API认证鉴权。

本文会使用ges4jupyter工具脚本进行相关查询的演示,该脚本中封装了刚刚提到的鉴权&Cypher查询API,并对结果进行了一些处理,提供了相关可视化的能力。

本文使用的代码包

ges4jupyter是jupyter连接GES服务的工具文件。文件中封装了使用 GES 查询的预置条件,包括配置相关参数和对所调用 API 接口的封装,如果你对这些不感兴趣,可直接运行而不需要了解细节,这对理解后续具体查询没有影响。本文的所有语句请求都会访问一个GES实例并得到实际的响应。

import moxing as mox
mox.file.copy('obs://obs-aigallery-zc/GES/ges4jupyter/beta/ges4jupyter.py', 'ges4jupyter.py')
mox.file.copy('obs://obs-aigallery-zc/GES/ges4jupyter/beta/ges4jupyter.html', 'ges4jupyter.html')

GESConfig的参数都是与调用 GES 服务有关的参数,依次为“公网访问地址”、“项目ID”、“图名”、“终端节点”、“IAM 用户名”、“IAM 用户密码”、“IAM 用户所属账户名”、“所属项目”,其获取方式可参考调用 GES 服务业务面 API 相关参数的获取。这里通过read_csv_config方法从配置文件中读取这些信息。如果没有配置文件,可以根据自己的需要补充下列字段。对于开启了https安全模式的图实例,参数port的值为443。

from ges4jupyter import GESConfig, GES4Jupyter, read_csv_config
eip = ''
project_id = ''
graph_name = ''
iam_url = ''
user_name = ''
password = ''
domain_name = ''
project_name = ''
port = 80
eip, project_id, graph_name, iam_url, user_name, password, domain_name, project_name, port = read_csv_config('cn_north_4_graph.csv')
config = GESConfig(eip, project_id, graph_name, iam_url = iam_url, user_name = user_name, password = password, domain_name = domain_name,project_name = project_name,port = port)
ges_util = GES4Jupyter(config, True);

首先在GES中创建索引,这有利于后续查询加速。

import time
def wait_job_finish(util, job_id, max_loop):job_result = util.get_job(job_id)if 'errorCode' not in job_result:for i in range(max_loop):if job_result['status'] == 'success':breakelse:time.sleep(1)job_result = util.get_job(job_id)print(job_result)job_id = ges_util.build_vertex_index()
wait_job_finish(ges_util, job_id, 100)
job_id = ges_util.build_edge_index()
wait_job_finish(ges_util, job_id, 100)

可以使用下列语句查看schema信息:

import time
body = ges_util.generate_schema_structure()
job_id = body["jobId"]
print('开始构造schema结构:')
wait_job_finish(ges_util, job_id, 100)
print('schema结构构造完成')
cypher_result = ges_util.cypher_query("call db.schema()",formats=['row','graph']);
ges_util.format_cypher_result(cypher_result, candidate_title = ['description', 'name'])

如图是本文使用的数据集的schema,主要包括下列类型的点边: 

使用子查询

一般来说,使用Cypher查询朋友的朋友是相对容易的,下列语句演示了如何查询顶点p367朋友的朋友。

match (n)-[:KNOWS]->(a)-[:KNOWS]->(b) where id(n)='p367' return distinct b

然而,使用一般的Cypher语义,从朋友的朋友中移除所有的朋友,表达朋友推荐场景中的“朋友的朋友而非我的朋友”却很困难。文章如何使用GES进行社交关系考据?—GES查询能力介绍中,描述了一种常规的查询语句写法:

match (n)-[:KNOWS]->(a) where id(n)='p367' with n, collect(a) as neighbor
match (n)-[:KNOWS]->(a)-[:KNOWS]->(b) 
where not (b in neighbor)
return b

由于cypher的结果是使用行(Row)组织数据,所有的计算以“行”作为单元进行,如果要进行过滤,只能进行行内过滤。所以上述语句第一步,先通过collect(a),将“朋友”这个集合组织到了一行里,而后才能将collect(a)作为过滤条件,进行二次查询。

将子查询作为查询条件

在GES 2.3.6版本,实现了子查询能力,支持Neo4j中的SemiApply算子,该算子支持类似于下列语句的运行,使得查询更为简洁:

match (n) where id(n)='p367'
match (n)-[:KNOWS*2..2]->(b)
where not (n)-[:KNOWS]->(b)
return id(b) limit 10
cypher_result = ges_util.cypher_query("""
match (n) where id(n)='p367' 
match (n)-[:KNOWS*2..2]->(b) where not (n)-[:KNOWS]->(b) 
return id(b) limit 10""",formats=['row','graph']);
ges_util.format_cypher_result(cypher_result)

注意到这里where条件后面跟从的不是一个一般的条件表达式,不是大于小于这样的比较运算,在条件运算not后跟随了一个图模式(Graph Pattern),整个where条件表示“不存在从顶点n连向顶点b,且label为KNOWS的边”。这样的表达方式使得整条查询语句看起来更为简洁。

也可以使用explain查看其查询计划,可以看到是AntiSemiApply在发挥作用。这里条件查询主要包含两个算子:

  • SemiApply: 用于支撑“where (n)-[:KNOWS]->(b)”这样的条件,表示对应的查询模式存在。
  • AntiSemiApply:用于支撑“where not (n)-[:KNOWS]->(b)”这样的条件,表示对应的查询模式不存在。

这两个算子对每个左子树生成的结果,都去检查右子树是否会/不会产生满足条件的结果,并将右子树的结果作为过滤条件,辅助左子树的结果过滤。

通过这两个算子,即可实现简单的条件子查询。

cypher_result = ges_util.cypher_query("""explain 
match (n) where id(n)='p367' 
match (n)-[:KNOWS*2..2]->(b) where not (n)-[:KNOWS]->(b) 
return id(b) limit 10""",formats=['row','graph']);
ges_util.format_cypher_result(cypher_result)

子查询作为条件,也可以用来描述兴趣推荐B场景:看小明有哪些朋友还没有录入兴趣爱好,允许小明把自己的兴趣爱好推荐给他们。

match (n:Person) where id(n)='p933' 
match (n)-[r]->(m) where not (m)-[:HAS_INTEREST]-() return id(m)

将子查询作为中间结果

此外,还可以将子查询作为中间结果,朋友推荐场景下,cypher语句还可以这么写:

match (n) where id(n)='p367' 
with [(n)-[:KNOWS*2..2]->(b)|id(b)] as hop2,  [(n)-[:KNOWS]->(b)|id(b)] as hop1
return [x in hop2 where not x in hop1|x] limit 10

在这条查询语句中,Graph Pattern出现在了with子句中,用于收集某个点的多跳结果。

另外采用类似的写法还可以筛选三度好友中“我不认识的人”的数目,示例如下:

match (n) where id(n)='p367' 
with [(n)-[:KNOWS*3..3]->(b)|id(b)] as hop3,  [(n)-[:KNOWS*1..2]->(b)|id(b)] as hop2
return size([x in hop3 where not x in hop2|x])
cypher_result = ges_util.cypher_query("""
match (n) where id(n)='p367' 
with [(n)-[:KNOWS*3..3]->(b)|id(b)] as hop3,  [(n)-[:KNOWS*1..2]->(b)|id(b)] as hop2 
return size([x in hop3 where not x in hop2|x])""",formats=['row','graph']);
ges_util.format_cypher_result(cypher_result, boxHeight=200)

同时这种子查询后续步骤也可以跟随一些过滤条件,进行各类统计操作,如上述提到的潜在二度人脉分析

match (n:Person) where id(n) in ['p367','p13194139534836','p932','p4398046512206','p6597069767359'] 
with n, [(n)-[:KNOWS*2..2]->(m) where not (n)-->(m)|m] as recSet
return id(n) as key, size([x in recSet where x.gender='male']) as maleNumber,size([x in recSet where x.gender='female']) as femaleNumber
cypher_result = ges_util.cypher_query("""
match (n:Person) where id(n) in ['p367','p13194139534836','p932','p4398046512206','p6597069767359'] 
with n, [(n)-[:KNOWS*2..2]->(m) where not (n)-->(m)|m] as recSet 
return id(n), size([x in recSet where x.gender='male']),size([x in recSet where x.gender='female'])
""",formats=['row','graph']);
ges_util.format_cypher_result(cypher_result, boxHeight=200)

下列元素出现在with子句中,描述了一个子查询:

[(n)-[:KNOWS*2..2]->(m) where some-condition|m] as recSet

这里会对每个遍历到的n,都进行二跳查询, 取二跳查询的末端节点m,然后组装成一个列表。

注意到where条件中,使用了刚刚提到的条件子查询:

where not (n)-->(m)

这里条件使用where条件,对子查询的结果进行了过滤,且过滤时,是将一个Graph Pattern作为的过滤条件,最后使用竖线进行投影。

在return子句中,使用了Cypher中List Comprehension的语法,进行列表过滤,并获取大小:

return id(n) as key, size([x in recSet where x.gender='male']) as maleNumber,size([x in recSet where x.gender='female']) as femaleNumber

支撑子查询结果作为中间结果的,是RollUpApply算子,可以通过explain看到其在查询计划中发挥价值:

cypher_result = ges_util.cypher_query("""explain 
match (n:Person) where id(n) in ['p367','p13194139534836','p932','p4398046512206','p6597069767359'] 
return n, [(n)-[:KNOWS*2..2]->(m) where not (n)-->(m)|m] as recSet""",formats=['row','graph']);
ges_util.format_cypher_result(cypher_result, boxHeight=200)

对每个左子树生成的结果(这里是(n:Person))都会作为变量输入,并执行右子树,选取右子树结果的值打包为list返回。

此外还可以限制子查询的数目,对查询进行PerNodeLimit(单点跳出限制:每个点每层只能向外跳出限定个数的顶点)。

例如兴趣推荐A场景中,看看小明的朋友有哪些兴趣爱好(人-INTEREST-兴趣),从每个朋友的兴趣爱好中选取至多N个兴趣爱好推荐给小明。

match (n:Person) where id(n)='p367' 
match (n)-[r]->(m) 
return [(m)-[:HAS_INTEREST]-(a)|a][0..3]

为了可视化演示效果,可视化时同步打印了“朋友”和“INTEREST”边。

同样的,也可以使用RollUpApply+Limit对每跳做PerNodeLimit,例如统计和小明的朋友有共同兴趣爱好的朋友,每个顶点每跳最多找3个点,最后一跳每个点最多找1个点:

match (n:Person) where id(n)='p367' 
match (n)-[r]->(m) with m limit 3 
with m,[(m)<-[r1:HAS_INTEREST]-(a)|a][0..3] as interests 
unwind interests as interest 
with interest, [(interest)-[r1:HAS_INTEREST]->(a) where not (a)--(m)|[r1,a]][0..1] as soulMate
return *

其他子查询

使用with也可以实现其他子查询任务,例如上一跳的查询结果经过limit限制后输入下一跳,成为查询条件:

match (n:Person) where id(n) in ['p367','p13194139534836','p932','p4398046512206','p6597069767359'] 
with n limit 10
match (m:Person{lastName:n.lastName}) return n.lastName, m.firstName

使用explain也可以看到其查询计划:

cypher_result = ges_util.cypher_query("""explain 
match (n:Person) where id(n) in ['p367','p13194139534836','p932','p4398046512206','p6597069767359'] 
with n limit 10
match (m:Person{lastName:n.lastName}) return n.lastName, m.firstName""",formats=['row','graph']);
ges_util.format_cypher_result(cypher_result)

由于不同的n,其n.lastName的值是不固定的,所以需要针对每个n,去做match (m:Person{lastName:n.lastName})这样的查询,因此需要使用Apply子查询算子支撑这样的语句。

总结

借助子查询进行局部遍历是图查询中的常用操作,将子查询作为过滤条件或者中间结果辅助查询,可以满足某些业务场景下对查询局部有限制的诉求,如文中提到的社交网络分析,再如股权关系中穿透层数分析、装备制造和配置管理(IT设备管理)领域依赖识别和变更影响分析等。

此外,由于Cypher以行的形式组织数据,某些情况下使用子查询可以节省中间结果产生,加速Cypher查询的执行。

当然,使用更高效的API(如GES产品中有多跳过滤API)或者使用非行存的查询执行引擎也是可选的解决方案。

点击关注,第一时间了解华为云新鲜技术~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/33422.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于面板数据的熵值法介绍与实现

熵值法是一种基于信息熵理论的客观赋值方法。即数据越离散&#xff0c;所含信息量越多&#xff0c;对综合评价影响越大。 目录 一、基于面板数据熵值法介绍二、R语言实现参考文献 一、基于面板数据熵值法介绍 传统的熵值法有个弊端&#xff0c;只能针对于截面数据&#xff0c;…

信息熵的计算

信息熵计算公式&#xff1a; 演示数据&#xff1a; 性别&#xff08;x&#xff09;考试成绩&#xff08;y&#xff09;男优女优男差女优男优 X的信息熵计算为&#xff1a; p(男) 3/5 0.6 p(女) 2/5 0.4 根据上面的计算公式可得&#xff1a; 列X的信息熵 为&#xff1a; H&…

各种信息熵(Information entropy)的计算方法

一、Jensen不等式 若f为区间I上的凹函数&#xff0c;则Jensen不等式成立&#xff1a; 这里若函数f为凹函数&#xff0c;则有&#xff1a; 凹函数&#xff08;上凸&#xff09;如下图所示&#xff1a; 归纳证明&#xff1a; 二、信息论 1.熵&#xff08;信息不确定性度…

信息与信源熵

0x01 三个定义 信息 指各个事物运动的状态及状态变化的方式。人们从对周围世界的观察得到的数据中获得信息。信息是抽象的意识或知识&#xff0c;它是看不见、摸不到的。当由人脑的思维活动产生的一种想法仍被存储在脑子里时&#xff0c;它就是一种信息。 消息 指包含信息的…

python计算图片的信源熵值(信息熵)

附录&#xff1a; from PIL import Image from matplotlib import pyplot as plt import numpy as np import scipy as cp import math image Image.open(rC:\Users\Administrator\Desktop\IMG.jpg) # 读入和显示图像 imagesnp.asarray(image) plt.subplot(211) plt.imshow(im…

【熵的计算】

熵的计算 什么是熵&#xff1f; 定义&#xff1a; 熵是表示随机变量不确定性的度量 简单理解&#xff1a;熵就是混乱程度&#xff0c;一个集合中类别越多&#xff0c;越混乱&#xff0c;属于哪一个类别越不确定。 熵的计算公式&#xff1a; 简单理解一下公式&#xff1a; …

信息熵计算及代码

实验目的:了解离散信源数学模型和信息熵实验内容:以附件中英文文本文件中的内容为来源&#xff0c;构建26个英文字母(区分大小写)为信源符号的数学模型&#xff0c;要求输出字母的概率和该模型的信息熵。要求:请使用自己熟悉的编程语言&#xff0c;完成信源建模&#xff0c;输出…

信息熵的计算与分析

信息熵的计算与分析 一、[实验目的]二、[实验环境]三、[实验原理]四、[实验内容]五、[实验过程]1、二元信源熵函数曲线2、求解离散单符号信源熵3、计算图像一维图像熵 一、[实验目的] 1、掌握离散信源熵的原理和计算方法。 2、熟悉matlab 软件的基本操作&#xff0c;练习使 用…

【chatgpt】解除PDF的password

无论是Adobe Acrobat Pro还是Pdf xchange editor都是一样的&#xff0c;更改安全性就可以了。 把该加密Pdf导入软件&#xff0c;然后点文件&#xff0c;属性&#xff0c;安全性&#xff0c;改成无安全后确定就行了。 pdf是可携带文件格式&#xff0c;亦称“PDF(portable docum…

免费好用的聊天机器人上线,原Openai前员工们创立的Claude

1.下载slack,注册登录。 2.在claude网站上同意Al与你的slack账号相联接。 3.在slack里就可以直接与AI对话了。 4.网页端Mac、苹果手机、安卓都可以&#xff0c;win没试过&#xff0c;应该也可以。 具体的细致操作网上有&#xff0c;也可以留言讨论。 Anthropic是一家总部位…

国内又款智能AI聊天软件-科大讯飞星火模型

介绍 介绍 中国科大讯飞星火GPT聊天软件是一款基于自然语言处理技术的人工智能聊天机器人。它利用了大量的文本数据&#xff0c;通过深度学习模型进行训练&#xff0c;从而实现与用户的智能对话。讯飞星火GPT聊天软件能够理解用户输入的问题或指令&#xff0c;并根据预设的回答…

启英泰伦推出多种智能语音识别照明解决方案,改装简单,成本低

随着人工智能技术的普及&#xff0c;智能家居设备开始走进千家万户。而智能照明系统成为其不可或缺的一部分&#xff0c;占据着举足轻重的地位。 但是照明系统和其他家居设备不一样的是&#xff0c;开发商交房时已布好电路&#xff0c;或用户直接购买精装房&#xff0c;导致改…

让 ChatGPT 更智能,Tauri 带你实现 AI 对话应用

背景 Tauri 和 Electron 都是用于开发跨平台桌面应用程序的工具&#xff0c;因为最近使用ChatGPT在国内环境的确不够友好&#xff0c;又没有一个比较轻量简洁的工具可用&#xff0c;如是想自己造个轻量点的轮子&#xff0c;力争做到代码轻量&#xff0c;界面美观简洁&#xff…

[AI达人特训营第三期] 使用Lora技术用Dreambooth训练国潮风格模型

★★★ 本文源自AlStudio社区精品项目&#xff0c;【点击此处】查看更多精品内容 >>> DreamBooth 介绍 DreamBooth: Fine Tuning Text-to-Image Diffusion Models for Subject-Driven Generation是一种新的文本生成图像(text2image)的“个性化”&#xff08;可适应用…

【社群运营】AI智能对话,打造自动化社群

人工智能大背景下&#xff0c;各行各业都在往智能化发展&#xff0c;无论是办公产品&#xff0c;还是生产器械都选择接入了更加智能的AI来提高生产效率。那么&#xff0c;在日常的社群管理工作中&#xff0c;我们又能否跟上这一波热度&#xff0c;让社群自动化高效运营&#xf…

夏杰语音麦克精灵:智能语音交互升级新体验

对于很多人来说&#xff0c;通过语音声控电视、空调等家电已经不再陌生。 “你好小智&#xff0c;我想听音乐”、“你好小智&#xff0c;播放深圳卫视”……近几年&#xff0c;“小智”逐渐被人认识。是的&#xff0c;它是夏杰语音旗下的一款智能精灵——麦克精灵。它不仅可以…

跟着我学 AI丨ChatGPT 详解

随着人工智能的发展&#xff0c;聊天机器人成为了一个备受关注的领域。而ChatGPT作为其中的佼佼者&#xff0c;其功能和技术水平也越来越受到人们的关注。那么&#xff0c;什么是ChatGPT&#xff1f;它又有哪些优点和限制呢&#xff1f; ChatGPT是一款基于自然语言处理技术开发…

小红书内容种草,曝光渠道分析总结

这是一个内容为王的时代&#xff0c;也是一个内容爆炸的时代。想要在以分享特色的小红书平台&#xff0c;实现内容种草&#xff0c;迅速出圈。今天来马文化传媒就从实操的角度&#xff0c;为大家带来小红书内容种草&#xff0c;曝光渠道分析总结的各种干货&#xff01; 一、什…

小红书达人账号数据分析

文章目录 一、项目背景二、数据预处理1、查看数据2、数据清洗2.1对达人列表进行清洗2.2对涨分榜进行清洗2.3对MCN列表进行清洗2.4对定性变量&#xff08;分类变量&#xff09;进行处理 3、表格处理3.1合并达人列表和涨粉榜 三、分析与数据可视化1、对达人列表进行相关性分析2、…

小红书账号分析丨千瓜指数高的小红书账号是否真的优质?

关键词&#xff1a;千瓜指数、小红书数据、小红书账号分析 达人账号质量是否优质从多个维度衡量&#xff0c;千瓜指数能够客观综合评价达人账号的质量&#xff0c;给到小红书达人一定的参考价值。 那么千瓜指数能够帮助达人什么&#xff1f; 品牌筛选达人会选择更优质的&#x…