一个比较具有实操性的知识图谱项目来练手,或者明确的路线做牵引对于知识图谱入门而言很重要,尤其是对于刚入门的人来说,对如何构建知识图谱还是相对陌生,这一需求更需要明确的指引。
而当前,知识图谱开源的东西较多,我们可以充分利用好开源的项目,借鉴前人的经验,进行实操,这也是老刘说NLP技术社区多个朋友的一些建议。
而就路线而言,我们可以不妨采用这样的路线:
首先,先了解知识图谱开源课程课件,对知识图谱各项技术有个大致的了解;
然后,实操一些常用的知识抽取关键模块开源项目,掌握目前性能较好的实体识别模型和关系抽取模型;
最后,再实践相对完整的知识图谱开源项目,以及开放性知识抽取开源项目完成整个知识图谱生命周期的全流程。
因此,解决“利用开源项目”来较快地认识知识图谱这一工作,本文主要从相对完整的知识图谱开源项目集合、一些常用的知识抽取关键模块开源项目、一些代表性的开放性知识抽取开源项目以及一些知识图谱开源课程课件四个角度出发,通过收集整理的方式给大家介绍,供大家参考。
一、相对完整的知识图谱开源项目集合
目前开源的知识图谱项目主要包括医疗领域、农业领域、金融领域知识图谱,项目相对来说比较完整。
但需要注意的是,目前开放的项目基本上都是采用爬虫方法,经本体定义后存储相应图数据库,最后进行问答、可视化等操作,通过事件操作,可以对知识图谱的全流程能有个比较好的认识,并未涉及到抽取等细节。
项目主要介绍star较多的几个开源项目,包括QASystemOnMedicalKG医疗知识图谱问答、Agriculture_KnowledgeGraph农业知识图谱、Financial-Knowledge-Graphs小型金融知识图谱、stock-knowledge-graph小型的证券知识图谱等四个。
1、QASystemOnMedicalKG医疗知识图谱问答
本项目是作者刘焕勇开源的一个项目,立足医药领域,以垂直型医药网站为数据来源,以疾病为核心,构建起一个包含7类规模为4.4万的知识实体,11类规模约30万实体关系的知识图谱。 本项目将包括以下两部分的内容:基于垂直网站数据的医药知识图谱构建,基于医药知识图谱的自动问答。
项目收益: 基于该项目,可以了解到如何针对现有的医药网站数据,如何设计知识图谱schema,如何使用cpyher语句插入neo4j数据库,以及如何基于特定领域图谱数据设计图谱问答问题类型,并进行实现。
地址:https://github.com/liuhuanyong/QASystemOnMedicalKG
2、Agriculture_KnowledgeGraph农业知识图谱
本项目是上海市《农业信息服务平台及农业大数据综合利用研究》子课题《上海农业农村大数据共享服务平台建设和应用》的研究成果。华师大课题组在前期国家重点研发计划《大数据知识工程基础理论及其应用研究》研究基础上,在本项目中,基于碎片化农业大数据,构建面向智慧农业的知识图谱及其应用系统。
项目收益:该项目给出了一些农业知识图谱的构建项目案例,包括其中的技术架构,包括数据的定义、基于Neo4j的数据导入、关系抽取、基于knn的实体分类以及数据导入的语句,从中可以熟悉如何设计知识图谱架构,如何进行实体分类以及实体关系抽取的实操;
// 导入新的节点
LOAD CSV WITH HEADERS FROM "file:///new_node.csv" AS line
CREATE (:NewNode { title: line.title })
//添加索引
CREATE CONSTRAINT ON (c:NewNode)
ASSERT c.title IS UNIQUE
//导入hudongItem和新加入节点之间的关系
LOAD CSV WITH HEADERS FROM "file:///wikidata_relation2.csv" AS line
MATCH (entity1:HudongItem{title:line.HudongItem}) , (entity2:NewNode{title:line.NewNode})
CREATE (entity1)-[:RELATION { type: line.relation }]->(entity2)
LOAD CSV WITH HEADERS FROM "file:///wikidata_relation.csv" AS line
MATCH (entity1:HudongItem{title:line.HudongItem1}) , (entity2:HudongItem{title:line.HudongItem2})
CREATE (entity1)-[:RELATION { type: line.relation }]->(entity2)
地址:https://github.com/qq547276542/Agriculture_KnowledgeGraph
3、Financial-Knowledge-Graphs小型金融知识图谱
Financial-Knowledge-Graphs小型金融知识图谱构建示例由作者jm199504开源共享,里面介绍了如何使用Tushare工具包获取开源金融数据,包括股票基本信息、股票持有股东信息、股票概念信息、股票公告信息、财经新闻信息、概念信息、沪股通和深股通成分信息、股票价格信息等数据,安装neo4j图数据库,读取csv文件进行图谱读写操作。
项目收益:通过该项目可以大致熟悉如何通过抓取线上数据,然后基于neo4j数据库进行数据导入,生成图谱,可以强化对neo4j图数据库的使用能力,包括如何使用neo4j图数据库的恶内置图算法能力;
MERGE (zhen:Person {name: "Zhen"})
MERGE (praveena:Person {name: "Praveena"})
MERGE (michael:Person {name: "Michael"})
MERGE (arya:Person {name: "Arya"})
MERGE (karin:Person {name: "Karin"})
MERGE (zhen)-[:FRIENDS]-(arya)
MERGE (zhen)-[:FRIENDS]-(praveena)
MERGE (praveena)-[:WORKS_WITH]-(karin)
MERGE (praveena)-[:FRIENDS]-(michael)
MERGE (michael)-[:WORKS_WITH]-(karin)
MERGE (arya)-[:FRIENDS]-(karin)
// 计算 Michael 和 Karin 之间的亲密度
MATCH (p1:Person {name: 'Michael'})
MATCH (p2:Person {name: 'Karin'})
RETURN algo.linkprediction.adamicAdar(p1, p2) AS score
// score: 0.910349
// 基于好友关系计算 Michael 和 Karin 之间的亲密度
MATCH (p1:Person {name: 'Michael'})
MATCH (p2:Person {name: 'Karin'})
RETURN algo.linkprediction.adamicAdar(p1, p2, {relationshipQuery: "FRIENDS"}) AS score
// score: 0.0
地址:https://github.com/jm199504/Financial-Knowledge-Graphs
4、stock-knowledge-graph小型的证券知识图谱
该项目与2中的项目类似,利用网络上公开的数据构建一个小型的证券知识图谱(知识库)。
该项目分成几个任务:
一个是从⽹页中抽取董事会的信息,如给定的html文件中,需要对每一个股票/公司抽取董事会成员的信息,这部分信息包括董事会成员“姓名”、“职务”、“性别”、“年龄”共四个字段;一个是获取股票行业和概念的信息;一个是设计知识图谱,如创建“人”实体,这个人拥有姓名、性别、年龄;一个是创建可以导⼊Neo4j的csv文件;一个是利用上面的csv文件生成数据库;一个是基于构建好的知识图谱,通过编写Cypher语句回答问题;
项目收益: 该项目是个不涉及具体抽取的项目,但其中的图谱构建思想值得大家进行事件,例如,在图谱设计环节,
设计一个这样的图谱:
设计思想如下,可以通过抓取的数据进行设计
创建“人”实体,这个人拥有姓名、性别、年龄
创建“公司”实体,除了股票代码,还有股票名称
创建“概念”实体,每个概念都有概念名
创建“行业”实体,每个行业都有⾏业名
给“公司”实体添加“ST”的标记,这个由LABEL来实现
创建“人”和“公司”的关系,这个关系有董事长、执行董事等等
创建“公司”和“概念”的关系
创建“公司”和“行业”的关系
另外,在创建可以导⼊Neo4j的csv文件方面,可以学习到如何根据neo4j数据库的数据要求,修改成对应的数据格式,例如:分别生成了 executive_prep.csv, stock_industry_prep.csv, stock_concept_prep.csv,但这些文件不能直接导入到Neo4j数据库。
所以需要做⼀些处理,并生成能够直接导入Neo4j的csv格式,即需要生成这⼏个文件:executive.csv, stock.csv, concept.csv, industry.csv, executive_stock.csv, stock_industry.csv, stock_concept.csv
最后,在利用上面的csv文件生成数据库任务中,可以学习到如何使用neo4j-import的命令,来进行数据导入:
neo4j_home$ bin/neo4j-admin import --id-type=STRING --nodes executive.csv --nodes stock.csv --nodes concept.csv --nodes industry.csv --relationships executive_stock.csv --relationships stock_industry.csv --relationships stock_concept.csv
地址:https://github.com/lemonhu/stock-knowledge-graph
二、一些常用的知识抽取关键模块开源项目
知识图谱构建中的关键步骤包括ner实体识别、实体关系抽取、事件抽取等,其中大家讨论最多的就是如何实现即插即用的实体识别和实体关系抽取,下面对一些代表性开源组件进行论述:
1、实体识别NER项目
实体识别模型当前比较主流的是两种,一种是BERT-NER系列,包括BERT+Softmax、BERT+CRF、BERT+Span、BERT+MRC等方法,另一种是基于指针网络的方法,如GlobalPointer、TPlinker:
1)BERT-NER-Pytorch实体识别
以下两个项目提供了BERT+Softmax、BERT+CRF、BERT+Span、BERT+MRC三种算法下的ner方法;
地址:https://github.com/lonePatient/BERT-NER-Pytorch
地址:https://github.com/z814081807/DeepNER
2)GlobalPointer_pytorch实体识别
类似于多头机制来做实体抽取,可以解决嵌套实体和非嵌套实体的问题,抽取的特征是头尾节点的点乘结果,TPlinker是加性特征,另外通过引入旋转位置编码RoPE可以提高了效果。
该项目参考苏剑林的文章GlobalPointer:用统一的方式处理嵌套和非嵌套NER,并用Pytorch实现:
地址:https://github.com/gaohongkui/GlobalPointer_pytorch
2、实体关系抽取项目
实体关系抽取,可以分成基于联合的方法以及基于pipeline串行的方法,前者代表的方法为pure,后者比较流行并且验证可行的方法包括casrel以及GPLinker。
1)casrel实体关系抽取
CasRel 本质上也是基于参数共享的联合实体关系抽取方法,它通常被大家称作层叠指针网络,将关系作为主语到宾语的映射函数。具体分为两步:第一步识别句中所有可能的主语;第二步针对每个主题探测各种关系及其对应的宾语。最终设计了一个端到端的级联双标签(主语标签,关系宾语标签)框架。有点像多轮问答来做关系抽取,他这里先抽取subject,然后来预测每个p的起始位置。
地址:https://www.kaggle.com/code/xuyouqian/casrel/notebook
2)GPLinker实体关系抽取
GPLinker是一种实体与关系联合抽取的方法,与casrel方法有可以匹敌的效果,先利用Global Pointer抽取subject的首尾(i, j)和object的首尾位置(i, j),然后利用Global Pointer抽取每一种关系p的实体的head的match的位置(hi, hj)和实体的尾部tail的match的位置(ti, tj)组合,最终输出交集的结果。
地址:https://github.com/xhw205/GPLinker_torch
地址:https://github.com/bojone/bert4keras/blob/master/examples/task_relation_extraction_gplinker.py
3)PURE实体关系抽取
PURE,是pipeline式关系抽取的模型,首先为每一个实体类型生成4个标记token,然后给定一组实体对,取出该实体对对应的4个标记token,接着顺序拼接所有实体对的标记token到文本token后面,之后将token传给特征提取器(一般为Bert),拿到每个token的隐向量输出,最后每4个标记token选择第1个和第3个标记token的隐向量进行拼接,传给分类层进行分类。
地址:https://github.com/princeton-nlp/PURE
三、一些代表性的开放性知识抽取开源项目
开放性知识抽取与预定义schema的抽取不同,其不需要预先定义好知识图谱本体,而是直接通过模型训练或者句法规则进行抽取。
1、spo_extract_platform开放三元组抽取
本项目作为笔者在开放领域的三元组抽取的一次尝试,标注内容大部分为人物头衔,人物关系,公司与人的关系,影视剧主演、导演信息,以句子级别进行标注,标注出句子中的主语,谓语,宾语,形成标注序列; 利用标注好的语料,采用bert+dl的方法进行训练;采用序列标注算法(ALBERT+BiLSTM+CRF)进行S,P,O识别,对新的语料,预测主语,谓语,宾语,然后利用一定的策略,如文本二分类(ALBERT+BiGRU+ATT)进行关系抽取,形成实体关系;
例如,给定:
6月25日,华为常务董事、运营商事业部总裁丁耘表示,
华为已在全球范围内获得50个5G商用合同,其中2/3是由华为协助其构建的。
抽取结果为:
[{'word': '华为', 'start': 6, 'end': 8, 'type': 'SUBJ'},
{'word': '常务董事', 'start': 8, 'end': 12, 'type': 'PRED'},
{'word': '运营商事业部', 'start': 13, 'end': 19, 'type': 'SUBJ'},
{'word': '总裁', 'start': 19, 'end': 21, 'type': 'PRED'},
{'word': '丁耘', 'start': 21, 'end': 23, 'type': 'OBJ'},
{'word': '华为', 'start': 26, 'end': 28, 'type': 'SUBJ'},
{'word': '华为', 'start': 54, 'end': 56, 'type': 'SUBJ'}]
按主语,谓语,宾语进行归类,形成主体集合{华为, 运营商事业部},谓语集合{常务董事, 总裁}以及宾语集合{丁耘};
接着,按照各个元素在句子出现的位置进行组合,比如华为的位置,离常务董事挨得近,那么形成一个三元组:
['华为', '常务董事', '丁耘'],
同理,形成另一个三元组:
['运营商事业部', '总裁', '丁耘'];
将句子按照逗号进行分割,形成小句子集合,看三元组的三个元素是否都在一个小句子中,如果是,则提取该三元组,如果不是,则放弃该三元组。
地址:https://github.com/percent4/knowledge_graph_demo
2、基于规则的开放因果抽取项目
基于因果关系知识库的因果事件图谱构建,用于构建因果事理图谱项目,本项目以构造和总结因果模板,结合中文语言特点,构建因果语言知识库的方式代替。 本项目是对因果事件抽取以及因果知识图谱构建的一种尝试。
'''2由因到果配套式'''
def ruler2(self, sentence):
'''
conm1:〈因为,从而〉、〈因为,为此〉、〈既[然],所以〉、〈因为,为此〉、〈由于,为此〉、〈只有|除非,才〉、〈由于,以至[于]>、〈既[然],却>、
〈如果,那么|则〉、<由于,从而〉、<既[然],就〉、〈既[然],因此〉、〈如果,就〉、〈只要,就〉〈因为,所以〉、 <由于,于是〉、〈因为,因此〉、
<由于,故〉、 〈因为,以致[于]〉、〈因为,因而〉、〈由于,因此〉、<因为,于是〉、〈由于,致使〉、〈因为,致使〉、〈由于,以致[于] >
〈因为,故〉、〈因[为],以至[于]>,〈由于,所以〉、〈因为,故而〉、〈由于,因而〉
conm1_model:<Conj>{Cause}, <Conj>{Effect}
'''
datas = list()
word_pairs =[['因为', '从而'], ['因为', '为此'], ['既然?', '所以'],
['因为', '为此'], ['由于', '为此'], ['除非', '才'],
['只有', '才'], ['由于', '以至于?'], ['既然?', '却'],
['如果', '那么'], ['如果', '则'], ['由于', '从而'],
['既然?', '就'], ['既然?', '因此'], ['如果', '就'],
['只要', '就'], ['因为', '所以'], ['由于', '于是'],
['因为', '因此'], ['由于', '故'], ['因为', '以致于?'],
['因为', '以致'], ['因为', '因而'], ['由于', '因此'],
['因为', '于是'], ['由于', '致使'], ['因为', '致使'],
['由于', '以致于?'], ['因为', '故'], ['因为?', '以至于?'],
['由于', '所以'], ['因为', '故而'], ['由于', '因而']]
for word in word_pairs:
pattern = re.compile(r's?(%s)/[p|c]+s(.*)(%s)/[p|c]+s(.*)' % (word[0], word[1]))
result = pattern.findall(sentence)
data = dict()
if result:
data['tag'] = result[0][0] + '-' + result[0][2]
data['cause'] = result[0][1]
data['effect'] = result[0][3]
datas.append(data)
if datas:
return datas[0]
else:
return {}
展示效果:
地址:https://github.com/liuhuanyong/CausalityEventExtraction
四、一些知识图谱开源课程课件
当然,目前开源的知识图谱课程也是在理论端可以作为我们进行知识图谱学习的一个很好的指引,例如,东南大学《知识图谱》研究生课程,由东南大学公开,汪鹏老师授课,目前已经开放相关课件可供学习,其中包括:
第1讲 知识图谱概论、第2讲 知识表示、第3讲 知识建模、第4讲 知识抽取基础:问题和方法、第5讲 知识抽取:数据采集;
第6讲 知识抽取:实体识别、第7讲 知识抽取:关系抽取、第8讲 知识抽取:事件抽取、第9讲 知识融合;
第10讲 知识图谱表示学习、第11讲 知识存储、第12讲 基于知识的智能问答、第13讲 实体链接、第14讲 知识推理共14个章节。
收益: 基于该项目,可以更系统的学习知识图谱相关概念以及技术方法,可以作为入门参考,此外还给出了一些相关算法的paper;
地址:https://github.com/npubird/KnowledgeGraphCourse
总结
为了“利用开源项目”来较快地认识知识图谱这一工作,本文主要从相对完整的知识图谱开源项目集合、一些常用的知识抽取关键模块开源项目、一些代表性的开放性知识抽取开源项目以及一些知识图谱开源课程课件四个角度出发,通过收集整理的方式给大家介绍。
当然,开源的项目其实在复现的过程中兴许会出现一些实际的问题,如环境错误、数据缺失等,这时候我们可以进一步地动用搜索能力去补充,并加以耐心。
最后,感谢开源工作者的无私奉献。
参考文献
1、https://blog.csdn.net/qq_16949707/article/details/127429413
2、https://kexue.fm/archives/8888
关于我们
老刘,刘焕勇,NLP开源爱好者与践行者,主页:https://liuhuanyong.github.io。
就职于360人工智能研究院、曾就职于中国科学院软件研究所。
老刘说NLP,将定期发布语言资源、工程实践、技术总结等内容,欢迎关注。
对于想加入更优质的知识图谱、事件图谱实践、相关分享的,可关注公众号,在后台菜单栏中点击会员社区->会员入群加入。
原文始发于微信公众号(老刘说NLP):老刘说知识图谱实践指引:知识图谱代表性全流程开源项目、NER/RE关键模型与开放课程概述