知识图谱最简单的demo实现

一、简介

知识图谱整个建立过程可以分为以下几点:

数据处理
创建三元组
可视化展示

其中:

  • 数据预处理:分词、命名实体识别、语义角色识别、句法依存分析等
  • 创建三元组:需要根据命名实体识别、语义角色识别结果进行处理,建立规则生成三元组
  • 用用图数据库或者接触可视化工具进行展示

二、数据预处理

这里我们使用哈工大的开源工具包LTP进行展示

本文主要介绍整体流程,中间的技术细节,会在后面分章节展开

2.1 数据

我们自己创建一段文本
当然也可以导入文本,或者批量导入csv等格式的数据,为了简便我们使用一段话来展示。

text="苏轼是宋朝的著名文学家,黄庭坚是他的好朋友。苏轼擅长写词,而黄庭坚擅长写诗。他在常州去世。"

2.2 数据处理

LTP支持将全部处理流程进行pipeline执行,当然我们也可以选择分布执行,在后面技术章节会详细展开

#  分词 cws、词性 pos、命名实体标注 ner、语义角色标注 srl、依存句法分析 dep、语义依存分析树 sdp、语义依存分析图 sdpg
output = ltp.pipeline(text, tasks=["cws", "pos", "ner", "srl", "dep", "sdp", "sdpg"])

我们把output展开看一下

output
LTPOutput(cws=['苏轼', '是', '宋朝', '的', '著名', '文学家', ',', '黄庭坚', '是', '他', '的', '好', '朋友', '。', '苏轼', '擅长', '写', '词', ',', '而', '黄庭坚', '擅长', '写', '诗', '。', '他', '在', '常州', '去世', '。'], pos=['nh', 'v', 'nt', 'u', 'a', 'n', 'wp', 'nh', 'v', 'r', 'u', 'a', 'n', 'wp', 'nh', 'v', 'v', 'n', 'wp', 'c', 'nh', 'v', 'v', 'n', 'wp', 'r', 'p', 'ns', 'v', 'wp'], ner=[('Nh', '苏轼'), ('Nh', '黄庭坚'), ('Nh', '苏轼'), ('Nh', '黄庭坚'), ('Ns', '常州')], srl=[{'predicate': '是', 'arguments': [('A0', '苏轼'), ('A1', '宋朝的著名文学家')]}, {'predicate': '是', 'arguments': [('A0', '黄庭坚'), ('A1', '他的好朋友')]}, {'predicate': '擅长', 'arguments': [('A0', '苏轼'), ('A1', '写词')]}, {'predicate': '写', 'arguments': [('A1', '词')]}, {'predicate': '擅长', 'arguments': [('A0', '黄庭坚'), ('A1', '写诗')]}, {'predicate': '写', 'arguments': [('A1', '诗')]}, {'predicate': '去世', 'arguments': [('A0', '他'), ('ARGM-LOC', '在常州')]}], dep={'head': [2, 0, 6, 3, 6, 2, 2, 9, 2, 13, 10, 13, 9, 2, 16, 2, 16, 17, 16, 22, 22, 16, 22, 23, 2, 29, 29, 27, 2, 2], 'label': ['SBV', 'HED', 'ATT', 'RAD', 'ATT', 'VOB', 'WP', 'SBV', 'COO', 'ATT', 'RAD', 'ATT', 'VOB', 'WP', 'SBV', 'COO', 'VOB', 'VOB', 'WP', 'ADV', 'SBV', 'COO', 'VOB', 'VOB', 'WP', 'SBV', 'ADV', 'POB', 'COO', 'WP']}, sdp={'head': [2, 0, 6, 3, 6, 2, 2, 9, 2, 13, 10, 13, 9, 9, 16, 9, 16, 17, 16, 22, 22, 16, 22, 23, 22, 29, 28, 29, 22, 29], 'label': ['EXP', 'Root', 'TIME', 'mDEPD', 'FEAT', 'LINK', 'mPUNC', 'EXP', 'eSUCC', 'FEAT', 'mDEPD', 'FEAT', 'LINK', 'mPUNC', 'AGT', 'eSUCC', 'dCONT', 'CONT', 'mPUNC', 'mRELA', 'AGT', 'eCOO', 'dCONT', 'CONT', 'mPUNC', 'EXP', 'mRELA', 'LOC', 'eSUCC', 'mPUNC']}, sdpg=[(1, 2, 'EXP'), (2, 0, 'Root'), (3, 6, 'TIME'), (4, 3, 'mDEPD'), (5, 6, 'FEAT'), (6, 2, 'LINK'), (7, 2, 'mPUNC'), (8, 9, 'EXP'), (8, 10, 'eCOO'), (9, 2, 'eSUCC'), (10, 13, 'FEAT'), (11, 10, 'mDEPD'), (12, 13, 'FEAT'), (13, 9, 'LINK'), (14, 9, 'mPUNC'), (15, 16, 'AGT'), (16, 9, 'eSUCC'), (17, 16, 'dCONT'), (18, 17, 'CONT'), (19, 16, 'mPUNC'), (20, 22, 'mRELA'), (21, 22, 'AGT'), (22, 16, 'eCOO'), (23, 22, 'dCONT'), (24, 23, 'CONT'), (25, 22, 'mPUNC'), (26, 29, 'EXP'), (27, 28, 'mRELA'), (28, 29, 'LOC'), (29, 22, 'eSUCC'), (30, 22, 'mPUNC'), (30, 29, 'mPUNC')])

当然,我们也可以使用字典分别返回其结果

# 使用字典格式作为返回结果
print(output.cws)  # print(output[0]) / print(output['cws']) # 也可以使用下标访问
print(output.pos)
print(output.sdp)
print(output.ner)
print(output.srl)

我们这里创建知识图谱主要使用命名实体识别和语义角色标注的结果

2.3 实体创建

实体创建主要是命名实体识别的结果

print(output.cws) 
print(output.ner)['苏轼', '是', '宋朝', '的', '著名', '文学家', ',', '黄庭坚', '是', '他', '的', '好', '朋友', '。', '苏轼', '擅长', '写', '词', ',', '而', '黄庭坚', '擅长', '写', '诗', '。', '他', '在', '常州', '去世', '。'][('Nh', '苏轼'), ('Nh', '黄庭坚'), ('Nh', '苏轼'), ('Nh', '黄庭坚'), ('Ns', '常州')]

LTP目前可以识别的实体类别主要有三种:

标记含义
Nh人名
Ni机构名
Ns地名

当然如果是复杂项目的数据,这个明显是不能支持的,后面我们会介绍如果训练自己的命名实体识别模型

从上面的结果我们可以看到,目前识别的结果只有人名和地名

正常来讲,北宋作为时间,应该也需要进行识别

接下来我们创建实体:

def entity_extraction(ner_result):ner_list_Nh=[]ner_list_Ni=[]ner_list_Ns=[]for i in  range(len(ner_result)):if output.ner[i][0] == "Nh":ner_list_Nh.append(ner_result[i][1])elif output.ner[i][0] == "Ni":ner_list_Ni.append(ner_result[i][1])elif output.ner[i][0] == "Ns":ner_list_Ns.append(ner_result[i][1])return list(set(ner_list_Nh)),list(set(ner_list_Ni)),list(set(ner_list_Ns))

根据不同的识别标签创建三个list,并且用set去重,最后得到实体

ner_list_Nh,ner_list_Ni,ner_list_Ns(['苏轼', '黄庭坚'], [], ['常州'])

最终的实体有三个,两个人名,一个地名

2.4 三元组构建

我们使用角色标注的结果创建三元组

实际情况下,只使用角色标注创建是不行的,需要根据依存句法、语义依存等一起来进行构建,这样会更好的理解上下文和全局

print(output.cws)  
print(output.srl)['苏轼', '是', '宋朝', '的', '著名', '文学家', ',', '黄庭坚', '是', '他', '的', '好', '朋友', '。', '苏轼', '擅长', '写', '词', ',', '而', '黄庭坚', '擅长', '写', '诗', '。', '他', '在', '常州', '去世', '。'][{'predicate': '是', 'arguments': [('A0', '苏轼'), ('A1', '宋朝的著名文学家')]}, {'predicate': '是', 'arguments': [('A0', '黄庭坚'), ('A1', '他的好朋友')]}, {'predicate': '擅长', 'arguments': [('A0', '苏轼'), ('A1', '写词')]}, {'predicate': '写', 'arguments': [('A1', '词')]}, {'predicate': '擅长', 'arguments': [('A0', '黄庭坚'), ('A1', '写诗')]}, {'predicate': '写', 'arguments': [('A1', '诗')]}, {'predicate': '去世', 'arguments': [('A0', '他'), ('ARGM-LOC', '在常州')]}]

为了更好的展示,我们分别打印一下

for i in range(len(output.srl)):#if srl[i]print(output.srl[i])
{'predicate': '是', 'arguments': [('A0', '苏轼'), ('A1', '宋朝的著名文学家')]}
{'predicate': '是', 'arguments': [('A0', '黄庭坚'), ('A1', '他的好朋友')]}
{'predicate': '擅长', 'arguments': [('A0', '苏轼'), ('A1', '写词')]}
{'predicate': '写', 'arguments': [('A1', '词')]}
{'predicate': '擅长', 'arguments': [('A0', '黄庭坚'), ('A1', '写诗')]}
{'predicate': '写', 'arguments': [('A1', '诗')]}
{'predicate': '去世', 'arguments': [('A0', '他'), ('ARGM-LOC', '在常州')]}

语义角色类型可以在LTP官网上查看
在这里插入图片描述
我们这里筛选有A0角色的进行创建

从一般的结果看,一般A0会对应到命名实体识别的实体上,当然我个人觉得这里是有优化空间的

kg_list=[]
for i in range(len(output.srl)):judge_for_a0=[]for j in range(len(output.srl[i]["arguments"])):judge_for_a0.append(output.srl[i]["arguments"][j][0])#print((judge_for_a0))if "A0" in judge_for_a0:index_a0 = judge_for_a0.index("A0")if "A1" in judge_for_a0:index_a1 = judge_for_a0.index("A1")elif "ARGM-LOC" in judge_for_a0:index_a1 = judge_for_a0.index("ARGM-LOC")kg_list.append([output.srl[i]["arguments"][index_a0][1],output.srl[i]["predicate"],output.srl[i]["arguments"][index_a1][1]])

生成的结果就是:

[['苏轼', '是', '宋朝的著名文学家'],['黄庭坚', '是', '他的好朋友'],['苏轼', '擅长', '写词'],['黄庭坚', '擅长', '写诗'],['他', '去世', '在常州']]

2.5 数据整理

  • 如果在三元组中的A0没有在实体中的话我们直接去掉;
  • 对于三元组中的第三列,我们这里单独将其定义为一类实体为标签
#实体清洗,与ner结果匹配
def  kg_list_rule(kg_list,ner_list_Nh):for i in range(len(kg_list)):for j in ner_list_Nh:#如果A0角色,包含ner识别的实体,将其替换为实体名称if j in kg_list[i][0]:kg_list[i][0]=jfor i in range(len(kg_list)):#如果语义角色识别的角色不再ner结果中则删除,此处需要优化if kg_list[i][0] in ner_list_Nh:continuedel kg_list[i]predicate = []for i in range(len(kg_list)):#提取谓语predicate.append(kg_list[i][2])return kg_list,predicate

最终结果如下:

([['苏轼', '是', '宋朝的著名文学家'],['黄庭坚', '是', '他的好朋友'],['苏轼', '擅长', '写词'],['黄庭坚', '擅长', '写诗']],['宋朝的著名文学家', '他的好朋友', '写词', '写诗'])

3、创建图谱–neo4j

目前neo4j应该是最容易使用的图数据库,所以我们使用neo4j进行创建,如果大家不想用图数据库,我们下一节介绍一个工具来进行可视化

3.1 链接neo4j

from py2neo import Node, Graph, Relationship, NodeMatchergraph = Graph("bolt://localhost:7687", user="neo4j", password='1qa2ws3ed',name="demo")

3.2 创建节点

def node_create(ner_list_Nh,ner_list_Ni,ner_list_Ns,predicate):if len(ner_list_Nh)!=0:for i in range(len(ner_list_Nh)):graph.create(Node('人名', name=ner_list_Nh[i]))if len(ner_list_Ni)!=0:for i in range(len(ner_list_Ni)):graph.create(Node('机构名', name=ner_list_Ni[i]))if len(ner_list_Ns)!=0:for i in range(len(ner_list_Ns)):graph.create(Node('地名', name=ner_list_Ns[i]))if len(predicate)!=0:for i in range(len(predicate)):graph.create(Node('标签', name=predicate[i]))

将所有实体,包括标签进行创建

3.3 创建边

def relationship_create(kg_list):for m in range(len(kg_list)):try:rel = Relationship(matcher.match("人名").where("_.name=" + "'" + kg_list[m][0]  + "'").first(),kg_list[m][1],matcher.match("标签").where("_.name=" + "'" + kg_list[m][2]  + "'").first())graph.create(rel)except AttributeError as e:print(e, m)

在这里插入图片描述
这里可以看到,其实这个结果有点不太理想,就是苏轼和黄庭坚之间没有建立关系,其实这个就是我们前面提到的,只使用语义角色标注创建三元组是不行的,后面我们可以结合其他方法进行优化。

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

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

相关文章

【C++干货铺】继承 | 多继承 | 虚继承

个人主页点击直达:小白不是程序媛 C系列专栏:C干货铺 代码仓库:Gitee 目录 继承的概念及定义 继承的概念 继承的定义 继承基类成员访问方式的变化 基类和派生类的赋值转化 继承中的作用域 派生类的默认成员函数 构造函数 拷贝构造…

基于Java SSM框架+Vue实现大学生兼职信息网站项目【项目源码+论文说明】计算机毕业设计

基于java的SSM框架Vue实现大学生兼职信息网站演示 摘要 21世纪的今天,随着社会的不断发展与进步,人们对于信息科学化的认识,已由低层次向高层次发展,由原来的感性认识向理性认识提高,管理工作的重要性已逐渐被人们所认…

nodejs的安装和验证

1.浏览器访问nodejs官网,根据操作系统选择对应版本的安装文件,如下图所示: 2.双击下载的安装文件,点击“Next”,如下图所示: 3.勾选“I accept the terms in the License Agreement”,然后点击“…

MIAOYUN荣获“2023中国赛宝信息技术应用创新优秀解决方案应用创新示范方向三等奖”

11月30日,2023(第四届)数字化转型推动高质量发展大会在中国海口成功召开,会上举办了2023中国赛宝信息技术应用创新优秀解决方案征集活动颁奖仪式。成都元来云志科技有限公司(简称“MIAOYUN”)联合国网浙江省…

应用于智慧工厂的AI边缘计算盒子+AI算法软硬一体化方案

智慧工厂解决方案,传统工厂/生产管理,普遍存在运营粗放、效率低、应变能力差、安全隐患突出、资源不平衡等“行业症状”; 以英码产品为核心的智能化场景解决方案,可以从本质上根治这些“症状”,如企业可利用智能预测系…

10.30 作业 C++

设计一个Per类&#xff0c;类中包含私有成员:姓名、年龄、指针成员身高、体重&#xff0c;再设计一个Stu类&#xff0c;类中包含私有成员:成绩、Per类对象p1&#xff0c;设计这两个类的构造函数、析构函数和拷贝构造函数。 #include <iostream>using namespace std;clas…

从零开始Inline Hook

中断表进入0环 通过中断门进入0环&#xff0c;首先了解一下中断门的构成 构造一个中断号 Base:函数地址 DPL:3 //因为三环使用调用门的条件就是CPL(即cs段选择子的RPL)<DPL P:1 //P为1时&#xff0c;中断表才有效 Segment Selector: 0x0008 //中断成功后切换自己的CPL 在…

拥抱复杂性:大模型的发展与挑战

原创 | 文 BFT机器人 大模型代表着机器学习和人工智能领域的前沿技术&#xff0c;它们的发展和应用对于推动科技进步和解决复杂问题具有重要意义。 01 什么是大模型&#xff1f; 大模型是指在计算机科学和人工智能领域中&#xff0c;具有庞大规模和复杂性的模型。这些模型通常…

STM32---时钟树

写在前面&#xff1a;一个 MCU 越复杂&#xff0c;时钟系统也会相应地变得复杂&#xff0c;如 STM32F1 的时钟系统比较复杂&#xff0c;不像简单的 51 单片机一个系统时钟就 可以解决一切。对于 STM32F1 系列的芯片&#xff0c;其有多个时钟源&#xff0c;构成了一个庞大的是时…

docker-compose部署zabbix+grafana

1.引言 1.1目的 zabbixgrafana实现图形化监控 2.部署环境 服务器ip服务版本192.168.5.137zabbix-server6.0.21192.168.5.137grafana10.2.2192.168.5.152zabbix-client6.0.21 3.部署zabbix-server 3.1 创建zabbix目录 mkdir zabbix3.2 编写docker-compose文件 cd zabbix…

【Linux】快速上手自动化构建工具make/makefile

&#x1f440;樊梓慕&#xff1a;个人主页 &#x1f3a5;个人专栏&#xff1a;《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》《C》《Linux》 &#x1f31d;每一个不曾起舞的日子&#xff0c;都是对生命的辜负 目录 前言 1.什么是make / makefile 2…

class-dump 混淆加固、保护与优化原理

​ 进行逆向时&#xff0c;经常需要dump可执行文件的头文件&#xff0c;用以确定类信息和方法信息&#xff0c;为hook相关方法提供更加详细的数据.class-dump的主要用于检查存储在Mach O文件的Objective-C中的运行时信息&#xff0c;为类&#xff0c;类别和协议生成声明信息&am…

leetcode-142-环形链表(C语言实现)

题目&#xff1a; 给定一个链表的头节点 head &#xff0c;返回链表开始入环的第一个节点。 如果链表无环&#xff0c;则返回 null。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&#xff0c;评…

2023年中外Top10快公司研究报告

引言 在市场竞争激烈的环境中&#xff0c;每年都有企业实现显著的高速增长&#xff0c;其利润增长率和销售增长率等关键财务指标在短期内急剧上升。本研究报告精选了一批在2015年至2022年间&#xff0c;其营业收入或营业利润年增长率超过10,000%的企业进行深入分析。这一现象反…

使用SLS日志服务采集Kong网关的日志

一、阿里云SLS 官方的接入文档已比较丰富了&#xff0c;本文不意重复说明此事。 站在使用的角度&#xff0c;以采集Kong的日志为示例&#xff0c;说明我们应该如何治理日志。 说白了&#xff0c;本文是想给你怎么省钱作一个建议&#xff0c;希望不会让你公司也“降本增笑”。…

ios-class-guard - iOS代码混淆与加固实践

​ 目录 ios-class-guard - iOS代码混淆与加固实践 摘要 引言 一、class-dump 二、ios-class-guard 混淆原理 三、ios-class-guard 混淆结果 四、ios-class-guar 的使用 ios-class-guard 不支持 Swift ios-class-guard 不支持 iPhoneOS SDK ios-class-guard --sdk-ro…

模型层——单表操作

单表操作 一 ORM简介 查询数据层次图解&#xff1a;如果操作mysql&#xff0c;ORM是在pymysq之上又进行了一层封装 MVC或者MTV框架中包括一个重要的部分&#xff0c;就是ORM&#xff0c;它实现了数据模型与数据库的解耦&#xff0c;即数据模型的设计不需要依赖于特定的数据库…

Java网络通信

什么是网络编程 网络结构三要素 IP地址 端口号 通信协议 UDP TCP

现货白银简单介绍

在贵金属投资领域&#xff0c;现货白银是当前国际上最为流行、交投最为活跃的白银投资方式&#xff0c;其交易市场遍布全球&#xff0c;包括伦敦、苏黎世、纽约、芝加哥及香港等主要市场&#xff0c;是一种以杠杆交易和做市商的形式进行的现货交易。 现货白银可以说是当下交易模…

FL Studio21.1.1.3750中文版是数字音频工作站 (DAW)

FL Studio水果音乐编曲软件中文版,一款强大的音乐制作软件,可以进行音乐编曲、剪辑、录音、混音。FL Studio21.1.1.3750中文版是数字音频工作站 (DAW) 之一&#xff0c;日新月异。它是一款录音机和编辑器&#xff0c;可让您不惜一切代价制作精美的音乐作品并保存精彩的活动画廊…