• [问题求助] 基于图数据库的OneID实现思路
    传统车企,公司想做B、C端用户数据的融合,基于OneID技术实现对用户的统一管理,有大侠在这方面做个探索吗?也就是说,基于图数据库如何实现OneID的存储和计算,以便更高效的对OneID进行算法升级等工作
  • [热门活动] 资讯|中国图数据库,领导者!
    近日 ,全球领先的IT市场研究和咨询公司IDC发布《IDC MarketScape: 中国图数据库市场厂商评估,2023》报告华为云GES(图引擎服务)凭借多年的技术积累和丰富的行业实践经验位居领导者类别IDC MarketScape报告中指出:“华为云GES作为拥有自主知识产权的国产分布式原生图数据库和图引擎产品,提供一站式的图存储、图查询和图计算能力,支持30+高性能算法,覆盖多场景分析计算,具备10+图神经网络和图嵌入算法。广泛应用于互联网、政务、安平、税务、电力等行业,为客户的辅助决策、降本增效等提供专业、高效的服务。”深耕技术,让GES应用更高效随着数字化转型的加速,企业的业务数据已经出现多源异构、关联复杂的特点,Graph(图)技术作为处理异构数据的技术应运而生。图数据分析平台将作为大数据、数仓的加持,成为企业数据分析的重要基础平台华为云GES集图数据库和图分析引擎一体化,具备完善的图分析、图查询、图可视化能力,作为中国首个商用的、拥有自主知识产权的原生图产品,具备以下几个优势:分析查询一体化一份数据做两件事:查询和分析一体化, 提供丰富的图分析算法,为关系分析、路径规划、精准营销等业务提供多样的分析能力;支持Cypher和Gremlin两种主流图查询语言,兼容客户的使用习惯;内置30+高性能算法,覆盖多场景分析计算,具备10+图神经网络和图嵌入算法大规模、高性能得益于高效的数据组织,华为云GES可以让客户有效地对百亿节点千亿边规模的数据进行查询和分析;深度优化的分布式图计算引擎,可以为客户提供高并发、秒级多跳的实时查询能力,查询和算法性能业界领先,6跳查询秒级响应。简单易用,支持no-code可视化分析华为云GES支持no-code图建模、实体的下钻、筛选展示以及算法调参等功能,可实现0代码完成图的构建和分析;除此之外,它还提供0门槛创建和使用图的功能,还可以针对部分场景,支持built-in操作,即开即用。合作共赢,让GES应用更全面依托于强大的科研能力,华为云GES已经在政务、金融、互联网等多个行业实践并取得明显应用效果,并已服务超过50家客户。可广泛应用于社交关系分析、营销推荐、数据血缘、信息传播、团伙挖掘、金融风控、工业互联网等具有丰富关系数据的场景。政务行业多地政府部门早已实现“数字化”办公,但是原有平台无法及时处理海量、复杂的业务诉求。以某市12345热线为例,平均一个月需要处理60多万单市民诉求,热线响应速度慢,工单处置能力有限。通过和华为云GES合作,借助大数据AI手段使得工单处理效率提升60%,热线接通率提升20%,市民满意度提升至87%,大大提升了政府服务水平。金融行业随着金融数字化进程,电子支付已是大势所趋,但同时也存在薅羊毛、恶意套现等欺诈手段,如何在海量数据中甄别异常用卡、异常套现,已是金融卡风控的重要一环,业界图数据库产品,大多数不提供内置算法。华为云GES内置了30+算法,能快速帮助金融分析师,从海量数据中快速甄别异常用卡情况例如在金融反欺诈场景中,利用GES内置的丰富算法,可实现业务6跳查询秒级响应,环路检测分钟级响应,将担保风险感知由原先几十分钟降为1分钟左右,帮助客户挖掘出潜在的风险,为客户保驾护航。互联网行业客户面临自建基础设施成本高、应用上线周期长、已有方案效率低以及推荐效果不佳等挑战。基于华为云GES,可实现好友、商品或者咨询的个性化推荐,准确率高达80%;通过对用户画像、行为相似度或者好友关系等,进行用户分群,实现用户群体分析管理,效率提升高达90%;通过企业投资、控股等关联关系,提供企业间深度追溯的能力,实现了原先开源图数据库不能满足“一键穿透公司股权全景”的功能。 持续创新,让GES能力更专业在华为开发者大会2023(Cloud)上,华为云盘古大模型3.0重磅发布,华为云GES依托盘古大模型的多模态知识图谱和图嵌入的知识表征,可支持图神经网络算法,提升识别效果,辅助客户决策。未来,华为云GES将持续加大与数据分析平台以及盘古大模型的深度融合,继续坚持技术创新,为企业提供更灵活、更融合、更智能的服务,加速企业数字化转型,共创数字化新未来。关于IDC MarketScape:IDC MarketScape厂商评估模型旨在为特定市场中信息和通信技术(ICT)厂商的竞争力提供一个概述。研究方法采用严格的定性和定量的标准的评分方法,以单一的图形说明每个厂商在特定市场中的位置。IDC MarketScape提供了一个清晰的框架,在其中可以对IT和信息通信技术厂商的产品、服务、能力和策略以及当前和未来的市场成功因素进行有意义的比较。该框架还为技术买家提供了针对当前或潜在厂商的360度优劣势评估,为技术买家提供参考。
  • [问题求助] Node2Vec各个参数说明
    我想请问下,和这个“映射维度”可以解释详细一下么,一般怎么去确定这个范围x
  • [通用服务] 【AI使能】GES图引擎
    图引擎服务(Graph Engine Service,简称GES),使用华为自研的EYWA内核,是针对以“关系”为基础的“图”结构数据,进行查询、分析的服务。广泛应用于社交关系分析、营销推荐、舆情及社会化聆听、信息传播、防欺诈等具有丰富关系数据的场景。分类文档链接备注最新动态cid:link_5 特性清单cid:link_2 原子APIcid:link_3 FAQcid:link_4 华为云在线课程(免费)图引擎服务https://education.huaweicloud.com/courses/course-v1:HuaweiX+CBUCNXE008+Self-paced/about?isAuth=0&cfrom=hwc图引擎服务(Graph Engine Service),是针对以“关系”为基础的“图”结构数据,进行查询、分析的服务。广泛应用于社交关系分析、推荐、精准营销、舆情及社会化聆听、信息传播、防欺诈等具有丰富关系数据的场景。华为云培训服务(收费)基于图引擎的医药查询系统cid:link_1如何在当前琳琅满目的药品中选取合适自己病症的良药呢?在人工智能发展迅猛的当下,让AI为选取药品贡献一份力量吧。华为云开发者网GES开放能力cid:link_6 
  • 持续更新!图引擎服务GES优质文章精选汇总!
    华为GES图引擎服务优质博文精选图数据基础知识 & GES介绍人人都在谈的图数据库到底是个啥? 作者:你好_TT, 2021-05-08从零开始学Graph Database:什么是图 作者:弓乙, 2022-10-08画张图,就能秒级洞察千亿复杂关系 2021-01-12华为云新一代黑科技核心算法揭秘 作者:mr.FangYang, 2018-08-21云图说-解析华为云”黑科技“---图计算技术 作者:阅识风云, 2018-07-10聊聊图的相似性 作者:你好_TT, 2021-12-25图算法实践之k-hop 作者:你好_TT, 2021-05-12GES容灾介绍  2023-07-22【干货】华为云图数据库GES技术演进 作者:Chenyi, 2023-08-23华为云GES:十年磨一剑,打造业界一流的云原生分布式图数据库 2023-08-24GES使用指引 &图进阶学习华为云图引擎服务 GES 实战——创图 作者:你好_TT, 2021-08-22调用 GES 服务业务面 API 相关参数的获取 作者:你好_TT, 2021-08-23图数据库对 NULL 属性值支持情况 作者:你好_TT, 2021-06-18Gremlin语言学习系列链接汇总 作者:你好_TT, 2021-02-05如何使用GES进行社交关系考据?---GES查询能力介绍 作者:弓乙, 2021-10-19聊聊图上超级快的多跳过滤查询 作者:弓乙, 2023-4-12使用GES4Jupyter连接GES并进行图探索 作者:蜉蝣与海, 2022-06-25使用参数化查询提高Cypher查询的性能 作者:蜉蝣与海, 2022-04-10记一次图引擎GES cypher慢查询的分析与优化作者:蜉蝣与海, 2022-05-08GES对图细粒度权限控制的支持 作者:你好_TT, 2021-12-29使用Cypher子查询进行图探索 作者:蜉蝣与海, 2023-05-10华为云图引擎服务GES属性管理进阶 2024-01-15GES场景化应用全链路数据血缘在满帮的实践 作者:你好_TT, 2021-12-09GES与Flink的对接 作者:你好_TT, 2021-12-29要想推荐系统做的好,图技术少不了 作者:你好_TT, 2021-12-27图计算助力智慧金融 作者:你好_TT, 2020-04-18扒一扒GES如何赋能互联网电商风控 作者:Dr Thunder, 2021-04-23使用GES处理金融风控场景示例一 作者:图森破, 2020-05-19基于人货场的电商知识图谱的构建 作者:某某人, 2020-07-04采用GES构建锅炉仿真系统的关系图谱 作者:犀牛, 2020-06-28基于GES图数据库的网络架构模型构建 作者:左手看星星, 2020-07-29华为云ModelArts与图引擎联手打造,图深度学习强势落地! 作者:我们都是云专家, 2019-08-08基于GES图数据库的大规模数据追溯服务优化 2021-03-03618 技术特辑(一)不知不觉超预算3倍,你为何买买买停不下来? 作者:技术火炬手, 2021-06-11云图说-复杂网络的破解之道,图引擎带你径直迈向成功作者:阅识风云, 2019-10-16云图说-互联网应用的关系分析利器——企业EI的百晓生“图引擎”作者:阅识风云, 2019-04-19爱库存X华为云:乘“云”破浪,逐梦新电商: 外部链接 云社区链接构建站点数字孪生,支撑确定性运维:华为云九洲云图CloudMap 作者:HWCloudAI 2023-03-315分钟迁移关系型数据库到图数据库 作者:RiverSide 2023-07-17HyG超大规模图计算引擎专题GES图计算引擎HyG揭秘之图切分 作者:π, 2022-06-23CSR格式如何更新? GES图计算引擎HyG揭秘之数据更新 作者:π, 2023-06-15图神经网络 & 图深度学习专题图嵌入&知识表征の初体验 作者:图森破, 2020-05-15在OCR场景使用GCN图卷积 作者:图森破, 2020-06-11风控领域图深度学习算法思考 作者:图森破, 2020-07-14知识图谱trans系列算法介绍 作者:图森破, 2021-06-29图嵌入算法介绍 作者: 图森破, 2021-06-29图神经网络!打开企业盈利的下一个风口 作者:chenyi, 2019-12-28图卷积神经网络初探 作者:chenyi, 2019-11-29图技术漫谈Neo4j闭源转商,成为强大图计算平台还需要几步?作者:chenyi, 2019-12-28Freebase Data Dump结构初探, 作者:蜉蝣与海, 2021-07-27带你认识图数据库性能和场景测试利器LDBC SNB, 作者: 闹闹与球球, 2022-06-24从图引擎平台技术,看华为云EI的决心和野心作者:chenyi, 2018-01-29使用Jupyter可视化图查询语言Cypher语法树 作者:蜉蝣与海, 2022-08-22Euler浅析 作者:弓乙, 2019-01-23从两个开源图数据库PR看查询执行时的编码设计问题 作者:蜉蝣与海, 2022-05-03Notebook案例精选图数据库实践-新冠患者轨迹追溯电商风控案例教育知识图谱利用图数据库研究COVID-19论文数据集基于图引擎的医药查询系统Koolab新冠患者轨迹追溯端边云Serverless大数据湖解决方案附录:GES首页:cid:link_21GES最新动态:cid:link_17AI训练营图数据库系列 作者:Ray博士第一讲第二讲第三讲开发者中心-图引擎服务GES开发指南:cid:link_0GES帮助文档:cid:link_9GES算法API参数参考:cid:link_11
  • [技术干货] 图数据库实践--COVID-19患者轨迹追溯
    图数据库实践--COVID-19患者轨迹追溯背景COVID-19 大流行的形势依然很严峻,新冠疫情确诊患者的轨迹信息成为疫情发展过程中大众关注的焦点,政府部门也陆续公开了部分确诊患者的非隐私信息,这部分数据为相关研究人员研究疫情的传播与防控提供了重要的数据支撑。 然而,公布的数据多为文本等非结构化数据,而且极其分散,难以直接为后续研究提供深度的支撑。患者的轨迹信息蕴含居家、出行、餐饮等丰富的接触关系,在新冠病毒人传人的特性下,如果能直观地展示这些接触信息,相信能对疫情的研究提供很大的帮助。基于此,我们利用相关技术手段从公开的病患轨迹数据抽取了病患相关的基本信息(年龄、性别等)、轨迹、病患关系等数据,并利用图数据库技术对其进行研究,尝试为政府相关部门对疫情的传播与防控工作提供有效的决策支撑。数据建模首先我们需要构建新冠疫情轨迹数据的图数据模型。图数据模型中的实体包括患者、轨迹点、交通工具等,实体关系包括居住于、逗留过等,具体的图模型见下图: 图模型中包含了四类点和六类边,元信息说明如下: 数据集我们采集了近期“旅行团疫情”公开的部分轨迹文本数据,根据设计的图模型对数据格式进行转换,转换后的数据可从此处下载。这份数据包含800+个点,1300+条边。创图我们下面将使用华为云图数据库 GES 对以上数据集进行探索和演示,我们需要先在 GES 中创图并将以上数据集导入,详细指导流程可参见华为图引擎文档-快速入门和华为云图引擎服务 GES 实战——创图。使用 GES 查询的预置条件首先通过moxing包从对象存储服务obs中下载ges4jupyter。ges4jupyter是jupyter连接GES服务的工具文件。文件中封装了使用 GES 查询的预置条件,包括配置相关参数和对所调用 API 接口的封装,如果你对这些不感兴趣,可直接运行而不需要了解细节,这对理解后续具体查询没有影响。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 支持 cypher和gremlin 两种查询语言,这里的查询示例以cypher举例。 在使用 cypher 查询之前,我们先创建点索引和边索引(可直接点击GES画布右下角“创建索引”按钮)。print('开始创建点索引:') job_id = ges_util.build_vertex_index() job_result = ges_util.get_job(job_id) if 'errorCode' not in job_result: for i in range(100): if job_result['status'] == 'success': break else: time.sleep(1) job_result = ges_util.get_job(job_id) print('点索引创建完成')print('开始创建边索引:') job_id = ges_util.build_edge_index() job_result = ges_util.get_job(job_id) if 'errorCode' not in job_result: for i in range(100): if job_result['status'] == 'success': break else: time.sleep(1) job_result = ges_util.get_job(job_id) print('边索引创建完成')查询演示首先查询这份图数据的统计信息,对全图的点边数目有所了解:import json print('统计信息:') result = ges_util.summary() format_result = json.dumps(result, indent=4) print(format_result)使用查询语言获取前10条边以及其顶点,对数据有个粗略的了解(建议使用nodebook打开并连接GES服务,可以看到运行后数据可视化的效果):cypher_result = ges_util.cypher_query("match (n)-[r]->(m) return n,r,m limit 10",formats=['row','graph']); ges_util.format_cypher_result(cypher_result)对于数据中的城市,采集了部分城市的防疫政策。了解其他城市的防疫政策,有助于规划出行。print('查看各个城市的防疫政策:') statement = "match (m:city) return id(m), m.防疫政策" result = ges_util.cypher_query(statement) format_result = ges_util.format_cypher_result(result) format_result在现实中,随着采集到更多的数据,不免对原有的数据进行更新,比如新发现关联患者,就涉及到节点和边的增加操作。假设北京新增病例40,其与原有北京病例39是亲属关系。print('数据更新:') print('先查询点是否存在:') vertex_id = '北京病例40' statement = "match (p) where id(p) ="' + vertex_id + '" return p" result = ges_util.cypher_query(statement) if len(result) == 0: print('该节点不存在,增加该节点:') label = 'patient' property_name = '性别' value = '男' ges_util.add_vertex(vertex_id, label, property_name, value) print('再次查询该节点:') statement = "match (p) where id(p) ='" + vertex_id + "' return p" result = ges_util.cypher_query(statement) format_vertex_detail = json.dumps(result[0]['data'], indent=4, ensure_ascii=False) print(format_vertex_detail) print('增加关联边:') source = '北京病例39' target = '北京病例40' label = 'relation' property_name = '类型' value = '家人' ges_util.add_edge(source, target, label, property_name, value) statement = "match (p)-[r]-(m) where id(p)='" + source + "' and id(m)='" + target + "' return r" result = ges_util.cypher_query(statement) format_edge_detail = json.dumps(result[0]['data'], indent=4, ensure_ascii=False) print(format_edge_detail) else: print('该节点已存在')对数据做宏观把控,往往有助于判断疫情趋势。可以对数据从不同维度做统计。 下面会从空间(城市地区风险)、时间(增长趋势)、年龄(患者年龄分布)等维度做统计。首先通过查询语句查看本轮疫情已经波及到的城市及每个城市疫情的严重程度。print('查看有确诊病例的城市并按确诊人数排序:') statement = "match (m:city)<-[r:comfirm]-(p:patient) with m, count(p) as patientNum return id(m), patientNum order by patientNum desc" result = ges_util.cypher_query(statement) format_result = ges_util.format_cypher_result(result) format_result目前中高风险区域的判断,是以区域确诊病例数目划分的。统计不同地域的确诊病例数目,可以判断各个区域的风险。print('将图数据库中的轨迹点,按涉及的确诊病例数目多少进行统计,并从按病例数目从多到少排序:') statement = "match (m:place)<-[s:stay]-(p:patient) with m, count(p) as patientNum return id(m), patientNum order by patientNum desc limit 10" result = ges_util.cypher_query(statement) format_result = ges_util.format_cypher_result(result) format_result此外对此轮疫情患者的年龄做一个调查,以了解此轮疫情中病毒传播的特点。print('查看全国患者年龄构成并按人数排序:') statement = "match (p:patient) where p.年龄 is not null return p.年龄, count(*) as m order by m desc limit 10" result = ges_util.cypher_query(statement) format_result = ges_util.format_cypher_result(result) format_result从时间维度统计确诊病例数目,往往会反映疫情的趋势,疫情是否得到了有效的控制。city_id = '石家庄市' print('查看{}每天确诊人数:'.format(city_id)) statement = "match (p:patient)-[r:comfirm]->(m:city) where id(m)='" + city_id + "' return r.时间, count(*) order by r.时间 asc" result = ges_util.cypher_query(statement) format_result = ges_util.format_cypher_result(result) format_result除了宏观上的统计,我们会关注重点区域(如景区、机场)等,是否和确诊病例发生交集。statement = "match (n)-[r]-(m) where id(n)='胡杨林景区' return n,r,m" result = ges_util.cypher_query(statement,formats=['row','graph']) ges_util.format_cypher_result(result)此外,我们可以对重点人员进行探索,分析其接触史,查询与该患者有直接关联关系的其他患者或地点等,探查可能的传播路径和圈定可疑人群。statement = "match (n)-[r]-(m) where id(n)='额济纳旗病例1' return n,r,m" result = ges_util.cypher_query(statement,formats=['row','graph']) ges_util.format_cypher_result(result)patient_id = '额济纳旗病例1' print('查看{}的活动轨迹:'.format(patient_id)) statement = "match (p:patient)-[r]->(m:place) where id(p)='" + patient_id + "' return id(p), r.时间, type(r), id(m) order by r.时间 asc" result = ges_util.cypher_query(statement) format_result = ges_util.format_cypher_result(result) format_resultpatient_id = '额济纳旗病例1' print('查看与{}有直接关联的患者:'.format(patient_id)) print('要么同时到过某地点:') statement = "match path = (p:patient)-[r1]-(m:place)-[r2]-(n:patient) where id(p)='" + patient_id + "' and id(p) <> id(n) and r1.时间 = r2.时间 return id(p), id(m), id(n), r1.时间, path" result = ges_util.cypher_query(statement,formats=['row','graph']) format_result = ges_util.format_cypher_result(result) format_resultprint('要么是某种亲密关系:') patient_id = '额济纳旗病例1' statement = "match path = (p:patient)-[r]-(n:patient) where id(p)='" + patient_id + "' return id(p), id(n), r.类型, path" result = ges_util.cypher_query(statement,formats=['row','graph']) format_result = ges_util.format_cypher_result(result) format_result此轮疫情源头是在额济纳旗,那么疫情又是怎么传到北京的呢?statement = "match path=(p:patient)-[]-(m:city) where id(m)='额济纳旗' and not (tostring(id(p)) contains '额济纳旗') return path" statement += " union match path=(p:patient)-[]-(m:city) where id(m)='北京' and not (tostring(id(p)) contains '北京') return path" result = ges_util.cypher_query(statement,formats=['row','graph']) ges_util.format_cypher_result(result)可以枚举所有在北京确诊的患者,通过最短路算法,检查其与额济纳旗之间的关系。import copy statement = "match (p:patient)-[r:comfirm]-(m:city) where id(m)='北京' return collect(distinct id(p))" result = ges_util.cypher_query(statement) print('北京所有的患者:') vertex_list = result["results"][0]['data'][0]['row'][0] print(vertex_list) print('查看此轮疫情入京可能的传播链:') source = '额济纳旗' chain_vid = [] for vid in vertex_list: target = vid avoid_ids = copy.deepcopy(vertex_list) avoid_ids.remove(vid) result = ges_util.filtered_shortest_path(source, target, avoid_ids) if len(result) != 0: chain_vid.append(target) path = '' for vtx_id in result: path = path + vtx_id + '-' print(path[:-1])可以对可能传播链上的节点进行一跳查询,分析传播链之间的关系。result = ges_util.cypher_query('match p=(n)--(m) where id(n) in $idlist and not (m:city) and not(m:patient and not(id(m) in $idlist)) return id(n),p',formats=['row','graph'], param={"idlist":chain_vid}) ges_util.format_cypher_result(result)我们分析了此轮疫情入京可能的传播链,会发现病例24和25是一同去额济纳旗旅游,而病例33、34、35、36和37也是一起去额济纳旗旅游的,另外病例39是因为和外省确诊患者同乘车被感染的,我们等于得到了三条独立的传播链。我们已经知道了疫情的源头(额济纳旗),通过路径搜索功能,可以探查某个患者可能的感染路径。vertex_id = '北京病例2' print('查看{}可能的感染路径:'.format(vertex_id)) result = ges_util.path_query({ "repeat": [ { "operator": "bothV", "vertex_filter": { "property_filter": { "leftvalue": { "id": "" }, "predicate": "NOTIN", "rightvalue": { "value": ["北京"] } } } } ], "until": [ { "vertex_filter": { "property_filter": { "leftvalue": { "id": "" }, "predicate": "=", "rightvalue": { "value": ["额济纳旗"] } } } } ], "times": 5, "queryType": "Tree", "vertices": ["北京病例2"] }) ges_util.format_path_query(result)import time print('连通性分析:') job_id = ges_util.connected_component() result = ges_util.get_job(job_id) if 'errorCode' not in result: for i in range(1000): if result['status'] == 'success': break else: time.sleep(1) result = ges_util.get_job(job_id) com_dict = {} for v_dict in result['data']['outputs']['community']: for key, value in v_dict.items(): statement = "match (p) where id(p)='" + key + "' return labels(p)" v_label = ges_util.cypher_query(statement)['results'][0]['data'][0]['row'][0] if v_label in ['city', 'patient']: com_dict.setdefault(value, []).append(key) print('连通分支个数 : {}'.format(len(com_dict))) for key, value in com_dict.items(): print('连通分支 ' + key + ' 中的点(仅关注城市和患者):') print(value)通过连通性分析,我们暂未发现此轮大连的疫情与额济纳旗有什么关联,可能来自不同的源头。
  • [技术干货] 利用图数据库研究 COVID-19 论文数据集
    利用图数据库研究 COVID-19 论文数据集COVID-19 大流行的形势依然很严峻,为应对 COVID-19 的传播及其对我们的影响,AI2等提供了一份 COVID-19 开放研究数据集(CORD-19)。CORD-19 数据集是关于冠状病毒的文献集,提供了超过50万篇学术论文的相关信息。我们研究了这份数据集,并用图数据库去组织和挖掘这份数据集蕴含的信息。针对 CORD-19,我们设计了以下的图模型。图模型中包含了两类点,分别是 paper 和 author,也包含了两类边,分别是 write 和 reference,下面的表格说明了它们的详细情况。数据集原始数据集位于COVID-19 开放研究数据集,根据我们设计的图模型重新组织的数据可从此处下载,这份图数据包含70万+ paper 点,173万+ author 点,67万+ reference 边,443万+ write 边。创图利用华为云图数据库 GES 对以上数据集进行探索,需要先在 GES 上创图,GES 创图的详细流程见华为云图引擎服务 GES 实战——创图。使用 GES 查询的预置条件下面封装了使用 GES 查询的预置条件,包括配置相关参数和对所调用 API 接口的封装,如果你对这些不感兴趣,可直接运行而不需要了解细节,这对理解后续具体查询没有影响。配置相关参数的定义。import requests import json import time import pandas as pd pd.set_option('display.max_rows', None) pd.set_option('display.max_columns', None) pd.set_option('display.width', None) pd.set_option('display.max_colwidth', -1) class config(object): def __init__(self, iam_url, user_name, password, domain_name, project_name, eip, project_id, graph_name): self.iam_url = iam_url self.user_name = user_name self.password = password self.domain_name = domain_name self.project_name = project_name self.eip = eip self.project_id = project_id self.graph_name = graph_name self.token = self.get_token() def get_token(self): url = ('https://{}/v3/auth/tokens').format(self.iam_url) headers = {'Content-Type': 'application/json;charset=utf8'} body = json.dumps({"auth": { "identity": { "methods": ["password"], "password": { "user": { "name": self.user_name, "password": self.password, "domain": { "name": self.domain_name } } } }, "scope": { "project": { "name": self.project_name } } } }) r = requests.post(url=url, data=body, verify=False, headers=headers) return r.headers['x-subject-token']config类的参数都是与调用 GES 服务有关的参数,依次为“终端节点”、“IAM 用户名”、“IAM 用户密码”、“IAM 用户所属账户名”、“项目名称”、“公网访问地址”、“项目ID”、“token值”,其获取方式可参考调用 GES 服务业务面 API 相关参数的获取。下面定义了与查询相关的接口。class GESFunc(object): def __init__(self, eip, project_id, graph_name, token): self.eip = eip self.project_id = project_id self.graph_name = graph_name self.headers = {'X-Auth-Token': token, 'Content-Type': 'application/json'} def build_vertex_index(self): url = ('http://{}/ges/v1.0/{}/graphs/{}/indices').format(self.eip, self.project_id, self.graph_name) body = json.dumps({ "indexName": "cypher_vertex_index", "indexType": "GlobalCompositeVertexIndex", "hasLabel": "true", "indexProperty": [] }) r = requests.post(url=url, data=body, headers=self.headers) return r.json()['jobId'] def build_edge_index(self): url = ('http://{}/ges/v1.0/{}/graphs/{}/indices').format(self.eip, self.project_id, self.graph_name) body = json.dumps({ "indexName": "cypher_edge_index", "indexType": "GlobalCompositeEdgeIndex", "hasLabel": "true", "indexProperty": [] }) r = requests.post(url=url, data=body, headers=self.headers) return r.json()['jobId'] def get_job(self, job_id): url = ('http://{}/ges/v1.0/{}/graphs/{}/jobs/{}/status').format(self.eip, self.project_id, self.graph_name, job_id) r = requests.get(url=url, headers=self.headers) output = r.json() return output def summary(self): url = ('http://{}/ges/v1.0/{}/graphs/{}/summary?label_details=true').format(self.eip, self.project_id, self.graph_name) r = requests.get(url=url, headers=self.headers) output = r.json()['data'] return output def cypher_query(self, statement): url = ('http://{}/ges/v1.0/{}/graphs/{}/action?action_id=execute-cypher-query').format(self.eip, self.project_id, self.graph_name) body = json.dumps({ "statements": [ { "statement": statement, "parameters": {}, "resultDataContents": [ "row" ], "includeStats": False } ] }) r = requests.post(url=url, data=body, headers=self.headers) output = r.json()['results'] return output def format_cypher_result(self, json_obj): for x in json_obj: columns = x["columns"] data = x["data"] rows = [] for y in data: rows.append(y["row"]) return pd.DataFrame(rows, columns=columns)创建好图之后,就可以对其进行查询和分析了。# 需填入参数 iam_url = '' user_name = '' password = '' domain_name = '' project_name = '' eip = '' project_id = '' graph_name = '' config = config(iam_url, user_name, password, domain_name, project_name, eip, project_id, graph_name) ges_util = GESFunc(config.eip, config.project_id, config.graph_name, config.token)/home/ma-user/anaconda3/lib/python3.6/site-packages/urllib3/connectionpool.py:858: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings InsecureRequestWarning)GES 支持 cypher 查询语言,后续的查询示例使用的是 cypher 查询语言。在使用 cypher 查询之前,我们先创建点索引和边索引。print('开始创建点索引:') job_id = ges_util.build_vertex_index() job_result = ges_util.get_job(job_id) if 'errorCode' not in job_result: for i in range(100): if job_result['status'] == 'success': break else: time.sleep(1) job_result = ges_util.get_job(job_id) print('点索引创建完成')开始创建点索引: 点索引创建完成print('开始创建边索引:') job_id = ges_util.build_edge_index() job_result = ges_util.get_job(job_id) if 'errorCode' not in job_result: for i in range(100): if job_result['status'] == 'success': break else: time.sleep(1) job_result = ges_util.get_job(job_id) print('边索引创建完成') 开始创建边索引: 边索引创建完成查询演示下面,我们可以书写并运行标准的 cypher 语言,对这份图数据进行探索了。以下是部分图数据的可视化展示。查询这份图数据的统计信息:print('统计信息:') result = ges_util.summary() res_str = json.dumps(result, indent=4) print(res_str)统计信息: { "vertexNum": 2449792, "labelDetails": { "labelInVertex": { "paper": 712464, "author": 1737328 }, "labelInEdge": { "reference": 670627, "write": 4434198 } }, "edgeNum": 5104825 }列举若干 paper 的信息:print('查询 papers:') statement = "match (n:paper) return n.title limit 5" paper_result = ges_util.cypher_query(statement) format_result = ges_util.format_cypher_result(paper_result) format_result查询 papers:.dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; }n.title0Clinical features of culture-proven Mycoplasma pneumoniae infections at King Abdulaziz University Hospital, Jeddah, Saudi Arabia1Nitric oxide: a pro-inflammatory mediator in lung disease?2Surfactant protein-D and pulmonary host defense3Role of endothelin-1 in lung disease4Gene expression in epithelial cells in response to pneumovirus infection查询某 paper 的 authors:print('查询某 paper 的 authors:') paper = paper_result[0]['data'][1]['row'][0] statement = "match (n:paper)<--(m:author) WHERE n.title = '" + paper + "' return id(m)" result = ges_util.cypher_query(statement) format_result = ges_util.format_cypher_result(result) format_result查询某 paper 的 authors:.dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; }id(m)0Vliet Albert van der1Eiserich Jason P2Cross Carroll E查询某 paper 被引用的次数:print('查询某 paper 被引用次数:') paper = paper_result[0]['data'][2]['row'][0] statement = "match (n:paper)<--(m:paper) WHERE n.title = '" + paper + "' return count(m)" result = ges_util.cypher_query(statement) format_result = ges_util.format_cypher_result(result) format_result查询某 paper 被引用次数:.dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; }count(m)05查询某 paper 与哪些 paper 被联合引用及其次数:print('查询某 paper 与哪些 paper 被联合引用及其次数:') paper = paper_result[0]['data'][3]['row'][0] statement = "match (n:paper)<--(p:paper)-->(m:paper) WHERE n.title = '" + paper + "' return m.title, count(*) as p order by p desc limit 5" result = ges_util.cypher_query(statement) format_result = ges_util.format_cypher_result(result) format_result查询某 paper 与哪些 paper 被联合引用及其次数:.dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; }m.titlep0Clinical course and risk factors for mortality of adult inpatients with COVID-19 in Wuhan, China: a retrospective cohort study21The use of corticosteroid as treatment in SARS was associated with adverse outcomes: a retrospective cohort study12Covid-19: ibuprofen should not be used for managing symptoms, say doctors and scientists13SARS-CoV2: should inhibitors of the renin-angiotensin system be withdrawn in patients with COVID-19?14Network-based drug repurposing for novel coronavirus 2019-nCoV/SARS-CoV-21查询标题带关键字"Virus"的 paper 数量:print('查询标题带关键字"Virus"的 paper 数量:') statement = "MATCH (p:paper) WHERE p.title IS NOT NULL AND p.title CONTAINS('Virus') RETURN count(p)" result = ges_util.cypher_query(statement) format_result = ges_util.format_cypher_result(result) format_result查询标题带关键字"Virus"的 paper 数量:.dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; }count(p)08354查询标题带关键字"Virus"的 paper,并按发表日期排序:print('查询标题带关键字"Virus"的 paper,并按发表日期排序:') statement = "MATCH (p:paper) WHERE p.publish_time IS NOT NULL AND p.title IS NOT NULL AND p.title " \ "CONTAINS('Virus') RETURN p.title, p.publish_time ORDER BY p.publish_time DESC LIMIT 5" result = ges_util.cypher_query(statement) format_result = ges_util.format_cypher_result(result) format_result查询标题带关键字"Virus"的 paper,并按发表日期排序:.dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; }p.titlep.publish_time0Rates of Coinfection Between SARS-CoV-2 and Other Respiratory Viruses in Korea20221Predict Mortality in Patients Infected with COVID-19 Virus Based on Observed Characteristics of the Patient using Logistic Regression2021-12-312P140 TeCC (TeleMedicine, Cystic Fibrosis, Corona-Virus) study in a previous telemedicine-naive centre: clinical challenges, outcomes, and user experience in the first six months of a global pandemic2021-12-313Virus structure and structure-based antivirals2021-12-314Virus-associated ribozymes and nano carriers against COVID-19.2021-12-01查询 paper 被引用的次数并以此排序:print('查询 paper 被引用的次数并以此排序:') statement = "match (m:paper)<--(p:paper) with m, count(p) as citedNum return m.title, citedNum order by citedNum desc limit 5" result = ges_util.cypher_query(statement) format_result = ges_util.format_cypher_result(result) format_result查询 paper 被引用的次数并以此排序:.dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; }m.titlecitedNum0Publisher's Note54361Clinical course and risk factors for mortality of adult inpatients with COVID-19 in Wuhan, China: a retrospective cohort study38242A pneumonia outbreak associated with a new coronavirus of probable bat origin36773Epidemiological and clinical characteristics of 99 cases of 2019 novel coronavirus pneumonia in Wuhan, China: a descriptive study30914A new coronavirus associated with human respiratory disease in China1975列举若干 author 的信息:print('查询 authors:') statement = "match (n:author) return id(n) limit 5" author_result = ges_util.cypher_query(statement) format_result = ges_util.format_cypher_result(author_result) format_result查询 authors:.dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; }id(n)0Madani Tariq A1Al-Ghamdi Aisha A2Vliet Albert van der3Eiserich Jason P4Cross Carroll E查询某 author 的合作者及合作次数:print('查询某 author 的合作者及合作次数:') author = author_result[0]['data'][0]['row'][0] statement = "match (n:author)-->(p:paper)<--(m:author) WHERE id(n) = '" + author + "' return id(m), count(*) as p order by p desc limit 5" result = ges_util.cypher_query(statement) format_result = ges_util.format_cypher_result(result) format_result查询某 author 的合作者及合作次数:.dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; }id(m)p0Petersen Eskild41Zumla Alimuddin42Drosten Christian43Hui David S44I Azhar Esam4查询某 author 论文被引用次数:print('查询某 author 论文被引用次数:') author = author_result[0]['data'][0]['row'][0] statement = "match (m:author)-->(p:paper)<--(n:paper) where id(m) = '" + author + "' return count(n)" result = ges_util.cypher_query(statement) format_result = ges_util.format_cypher_result(result) format_result查询某 author 论文被引用次数:.dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; }count(n)09查询论文互相引用情况:print('查询论文互相引用情况:') statement = "match (m:paper)-->(p:paper)-->(n:paper) where id(m) <> id(p) and id(m) = id(n) return m,p limit 10" result = ges_util.cypher_query(statement) format_result = ges_util.format_cypher_result(result) format_result查询论文互相引用情况:.dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; }mp0{'journal': 'Rev Mal Respir', 'publish_time': '2008-01-03', 'title': 'Chronique pour une pandémie grippale annoncée'}{'journal': 'Revue des Maladies Respiratoires', 'publish_time': '2004-12-31', 'title': 'La communication sur le SRAS : un outil essentiel de santé publique'}1{'journal': 'Intensive Care Med', 'publish_time': '2020-03-23', 'title': 'Acute respiratory distress syndrome-attributable mortality in critically ill patients with sepsis'}{'journal': 'J Biomed Sci', 'publish_time': '2003-10-18', 'title': 'Acute respiratory distress syndrome'}2{'journal': None, 'publish_time': '2020-11-19', 'title': 'Curvature domains in V4 of macaque monkey'}{'journal': None, 'publish_time': '2020-11-19', 'title': 'Curvature-processing domains in primate V4'}3{'journal': None, 'publish_time': '2020-11-19', 'title': 'Curvature-processing domains in primate V4'}{'journal': None, 'publish_time': '2020-11-19', 'title': 'Curvature domains in V4 of macaque monkey'}4{'journal': 'Theor Med Bioeth', 'publish_time': '2020-12-17', 'title': 'Philosophical investigations into the essence of pediatric suffering'}{'journal': 'Theor Med Bioeth', 'publish_time': '2021-01-05', 'title': 'What we talk about when we talk about pediatric suffering'}5{'journal': 'Theor Med Bioeth', 'publish_time': '2020-12-17', 'title': 'Philosophical investigations into the essence of pediatric suffering'}{'journal': 'Theor Med Bioeth', 'publish_time': '2020-12-07', 'title': 'Relational suffering and the moral authority of love and care'}6{'journal': 'Theor Med Bioeth', 'publish_time': '2020-12-17', 'title': 'Philosophical investigations into the essence of pediatric suffering'}{'journal': 'Theor Med Bioeth', 'publish_time': '2020-12-07', 'title': 'Our suffering and the suffering of our time'}7{'journal': 'PLoS One', 'publish_time': '2021-04-01', 'title': 'Prevalence of depression, anxiety and associated factors among school going adolescents in Bangladesh: Findings from a cross-sectional study'}{'journal': 'BMC Psychiatry', 'publish_time': '2021-05-25', 'title': 'Prevalence and correlates of anxiety and depression in frontline healthcare workers treating people with COVID-19 in Bangladesh'}8{'journal': 'PLoS Comput Biol', 'publish_time': '2020-09-21', 'title': 'Fast estimation of time-varying infectious disease transmission rates'}{'journal': 'PLoS Biol', 'publish_time': '2020-12-21', 'title': 'Patterns of smallpox mortality in London, England, over three centuries'}9{'journal': 'Commun Biol', 'publish_time': '2021-04-22', 'title': 'Structure and assembly of double-headed Sendai virus nucleocapsids'}{'journal': 'PLoS Pathog', 'publish_time': '2021-07-16', 'title': 'CryoEM structure of the Nipah virus nucleocapsid assembly'}
  • [技术干货] 电商风控图模板
    电商风控图模板互联网电商为扩张业务、推广产品,会采用奖励、返点、打折等手段实现用户和商户裂变。例如,商品的链接在商户或客户间转发时将会附带一标识ID,若商品被购买,具有该标识ID的商户或用户均会得到一笔奖励。而在裂变过程中,存在薅羊毛、虚开账号等损害平台或商家利益的行为。基于图模型的互联网电商风控,将提供客群管控、羊毛党发现等解决方案,有效帮助客户降低损失。 图模型以下是电商风控图模型元数据。 创建图引擎实例创建图引擎实例的详细流程可参考链接:cid:link_1Notebook源码配置参数的定义。config类的属性依次为“终端节点”、“IAM 用户名”、“IAM 用户密码”、“IAM 用户所属账户名”、“项目名称”、“公网访问地址”、“项目ID”、“token值”,其获取方式可参考链接:https://bbs.huaweicloud.com/blogs/296930。import requests import json import time class config(object): def __init__(self, iam_url, user_name, password, domain_name, project_name, eip, project_id, graph_name): self.iam_url = iam_url self.user_name = user_name self.password = password self.domain_name = domain_name self.project_name = project_name self.eip = eip self.project_id = project_id self.graph_name = graph_name self.token = self.get_token() def get_token(self): url = ('https://{}/v3/auth/tokens').format(self.iam_url) headers = {'Content-Type': 'application/json;charset=utf8'} body = json.dumps({"auth": { \ "identity": { \ "methods": ["password"], \ "password": { \ "user": { \ "name": self.user_name, \ "password": self.password, \ "domain": { \ "name": self.domain_name \ } \ } \ } \ }, \ "scope": { \ "project": { \ "name": self.project_name \ } \ } \ } \ }) r = requests.post(url=url, data=body, verify=False, headers=headers) return r.headers['x-subject-token']调用API接口的定义。class GESFunc(object): def __init__(self, eip, project_id, graph_name, token): self.graph_name = graph_name self.headers = {'X-Auth-Token': token, 'Content-Type': 'application/json'} self.project_id = project_id self.eip = eip def connected_component(self): url = ('http://{}/ges/v1.0/{}/graphs/{}/subgraphs/action?action_id=execute-algorithm').format(self.eip, self.project_id, self.graph_name) subgraph_creator = { "name": "filtered", "parameters": { "vertex_filter": { "property_filter": { "leftvalue": { "label_name": "labelName" }, "predicate": "=", "rightvalue": { "value": "store" } } } }} parameters = {} body = json.dumps({"algorithmName": "connected_component", "graphName": self.graph_name, "subgraphCreator": subgraph_creator, "parameters": parameters}) r = requests.post(url=url, data=body, headers=self.headers) return r.json()['jobId'] def get_job(self, job_id): url = ('http://{}/ges/v1.0/{}/graphs/{}/jobs/{}/status').format(self.eip, self.project_id, self.graph_name, job_id) r = requests.get(url=url, headers=self.headers) output = r.json()['data']['outputs'] return output def delete_edge(self, source_vertex, target_vertex): url = ('http://{}/ges/v1.0/{}/graphs/{}/edges?source={}&target={}').format(self.eip, self.project_id, self.graph_name, source_vertex, target_vertex) r = requests.delete(url=url, headers=self.headers) output = r.json()['result'] return output def add_edge(self, source_vertex, target_vertex, label): url = ('http://{}/ges/v1.0/{}/graphs/{}/edges').format(self.eip, self.project_id, self.graph_name) body = json.dumps({"source": source_vertex, "target": target_vertex, "label": label }) time.sleep(2) r = requests.post(url=url, data=body, headers=self.headers) time.sleep(2) output = r.json()['result'] return output def get_cypher(self, statement, idList): url = ('http://{}/ges/v1.0/{}/graphs/{}/action?action_id=execute-cypher-query').format(self.eip, self.project_id, self.graph_name) statements = [{ "statement": statement, "resultDataContents": ["row"], "parameters": {"idList": idList}, "includeStats": False }] body = json.dumps({"statements": statements}) r = requests.post(url=url, data=body, headers=self.headers) output = r.json()['results'] return output def get_community_info(self, output): community_list = output['community'] community_dict = {} for community in community_list: vertex_id = list(community.keys())[0] community_id = community[vertex_id] if community_id not in community_dict: component = set() component.add(vertex_id) community_dict[community_id] = component else: community_dict[community_id].add(vertex_id) return community_dict def community_change_info(self, monitor_id, old_community_info, new_community_info): monitor_set = set() new_monitor_set = set() change_id_list = [] for community_id in old_community_info: if monitor_id in old_community_info[community_id]: monitor_set = old_community_info[community_id] for community_id in new_community_info: if monitor_id in new_community_info[community_id]: new_monitor_set = new_community_info[community_id] for id in monitor_set: if id not in new_monitor_set: change_id_list.append(id) return change_id_list创建好图之后,就可以对其进行查询和分析了。config = config('', '', '', '', '', '', '', '') test = GESFunc(config.eip, config.project_id, config.graph_name, config.token)羊毛党发现在电商中,可能存在客户“薅羊毛”的行为。例如,电商平台为用户裂变,对新注册账号会有一些奖励活动,用户为获得更多奖励会在平台上注册多个账号。然而,过多的虚假账号会造成电商平台成本上升,利润下降。在本案例中,首先,通过电话号码(1XX725080460)和地址ID(0f1061e6-e903-11eb-8084-643e8cb8138c)找出马甲客户,该客户为给定电话号码和地址ID的共同邻居,共找出两个节点VRG 7和VRG 48。然后,通过VRG 7和VRG 48反方向查询可找到客户节点VRG 8和VRG 49。通过对VRG 7、VRG 48、VRG 8和VRG 49相互关联性的分析,可研判VRG 8和VRG 49是否是马甲客户的帮凶,还是普通受欺诈的无辜百姓。idList = []statement = "match (a)-[r1]->(common)<-[r2]-(b) where id(a)='0f1061e6-e903-11eb-8084-643e8cb8138c' and id(b)='1XX725080460' return common"result = test.get_cypher(statement, idList)通过地址和电话信息发现羊毛党可能为:print(result)[{'columns': ['common'], 'data': [{'row': [{'billing_street': '李新庄镇', 'billing_province': '山东省', 'billing_city': '菏泽市', 'email_address': 'anonymized@corporation.com', 'identity_id': '623062109986XXXX', 'last_activity_date': '2018-10-24', 'customer_name': 'VRG 7', 'billing_district': '单县', 'created_date': '2018-10-24'}], 'meta': [{'id': '0011R00001z10NgQAI', 'type': 'node', 'labels': ['customer']}]}, {'row': [{'billing_street': '李新庄镇', 'billing_province': '山东省', 'billing_city': '菏泽市', 'email_address': 'anonymized@corporation.com', 'identity_id': '623062109986XXXX', 'last_activity_date': '2018-10-24', 'customer_name': 'VRG 48', 'billing_district': '单县', 'created_date': '2018-10-24'}], 'meta': [{'id': '0013600000FSw9KAAT', 'type': 'node', 'labels': ['customer']}]}]}]statement = "match (a)-[r1]->(common)<-[r2]-(b), (common)-[r3]->(c) where id(a)='0f1061e6-e903-11eb-8084-643e8cb8138c' and id(b)='1XX725080460' return c"result = test.get_cypher(statement, idList)与该羊毛党具有较大相关性的客户为:print(result)[{'columns': ['c'], 'data': [{'row': [{'billing_street': '东二营镇', 'billing_province': '天津市', 'billing_city': '市辖区', 'email_address': 'anonymized@corporation.com', 'identity_id': '623062573189XXXX', 'last_activity_date': '2018-10-24', 'customer_name': 'VRG 8', 'billing_district': '蓟州区', 'created_date': '2018-10-24'}], 'meta': [{'id': '0011R00001z1109QAA', 'type': 'node', 'labels': ['customer']}]}, {'row': [{'billing_street': '四平市铁东区城东乡', 'billing_province': '吉林省', 'billing_city': '四平市', 'email_address': 'anonymized@corporation.com', 'identity_id': '6226632105938XXXX', 'last_activity_date': '2018-08-02', 'customer_name': 'VRG 49', 'billing_district': '铁东区', 'created_date': '2016-04-10'}], 'meta': [{'id': '0013600000FSwALAA1', 'type': 'node', 'labels': ['customer']}]}]}]time.sleep(5)社群管控商户的裂变呈现树状结构,较为顶层的商户往往体量较大,收益较高。然而,底层商户的频繁变动可能对顶层商户的收益产生影响。平台希望管控好底层商户从而实现顶层商户的稳定。本案例中,针对给定的顶层商户(0031R00001vSBTkQAO),监控其发展的商户是否较为稳定。首先,检测出给定商户所在的社群,然后,通过删边操作模拟随时间变化的下线流失,并再次检测给定商户社群,最后,给出变化的商户的名单。通过检测发现,0031R00001vRlHbQAK、0031R00001vRlYiQAK、0031R00001uqjUQQAY、0031R00001uoQr5QAE、0031R00001vS9WcQAK、0031R00001vSB7DQAW这六个下线脱离了与给定顶层商户的联系并自立门户,将对给定顶层商户产生一定的经济损失。job_id = test.connected_component()result = test.get_job(job_id)old_community_info = test.get_community_info(result)monitor_id = '0031R00001vSBTkQAO'删边模拟顶层客户下线的流失:result = test.delete_edge('Samantha-Mars', '0031R00001uoQr5QAE')job_id = test.connected_component()result = test.get_job(job_id)test.add_edge('Samantha-Mars', '0031R00001uoQr5QAE', 'transfer')new_community_info = test.get_community_info(result)change_id_list = test.community_change_info(monitor_id, old_community_info, new_community_info)变化的商户为:print(change_id_list)['0031R00001vRlYiQAK', '0031R00001vSB7DQAW', '0031R00001uqjUQQAY', '0031R00001vS9WcQAK', '0031R00001vRlHbQAK', '0031R00001uoQr5QAE']
  • [技术干货] 教育知识图谱
    教育知识图谱背景为了解决教师在教学过程中知识框架梳理、组卷策略等问题, 以及学生在学习过程中认知过载、学习迷航等问题,知识图谱被引入教育行业。针对这些需求,本文以高中数学学科知识图谱为例,提供了教育图谱在知识导航、组卷策略等方面的应用示例。数据建模首先我们需要构建教育图谱的图数据模型。图数据模型中的实体包括知识点和题目,实体关系包括知识点之间的包含关系以及知识点和题目之间的关联关系,具体的图模型见下图:图模型中包含了两类点和两类边,元信息说明如下: 数据集本文采集了高中数学几乎所有的知识点和部分题目信息,根据设计的图模型对数据格式进行转换,转换后的数据可从此处下载。这份数据包含7W+个点,14W+条边。创图本文将使用华为云图数据库 GES 对以上数据集进行探索和演示,我们需要先在 GES 中创图并将以上数据集导入,详细指导流程可参见华为云图引擎服务 GES 实战——创图。使用 GES 查询的预置条件下面文件封装了使用 GES 查询的预置条件,包括配置相关参数和对所调用 API 接口的封装。import moxing as mox mox.file.copy('obs://obs-aigallery-zc/GES/edu_knowledge_graph/config.py', 'config.py')config类的参数都是与调用 GES 服务有关的参数,依次为“终端节点”、“IAM 用户名”、“IAM 用户密码”、“IAM 用户所属账户名”、“项目名称”、“公网访问地址”、“项目ID”、“token值”,其获取方式可参考调用 GES 服务业务面 API 相关参数的获取。下面文件封装了与查询相关的接口。mox.file.copy('obs://obs-aigallery-zc/GES/edu_knowledge_graph/ges_func.py','ges_func.py')创建好图之后,就可以对其进行查询和分析了。import time import json from config import config from ges_func import GESFunc # 需填入参数 iam_url = '' user_name = '' password = '' domain_name = '' project_name = '' eip = '' project_id = '' graph_name = '' config = config(iam_url, user_name, password, domain_name, project_name, eip, project_id, graph_name) ges_util = GESFunc(config.eip, config.project_id, config.graph_name, config.token)GES 支持 cypher 查询语言,后续的查询示例使用到 cypher 查询语言。在使用 cypher 查询之前,我们先创建点索引和边索引(可直接点击GES画布右下角“创建索引”按钮)。print('开始创建点索引:') job_id = ges_util.build_vertex_index() job_result = ges_util.get_job(job_id) if 'errorCode' not in job_result: for i in range(100): if job_result['status'] == 'success': break else: time.sleep(1) job_result = ges_util.get_job(job_id) print('点索引创建完成')print('开始创建边索引:') job_id = ges_util.build_edge_index() job_result = ges_util.get_job(job_id) if 'errorCode' not in job_result: for i in range(100): if job_result['status'] == 'success': break else: time.sleep(1) job_result = ges_util.get_job(job_id) print('边索引创建完成')查询演示查询这份图数据的统计信息:print('统计信息:') result = ges_util.summary() format_result = json.dumps(result, indent=4) print(format_result)统计信息: { "vertexNum": 70528, "labelDetails": { "labelInVertex": { "knowledge_point": 2163, "exercises": 68365 }, "labelInEdge": { "include": 2145, "related": 138742 } }, "edgeNum": 140887 }可以看到,这份知识图谱包含2000多个知识点和接近七万的题目。知识点图谱输入某个知识点,将展示该知识点所有下游知识点。knowledge_point = '集合的基本运算' statement = "g.V('{}').repeat(outE().otherV().hasLabel('knowledge_point')).emit().path()".format(knowledge_point) result = ges_util.gremlin_query(statement)['results'] format_result = json.dumps(result, indent=4, ensure_ascii=False) # print(format_result)题目知识点追踪输入题目,将追踪到该题目考察的所有知识点。exercises_id = '1' statement = "g.V('{}').repeat(inE().otherV().hasLabel('knowledge_point')).emit().path()".format(exercises_id) result = ges_util.gremlin_query(statement)['results'] format_result = json.dumps(result, indent=4, ensure_ascii=False) # print(format_result)知识点关系查询knowledge_point_1 = "集合" knowledge_point_2 = "空集" result = ges_util.n_paths(knowledge_point_1, knowledge_point_2) format_result = json.dumps(result, indent=4, ensure_ascii=False) # print(format_result)某知识点包含哪些知识点knowledge_point = "集合" statement = "match (n)-->(m:knowledge_point) where id(n) = '{}' return id(m)".format(knowledge_point) result = ges_util.cypher_query(statement) format_result = ges_util.format_cypher_result(result) print(format_result)与某知识点相关的题目的数量knowledge_point = "描述法表示集合" statement = "match (n)-->(m:exercises) where id(n) = '{}' return count(m)".format(knowledge_point) result = ges_util.cypher_query(statement) format_result = ges_util.format_cypher_result(result) print(format_result)包含某知识点的题型分布knowledge_point = "描述法表示集合" statement = "match (n)-->(m:exercises) where id(n) = '{}' return m.type, count(*)".format(knowledge_point) result = ges_util.cypher_query(statement) format_result = ges_util.format_cypher_result(result) print(format_result) m.type count(*) 0 解答题 127 1 单选题 277 2 多选题 15 3 填空题 118 4 双空题 13 5 概念填空 4某知识点会和哪些其他知识点一起考察knowledge_point = "描述法表示集合" statement = "match (n)-->(m:exercises)<--(p:knowledge_point) where id(n) = '{}' return id(p), count(*)".format(knowledge_point) result = ges_util.cypher_query(statement) format_result = ges_util.format_cypher_result(result) print(format_result)自动组卷为了考察学生的学习情况,老师需要组织一套试卷,该例子中,限制了考察的知识点范围,以及各个题型的题目数量,skip的含义是在所有满足条件的试卷中选择某一套试卷。knowledge_point = "描述法表示集合" single_choice_num = 4 multiple_choice_num = 2 gap_filling_num = 2 free_response_question_num = 2 skip = 1 exercises_list = ges_util.test_paper_composition(single_choice_num, multiple_choice_num, gap_filling_num, free_response_question_num, knowledge_point, skip) format_result = ges_util.format_cypher_result(exercises_list) print(format_result)拿到一份试卷后,我们可以看看这套试卷整体的难易程度,当然也可以将试卷的难易程度作为组织试卷的限制条件。print('试题的平均通过率(难度):') ave_pass_rate = ges_util.ave_pass_rate(exercises_list, 10) print(ave_pass_rate)
  • [技术干货] 电网供电管理
    电网供电管理介绍配电网是电力系统中起重新分配电能作用的网络,直接面向电力用户。据统计,超过85%的故障停电是由于配电网故障造成的。所以需要加强配电网的管理,从而最大程度减少电网故障对用户的影响。在发生停电之前,提高供电的可靠性,当不可避免地发生停电时,需要一个有效的方式尽快恢复供电。配电网是一个天然的图数据模型----导电设备、设备容器、物理连接节点等可以作为节点,线路、连接关系可以看作边。 我们通过一个案例介绍华为图引擎GES在配电网几个典型场景上的应用。图模型以下是配电网的图数据模型。 下面详细列出了用到的样例数据的点类、边类及其附带的属性。 说明:此处基于电网CIM/E模型设计配电网图数据模型,通过联结节点将导电设备连接起来,导电设备包括busbarsection(母线))、energyconsumer(用户点)、fuse(熔断器)等,aclinesegment(导线段)连接的是两个不同的联结节点,resistancefreeline(无电阻导线)连接的是导电设备和联结节点,另外,导电设备包含设备类型(PSRType)、电压等级(BaseVoltage)、开关状态(status)、所属设备容器(container)等属性。样例数据集可点击此处下载原始数据集。样例数据集中提供了两条线路,其中一条线路的一部分可视化展示如下:创图创图的详细流程见华为云图引擎服务 GES 实战——创图。源码配置参数的定义。import requests import json import time class config(object): def __init__(self, iam_url, user_name, password, domain_name, project_name, eip, project_id, graph_name): self.iam_url = iam_url self.user_name = user_name self.password = password self.domain_name = domain_name self.project_name = project_name self.eip = eip self.project_id = project_id self.graph_name = graph_name self.token = self.get_token() def get_token(self): url = ('https://{}/v3/auth/tokens').format(self.iam_url) headers = {'Content-Type': 'application/json;charset=utf8'} body = json.dumps({"auth": { \ "identity": { \ "methods": ["password"], \ "password": { \ "user": { \ "name": self.user_name, \ "password": self.password, \ "domain": { \ "name": self.domain_name \ } \ } \ } \ }, \ "scope": { \ "project": { \ "name": self.project_name \ } \ } \ } \ }) r = requests.post(url=url, data=body, verify=False, headers=headers) return r.headers['x-subject-token']config类的属性依次为“终端节点”、“IAM 用户名”、“IAM 用户密码”、“IAM 用户所属账户名”、“项目名称”、“公网访问地址”、“项目ID”、“token值”,其获取方式可参考调用 GES 服务业务面 API 相关参数的获取。调用API接口的定义。class GESFunc(object): def __init__(self, eip, project_id, graph_name, token): self.eip = eip self.project_id = project_id self.graph_name = graph_name self.headers = {'X-Auth-Token': token, 'Content-Type': 'application/json'} def filter_query_vertex(self): url = ('http://{}/ges/v1.0/{}/graphs/{}/action?action_id=execute-gremlin-query').format(self.eip, self.project_id, self.graph_name) command = "g.V().has('container','变电站')" body = json.dumps({"command": command}) r = requests.post(url=url, data=body, headers=self.headers) output = r.json()['data'] return output def query_scope(self, id): url = ('http://{}/ges/v1.0/{}/graphs/{}/action?action_id=execute-algorithm').format(self.eip, self.project_id, self.graph_name) body = json.dumps({"executionMode": "sync", "algorithmName": "k_hop", "parameters": {"k": 100, "source": id, "mode": "ALL"}}) r = requests.post(url=url, data=body, headers=self.headers) return r.json()['data']['outputs'] def query_consumer(self, id_list): url = ('http://{}/ges/v1.0/{}/graphs/{}/action?action_id=filtered-query').format(self.eip, self.project_id, self.graph_name) body = json.dumps({"executionMode": "sync", "filters": [ { "operator": "vertex", "vertex_filter": { "property_filter": { "leftvalue": { "label_name": "labelName" }, "predicate": "=", "rightvalue": { "value": "energyconsumer" } } } } ], "by": [ { "id": True, "properties": True, "selectedProperties": [ "name" ] } ], "full_path": False, "vertices": id_list}) r = requests.post(url=url, data=body, headers=self.headers) return r.json()['data'] def outage_analysis(self, id): url = ('http://{}/ges/v1.0/{}/graphs/{}/action?action_id=path-query').format(self.eip, self.project_id, self.graph_name) body = json.dumps( { "repeat": [ { "operator": "bothV" } ], "until": [ { "vertex_filter": { "property_filter": { "leftvalue": { "property_filter": { "leftvalue": { "label_name": "labelName" }, "predicate": "=", "rightvalue": { "value": "fuse" } } }, "predicate": "&", "rightvalue": { "property_filter": { "leftvalue": { "property_name": "status" }, "predicate": "=", "rightvalue": { "value": "open" } } } } } } ], "queryType": "Tree", "emit": False, "times": 20, "by": [ { "properties": True, "selectedProperties": ["status"] } ], "vertices": [ id ] } ) r = requests.post(url=url, data=body, headers=self.headers) return r.json()['data'] def query_vertex(self, id): url = ('http://{}/ges/v1.0/{}/graphs/{}/action?action_id=execute-gremlin-query').format(self.eip, self.project_id, self.graph_name) command = "g.V(" + id + ")" body = json.dumps({"command": command}) r = requests.post(url=url, data=body, headers=self.headers) output = r.json()['data'] return output def annular_electric_supply(self): url = ('http://{}/ges/v1.0/{}/graphs/{}/action?action_id=execute-algorithm').format(self.eip, self.project_id, self.graph_name) body = json.dumps({ "algorithmName": "circle_detection", "parameters": { "directed": False, "max_length": 15 }}) r = requests.post(url=url, data=body, headers=self.headers) return r.json()['jobId'] def get_job(self, job_id): url = ('http://{}/ges/v1.0/{}/graphs/{}/jobs/{}/status').format(self.eip, self.project_id, self.graph_name, job_id) r = requests.get(url=url, headers=self.headers) output = r.json()['data']['outputs'] return output def query_interconnection_switch(self, id_list): url = ('http://{}/ges/v1.0/{}/graphs/{}/action?action_id=filtered-query').format(self.eip, self.project_id, self.graph_name) body = json.dumps({ "executionMode": "sync", "filters": [ { "operator": "vertex", "vertex_filter": { "property_filter": { "leftvalue": { "property_name": "name" }, "predicate": "SUBSTRING", "rightvalue": { "value": "联络开关" } } } } ], "by": [ { "id": True, "properties": True, "selectedProperties": [ "name" ] } ], "full_path": False, "vertices": id_list}) r = requests.post(url=url, data=body, headers=self.headers) return r.json()['data']创建好图之后,就可以对其进行查询和分析了。# 需填入参数 config = config(" ", " ", " ", " ", " ", " ", " ", " ") test = GESFunc(config.eip, config.project_id, config.graph_name, config.token)场景演示供电范围查询指查询指定设备所承担供电范围内的其他设备,这个需要查询的设备可以是站内变压器,也可以是变电站。这有助于设备管理,也能够清楚地知道由于变电站的故障所造成的停电范围,早作防范。一般更关心的是变电站供电的用户。以上图例中,如果断开间隔开关1,其下游所有的用户都会处于停电状态。下面是一个具体的操作示例。首先查找位于变电站中的母线。(母线是各级电压配电装置的中间环节,它的作用是汇集、分配和传送电能。)result = test.filter_query_vertex() print('the busbarsections in substations:') print(result)从结果看,我们得到了两条母线,选取其中一条母线,查看其供电范围。result = test.query_scope("1157") print('the equipments in the scope of supply of "1157":') print(result)得到的结果包含供电范围内所有设备的ID。 我们比较关心的是供电范围内涉及的用户。id_list = result["vertices"] result = test.query_consumer(id_list) print('the consumers in the scope of supply of "1157":') print(result)另外,如果该供电范围内有重点用户,就需要检查、调整供配电方案,例如对重点用户提供市电和发电机供电切换供电方案。停电故障分析关于停电,如果是非计划停电,我们需要知道的是故障出在哪里,尽快去修复。GES无论是在故障定位还是抢修路径设计方面都能发挥作用。图例中,当标红用户点出现停电时,可以回溯供电路径,查找故障原因。下面是一个具体的操作示例。本场景中我们假设由于设备故障造成某用户节点(节点ID为74)停电,我们要做的是通过路径回溯定位到故障点(假设故障原因为设备故障而非线路故障)。result = test.outage_analysis("74") print('the cause of the problem:') print(result)进一步查询id为55的节点详情。result = test.query_vertex("55") print('the details of faulty equipment:') print(result)查询到的结果显示是因为节点ID为55的熔断器发生熔断导致的节点ID为74的用户接入点出现停电现象。环形供电查询环形供电是指电源和负荷点通过线路联结成环形的供电方式。环形供电能提高供电的可靠性,当环内任一段线路出现故障时,通过开关的切换能保证负荷点的正常供电。 图例中四条单路进线两两相连形成环形供电网络,当本段进线出现供电中断后,能从其他进线侧获取电能。下面是一个具体的操作示例。本场景演示了利用GES搜索配电网中的环形供电线路。result = test.annular_electric_supply() job_id = result time.sleep(1) result = test.get_job(job_id) print('the id list of annular_electric_supply:') print(result)the id list of annular_electric_supply: {'data_return_size': 1, 'min_length': 3, 'runtime': 0.0019060000000000001, 'circles': [['1250', '1251', '1249', '1054', '1203', '1035', '1202', '1036', '1204', '1049', '1237', '1046', '1274', '1250']], 'data_offset': 0, 'n': 100, 'data_total_size': 1, 'max_length': 15}可以进一步确定环形供电路径中联络开关的位置,联络开关的常规状态是open,只有在需要的时候才会close。(为了能尽可能的减少停电的影响,我们通过将两条配电线路通过开关连接起来,以便能实现负荷之间的转供,这个用来连接两条配电线路的开关就叫“联络开关”。)for i in range(len(result['circles'])): id_list = result['circles'][i] res = test.query_interconnection_switch(id_list) print('interconnection switch:') print(res)interconnection switch: {'vertices': [{'id': '1046', 'properties': {'name': ['南线小渔村委会支-临湖线联络开关']}}]}基于查询到的结果,我们可以知道环形路径上任何设备或线路出现故障都不会影响整体的供电情况,只需要切换联络开关即可,而我们也已经知道了联络开关的位置。
  • [云服务] 【数据使能】图引擎服务GES能力项
    分类文档链接备注最新动态cid:link_5特性清单cid:link_2原子APIcid:link_3FAQcid:link_4华为云在线课程(免费)图引擎服务https://education.huaweicloud.com/courses/course-v1:HuaweiX+CBUCNXE008+Self-paced/about?isAuth=0&cfrom=hwc图引擎服务(Graph Engine Service),是针对以“关系”为基础的“图”结构数据,进行查询、分析的服务。广泛应用于社交关系分析、推荐、精准营销、舆情及社会化聆听、信息传播、防欺诈等具有丰富关系数据的场景。华为云培训服务(收费)基于图引擎的医药查询系统cid:link_1如何在当前琳琅满目的药品中选取合适自己病症的良药呢?在人工智能发展迅猛的当下,让AI为选取药品贡献一份力量吧。华为云开发者网GES开放能力cid:link_6
  • [教程] 从零开始学Graph Database:什么是图
    传统上我们使用图来解决一些数学问题。比如图论起源于著名的柯尼斯堡七桥问题, 该问题被欧拉推广为:怎样判断是否存在着一个恰好包含了所有边,且没有重复的路径。即一笔画问题。当然了,图并非只能解决这类图论经典问题(如 四色问题,马的遍历问题,邮递员问题, 网络流问题 ),只要能够将研究对象表示为图结构,就能利用图的特点来解决问题,甚至大部分情况下,并不需要使用到多么高深的算法。 详情参见:《从零开始学Graph Database(1)》
  • [技术干货] 使用Jupyter可视化查询语句的语法树--以图查询语言Cypher为例
    “语法解析”和“词法解析”是计算机理解查询语句的重要一环。而词法和语法的解析依赖于一定的文法规则,有诸多网站可以可视化文法规则,但是对于根据文法规则生成的语法树进行可视化的文章却比较少。对文法规则生成的语法树进行可视化,可以降低查询语言的理解成本。本文以华为图引擎使用的cypher查询语言为例,将查询语句的解析结果(语法树)在jupyterLab上可视化。案例中使用的工具不仅可以可视化cypher语言的语法树结构,对其他antlr生成的抽象语法树同样适用。详情参见:cid:link_1AI Gallery案例地址为:cid:link_0
  • [算子编译] 请问Graph Kernel Fusion(图算融合)在mindspore1.7.0下会生成融合后的mindIR的.dot文件吗
    【功能模块】图算融合,GPU (NVIDIA-RTX3080) 验证【操作步骤&问题现象】1、参考(基于mindspore0.5.0)链接1: https://gitee.com/mindspore/course/tree/master/06_distributed/graph_kernel2、参考(基于mindspore1.0.0)链接2: https://bbs.huaweicloud.com/forum/forum.php?mod=viewthread&tid=78817&page=1&replytype=13、按照教程和另一位大佬的帖子开启图算融合后,对基本组合算子和自组合算子进行试验,发现mindspore1.7.0生成的ir和.dot文件和之前版本的mindir文件的命名形式不一样,发现没有生成例子当中的文件(hwopt_d_fuse_basic_opt_end_graph_0.dot/hwopt_d_composite_opt_end_graph_0.dot)。未找到如下图红框中类似的图算融合后生成的ir/dot文件.minspore1.0.0生成的ir文件如下图(源自链接2楼主)请问是否有图算融合的整体流程图(细化到生成每个IR的小阶段)参考,多谢!【截图信息】本人基于mindspore1.7.0生成的mindir文件信息中,未找到图算融合后的.dot。烦请指导~多谢【日志信息】(可选,上传日志内容或者附件)
  • [技术干货] 将Graph Explorer搬上JupyterLab:使用GES4Jupyter连接GES并进行图探索
    GES4Jupyter是一款可以在JupyterLab中连接访问GES并可视化的工具。工具中封装了部分GES业务面接口,并提供对返回数据的可视化能力。基于该工具在Jupyter上进行图探索,可以大大降低编码成本,丰富JupyterLab的数据表现力。详情参考:https://bbs.huaweicloud.com/blogs/361607
总条数:50 到第
上滑加载中