《海贼王》知识图谱构建
- 项目背景
- 项目内容
- 数据采集
3.1… 数据来源
3.2… 人物知识图谱构建
3.2.1. 抽取通用知识图谱中已有的目标域知识
3.2.2. 抽取网页中半结构化的知识
3.3… 关系抽取数据集构建
3.1. 数据集统计信息
3.4… 实体关系知识图谱构建 - 知识存储
4.1… 基于RDF 三元组数据库:Apache Jena
4.1.3 SPARQL查询示例
4.2… 基于原生图数据库:Neo4j
4.2.1. Neo4j简介
4.2.3. Cypher查询示例 - 知识抽取
5.1… 数据转换&标注统计
5.2… 训练
5.3… 训练结果
6.1. 图计算
6.1.1. 人物网络分析
6.1.2. 关键节点
6.1.3. 节点中心度
6.1.4. 社区发现
6.1.5. PageRank 6.2. 知识推理 - 知识应用
7.1… 智能问答
7.1.1. 支持的问题类型
7.1.2. 查询示例
7.2… 知识图谱可视化
参考资料
1.项目背景
《海贼王》(英文名ONE PIECE) 是由日本漫画家尾田荣一郎创作的热血少年漫画,因为其宏大的世界观、丰富的人物设定、精彩的故事情节、草蛇灰线的伏笔,受到世界各地的读者欢迎,截止2019年11 月7日,全球销量突破4亿6000万本 1 ,并被吉尼斯世界纪录官方认证为“世界上发行量最高的单一作者
创作的系列漫画” 2 。
《海贼王》从1997年开始连载至今,以及将近22年,在900多话的漫画中大量性格鲜明的角色相继登 场,故事发生的地点也在不断变化,本文转载自http://www.biyezuopin.vip/onews.asp?id=15228这既给我们带来阅读的乐趣,同时也为我们梳理故事脉络带来了挑 战。
本次任务试图为《海贼王》中出现的各个实体,包括人物、地点、组织等,构建一个知识图谱,帮助我 们更好的理解这部作品。
2.项目内容
本项目内容包括数据采集、知识存储、知识抽取、知识计算、知识应用五大部分
1.数据采集
本次项目主要采集构建了两个知识图谱和一个关系抽取数据集
人物知识图谱:主要包含各个人物的信息
关系抽取数据集:标注出自然语言中存在的实体以及他们之间的关系实体关系知识图谱:构建《海贼王》中各个实体之间关系的知识图谱
2.知识存储
尝试使用了三元组数据库Apace Jena和原生图数据库Neo4j,并分别使用RDF结构化查询语言
SPARQL和属性图查询语言Cypher,在知识图谱上进行查询。
3.知识抽取
基于之间构建的关系抽取数据集,利用deepke中提供的工具进行关系抽取实践,测试了包括
PCNN、GCN、BERT等模型在我们构建数据集上的效果
4.知识计算
图计算:在Neo4j上对实体关系知识图谱进行了图挖掘,包括最短路径查询、权威结点发 现、社区发现等
知识推理:在Apache Jena上对关系知识图谱进行了知识推理,补全了一部分的数据
5.知识应用
智能问答:基于REfO实现一个对于《海贼王》中人物的知识库问答系统(KBQA)。
可视化图片:通过D3对实体关系图片进行可视化,并整合了人物知识图谱中的信息,进行展 示。
3.数据采集
3.1.数据来源
本次项目中所使用的数据主要来源为两个:一个是从别的知识图谱中获取已经存在的知识信息,另一个 是从相关网页中爬取解析半结构化的自然语言文本信息。
# encoding=utf-8
"""
@author: SimmerChan
@contact: hsl7698590@gmail.com
@file: word_tagging.py
@time: 2017/12/20 15:31
@desc: 定义Word类的结构;定义Tagger类,实现自然语言转为Word对象的方法。
"""
import jieba
import jieba.posseg as pseg
class Word(object):
def __init__(self, token, pos):
self.token = token
self.pos = pos
class Tagger:
def __init__(self, dict_paths):
# TODO 加载外部词典
for p in dict_paths:
jieba.load_userdict(p)
# TODO jieba不能正确切分的词语,我们人工调整其频率。
jieba.suggest_freq(('喜剧', '电影'), True)
jieba.suggest_freq(('恐怖', '电影'), True)
jieba.suggest_freq(('科幻', '电影'), True)
jieba.suggest_freq(('喜剧', '演员'), True)
jieba.suggest_freq(('出生', '日期'), True)
jieba.suggest_freq(('英文', '名字'), True)
@staticmethod
def get_word_objects(sentence):
# type: (str) -> list
"""
把自然语言转为Word对象
:param sentence:
:return:
"""
return [Word(word, tag) for word, tag in pseg.cut(sentence)]
# TODO 用于测试
if __name__ == '__main__':
tagger = Tagger(['./external_dict/movie_title.txt',
'./external_dict/person_name.txt',
'./external_dict/vivre_zhpname.txt',
'./external_dict/onepiece_place_terminology.txt'])
while True:
s = input()
for i in tagger.get_word_objects(s):
print(i.token, i.pos)