常识图谱之《海贼王-ONEPICE》范畴图谱项目实战(含码源):数据收集、常识存储、常识抽取、常识核算、常识运用、图谱可视化、问答体系(KBQA)等
实体联系可视化页面可视化页面尝鲜
1. 项目背景& 项目内容
《海贼王》(英文名ONE PIECE) 是由日本漫画家尾田荣一郎创作的热血少年漫画,由于其宏大的国际观、丰厚的人物设定、精彩的故事情节、草蛇灰线的伏笔,遭到国际各地的读者欢迎,截止2019年11月7日,全球销量打破4亿6000万本[^1],并被吉尼斯国际纪录官方认证为“国际上发行量最高的单一作者创作的系列漫画”[^2]。
《海贼王》从1997年开端连载至今,以及将近22年,在900多话的漫画中很多性情显着的人物相继上台,故事产生的地址也在不断改变,这既给咱们带来阅览的乐趣,一起也为咱们梳理故事头绪带来了挑战。
本次使命试图为《海贼王》中呈现的各个实体,包含人物、地址、安排等,构建一个常识图谱,协助咱们更好的理解这部著作。
本项目内容包含数据收集、常识存储、常识抽取、常识核算、常识运用五大部分
-
数据收集
本次项目首要收集构建了两个常识图谱和一个联系抽取数据集
- 人物常识图谱:首要包含各个人物的信息
- 联系抽取数据集:标示出自然言语中存在的实体以及他们之间的联系
- 实体联系常识图谱:构建《海贼王》中各个实体之间联系的常识图谱
-
常识存储
测验运用了三元组数据库Apace Jena和原生图数据库Neo4j,并别离运用RDF结构化查询言语SPARQL和特点图查询言语Cypher,在常识图谱上进行查询。
-
常识抽取
依据之间构建的联系抽取数据集,运用deepke中供给的东西进行联系抽取实践,测验了包含PCNN、GCN、BERT等模型在咱们构建数据集上的作用
-
常识核算
- 图核算:在Neo4j上对实体联系常识图谱进行了图挖掘,包含最短途径查询、威望结点发现、社区发现等
- 常识推理:在Apache Jena上对联系常识图谱进行了常识推理,补全了一部分的数据
-
常识运用
- 智能问答:依据REfO完结一个关于《海贼王》中人物的常识库问答体系(KBQA)。
- 可视化图片:经过D3对实体联系图片进行可视化,并整合了人物常识图谱中的信息,进行展示。
码源下载见文末跳转
码源下载见文末跳转
2.数据收集
- 数据来历
本次项目中所运用的数据首要来历为两个:一个是从别的常识图谱中获取现已存在的常识信息,另一个是从相关网页中爬取解析半结构化的自然言语文本信息
2.1 人物常识图谱构建
2.1.1 抽取通用常识图谱中已有的目标域常识
常识图谱技能近些年来快速开展,一些公司机构现已构建了许多通用常识图谱,咱们可以从中抽取出咱们目标范畴内相关的实体常识信息,作为咱们常识图谱的冷发动数据。
CN-DBpedia[^3]是由复旦大学常识工场[^4]实验室研发并维护的大规模通用范畴结构化百科,咱们挑选其作为通用常识图谱来历。
整个处理流程如下:
- 构建《海贼王》实体词汇库
- 获取实体列表
- 挑选实体列表
- 获取图谱中对应实体的三元组常识
构建《海贼王》实体词汇库
首要经过范畴WiKi获取《海贼王》中的实体词汇库。在这里,咱们在萌娘百科的相关页面[^6]中获取由粉丝爱好者收拾的词条名信息,作为词汇库。
咱们将原始的半结构化词条数据保存在 cndbpedia/data/raw_moegirl_onepiece_entries.txt
中,并运用正则表达式对其进行解析
python cndbpedia/parse_raw_moegirl_onepiece_entries.py
输出的成果保存在 cndbpedia/data/processed_moegirl_onepiece_entries.txt
中,总共提取了509个词条名
获取实体列表
咱们运用常识工厂供给的API[^5],将词条名作为输入实体指称项称号(mention name),获取回来对应实体(entity)的列表。
python cndbpedia/get_onepiece_cndbpedia_entities.py
总共获取了1014个不同的实体名,并输出了两个文件,输出的成果保存在 cndbpedia/data
文件夹中。
-
cndbpedia_onepiece_entities_list.txt
:保存了一切识别出的CN-DBpedia中的实体名,例如爱德华纽盖特(《航海王燃烧意志》游戏人物) 爱德华纽盖特(日本漫画《海贼王》中的人物) 爱莎(《弑神者!》中的弑神者之一) 爱莎(《海贼王》中的人物) 爱莎(艾尔之光游戏人物)
-
moelgirl_cndbpedia_entities_mapping.json
:保存着从moegirl的的条目作为实体指称项称号,在api上查找到的对应的实体列表,例如"夏奇": [ "夏奇(日本动漫《海贼王》人物)", "夏奇(福建人民艺术剧院主持人)", "夏奇(深圳市夏奇实业有限公司)", "夏奇(《永嘉诗联》主编)" ], "布拉曼克": [ "布拉曼克" ], "艾佛兰德拉": [ "艾佛兰德拉" ], "顶上战役": [ "大事情(漫画《海贼王》中顶上战役)" ], "堪十郎": [ "堪十郎" ],
挑选实体列表
由于自然言语和实际国际的多义性,往往一个mention name可能对应着常识图谱中的多个不同实体。就拿 布鲁克
这个姓名来说,在api回来的实体列表中,就有好多不同的实体
布鲁克
布鲁克(奥地利城市穆尔河畔布鲁克缩写)
布鲁克(广告策划师)
布鲁克(日本动漫《海贼王》中的人物)
布鲁克(温力铭演唱歌曲)
布鲁克(游戏《赛尔号》中的精灵)
布鲁克(西班牙2010年拍照电影)
而其间第四个才是咱们需求的。
因而咱们可以设置一些挑选条件,只有当实体名中包含:海贼王,航海王,海贼,航海,onepiece,one piece,动漫,漫画
这些要害词之一时,才认为是咱们需求的实体
python cndbpedia/filter_moelgirl_cndbpedia_entities_mapping_file.py
输出的成果保存在 cndbpedia/data
文件夹中
**挑选成果:**在509个词条中
- 有162个词条在CN-DBpedia没有对应的实体名,这些词条被保存在
moelgirl_cndbpedia_api_no_results_mention_name_list.txt
; - 有11个词条虽然有实体名,但一切对应实体名中都没有包含上面提到的要害词,这些词条被保存在
filter_out_entities_mapping.json
- 剩下336个词条中,都有对应符合条件的实体名,总共有357个。这些词条被保存在
query_avpair_entities_list.txt
,此外query_avpair_entities_mapping.json
中保存着这些合法词条名和实体名对应的字典。
获取图谱中对应实体的三元组常识
咱们运用常识工厂供给的API[^5],依据前面挑选的实例列表,获取图谱中对应实体的三元组常识
python cndbpedia/get_onepiece_cndbpedia_avpair.py
输出成果保存在 cndbpedia/data
文件夹中
-
query_avpair_cndbpedia_onepiece_results.json
:保存着每个实体对应的三元组常识的字典,采用两级索引结构,榜首级索引是mention name,第二级索引是实体姓名,示例如下"砂糖": { "砂糖(《海贼王》人物)": { "性别": "女", "配音": "詹雅菁(台湾)", "中文名": "砂糖", "上台著作": "海贼王", "初次上台": "漫画第682话、动画608话", "恶魔果实": "超人系童趣果实", "职位": "唐吉诃德宗族梅花军特别干部", "外文称号": "Sugar", "年纪": "表面年纪10岁,真实年纪22岁", "CATEGORY_ZH": "人物", "DESC": "砂糖是日本动漫《海贼王》中的人物,童趣果实能力者。唐吉诃德宗族干部,从属梅花军托雷波尔。被宗族视为重要的干部,多弗朗明哥为此特别安排宗族最高干部托雷波尔担任她的贴身警卫。" } },
-
query_avpair_keys_list_file.txt
:保存在一切特点称号的列表
2.1.2 抽取网页中半结构化的常识
生命卡(vivre card)[^7]是海贼王官方收拾发布的人物资料图鉴,包含着丰厚的人物信息。国内的粉丝爱好者也将其翻译成了中文版别,并发布在了网页上[^8]。这部分便是希望抽取Talkop论坛中相关网页中存在的半结构化信息,构建对应人物的常识图谱。
抽取流程
由于格局较为固定,因而采用模板匹配的方法来抽取常识,整个流程如下:
-
从网页中获取原始文本信息
-
人工删除不相关的文本
-
运用代码以模板匹配的方法,主动抽取人物特点信息
cd talkop python parse_processed_manual_talkop_vivre_card.py
输出的文件保存在
talkop/data/processed_manual_talkop_vivre_card
文件夹中,每个网页对应着三个输出文件-
xxx-predicate_key_list.txt
:一切解析得到的predicate -
xxx-entities_id_name_list.txt
:一切解析得到的id和实体名 -
xxx-entities_avpair.json
:抽取到一切实体的特点常识,以json的格局保存
-
-
人工校验:例如:检查是否抽取到了一切的实体、经过检查抽取的predicate成果来调整模板。整个进程中是代码主动抽取和人工校验构成闭环的进程,在闭环进程中不断补充模板信息,改善抽取成果
在整个进程中,2、3、4是不断循环往复的进程,直至抽取的常识满足咱们的需求。
汇总成果
在上面部分中,咱们别离抽取了各个网页中人物实体的特点信息,现在将这些信息进行进一步的汇总
cd talkop
python summary_talkop_vivre_card.py
从汇总的成果可以看到,总共包含660个不同的实体,164个不同的predicate
输出的文件保存在 talkop/data/processed_manual_talkop_vivre_card
文件夹中,总共有两个文件:
-
summary_predicate_set.txt
:一切predicate的汇总 -
summary_entities_id_name_list.txt
:一切抽取得到的实体名以及对应ID的汇总
2.2. 联系抽取数据集构建
-
标示数据来历:在前面构建的人物常识图谱中,有一项重要的特点是前史信息,记录着每个人物在故事中的时间线以及对应的故事。每个人的前史信息记录着其与其他实体之间交互的信息,咱们可以运用它来构建咱们垂直范畴内的联系抽取数据集
-
标示东西:精灵标示帮手[^8]
-
构建方法:自底向上构建,在构建进程中逐渐构建整个图谱的schema
-
**数据标示格局:**精灵标示帮手供给导出json格局,其详细方式如下所示,其间
T
和E
别离表明标示出的实体信息和联系信息{ "content": "xxxx" "labeled": true, "outputs": { "annotation": { "A": [""], "E": [""], "R": ["",{ "arg1": "Arg1", "arg2": "Arg2", "from": 1, "name": "到过", "to": 2 }, ], "T": ["",{ "attributes": [], "end": 7, "id": 1, "name": "人", "start": 0, "type": "T", "value": "蒙其D路飞" }, ] } }, "path": "D:\\annot\\fuseki_vivrecard_sentence_item.txt", "time_labeled": 1578072175246 }
-
数据存储方位: 被标示的原始数据被保存在
deepke-master/data/vivrecard/rawfuseki_vivrecard_sentence_item.txt
原始标示成果被保存在deepke-master/data/vivrecard/annot/outputs/fuseki_vivrecard_sentence_item.json
。为了方便后续联系抽取模型处理,咱们将标示数据转为符合deepke项目格局的数据
并保存在
deepke-master/data/vivrecard/origin
,详细详情拜见常识抽取部分
2.3 数据集统计信息
-
实体类型:总共7种实体:’事情’, ‘安排’, ‘船只’, ‘地址’, ‘职务’, ‘恶魔果实’, ‘人’
-
联系类型:总共22种联系
head_type tail_type relation index freq None None None 0 0 人 事情 参加 1 36 人 人 同盟 2 1 人 人 夫妻 3 3 人 人 战役 4 38 人 人 母亲 5 3 人 人 父亲 6 4 人 人 教师 7 6 人 人 遇见 8 100 人 地址 出生地 9 3 人 地址 到过 10 145 人 恶魔果实 具有果实 11 10 人 安排 创立 12 23 人 安排 加入 13 66 人 安排 归于 14 38 人 安排 战役 15 20 人 安排 离开 16 18 人 安排 遇见 17 14 人 安排 领导 18 15 人 职务 担任 19 70 人 船只 制作 20 2 安排 安排 战役 21 1 这些联系的频数柱状图如下图所示,可以看到这些联系展现出显着的长尾散布
- 练习正样本个数:616个
2.4 实体联系常识图谱构建
在进行联系抽取数据集的标示进程中,咱们将标示的实体和联系独自导出,构建《海贼王》实体联系数据集
在上述进程中,总共标示了307个不同的实体,569个不同结点间的联系
cd deepke-master
python utils/convert_vivrecard2deepke.py
输出的实体联系数据保存在 deepke-master/data/vivrecard/summary/vizdata_vivrecard_relation.json
,可用于后续进行常识图谱可视化,详细拜见常识图谱可视化部分
3. 常识存储
3.1. 依据RDF 三元组数据库:Apache Jena
3.1.1 Jena 简介&项目实践
Jena[^9]是 Apache 顶级项目,其前身为惠普实验室开发的 Jena 东西包.Jena 是语义 Web 范畴首要的开源框 架和 RDF 三元组库,较好地遵从了 W3C 规范,其功用包含:RDF 数据管理、RDFS 和 OWL 本体管理、SPARQL 查询处理等.Jena 具备一套原生存储引擎,可对 RDF 三元组进行依据磁盘或内存的存储管理.一起,具有一套基 于规矩的推理引擎,用以履行 RDFS 和 OWL 本体推理使命.
avpair to triple
以vivrecard人物特点常识图谱为例,首先咱们将之前取得的数据,转化为Jena支撑解析的 N-Triple
三元组格局,命名空间前缀为 <http://kg.course/talkop-vivre-card/>
cd talkop
python avpair2ntriples_talkop_vivre_card.py
导出的 N-Triple
格局的数据保存在 talkop/data/processed_manual_talkop_vivre_card/ntriples_talkop_vivre_card.nt
,总共有14055个,其间非空triples有12863个
NOTE:
-
在项目构建进程中,咱们也将从CN-DBpedia获取的常识转化为
N-Triple
格局,命名空间前缀为<http://kg.course/onepiece/>
python cndbpedia/avpair2ntriples_onepiece_cndbpedia.py
成果保存在
cndbpedia/data/ntriples_cndbpedia_onepiece.nt
,总共有4691个triple
发动 Fuseki
按照陈华均教师供给文件:github.com/zjunlp/kg-c…
进一步装备fuseki,上传数据集就可以查询了
3.1.2 SPARQL查询示例
SPARQL[^11] 是 W3C 制定的 RDF 常识图谱规范查询言语.SPARQL 从语法上学习了 SQL.SPARQL 查询的 基本单元是三元组形式(triple pattern),多个三元组形式可构成基本图形式(basic graph pattern).SPARQL 支撑多 种运算符,将基本图形式扩展为复杂图形式(complex graph pattern).SPARQL 1.1 版别引入了特点途径(property path)机制以支撑 RDF 图上的导航式查询.下面运用图 2 所示的电影常识图谱 RDF 图,经过示例介绍 SPARQL 言语的基本功用. [^10]
下面给出了运用SPARQL在咱们构建的数据库上进行查询的示例
-
查询前五个人物的身高
PREFIX : <http://kg.course/talkop-vivre-card/> select ?s ?name ?zhname ?height ?o where { ?s ?height ?o . FILTER(?height in (:身高, :身长)) . OPTIONAL { ?s :称号 ?name. ?s :外文名 ?zhname.} } limit 5
成果
"s" , "name" , "zhname" , "height" , "o" , ":0001" , "【蒙其D路飞/Monkey D Luffy】" , "Monkey D Luffy" , ":身高" , "174cm" , ":0004" , "【乌索普/Usopp】" , "Usopp" , ":身高" , "174cm" , ":0511" , "【乔艾莉波妮/Jewelry Bonney】" , "Jewelry Bonney" , ":身高" , "174cm" , ":0002" , "【罗罗诺亚索隆/Roronoa Zoro】" , "Roronoa Zoro" , ":身高" , "181cm" , ":0224" , "【缇娜/Hina】" , "Hina" , ":身高" , "181cm" ,
-
挑选生日范围
PREFIX : <http://kg.course/talkop-vivre-card/> select ?s ?name ?o where { ?s :生日 ?o . ?s :称号 ?name . filter(?o > '4月1日' && ?o < '5月1日') } limit 5
成果
"s" , "name" , "o" , ":0009" , "【布鲁克/Brook】" , "4月3日" , ":0660" , "【伯尔杰米/Porchemy】" , "4月3日" , ":0010" , "【甚平/Jinbe】" , "4月2日" , ":0076" , "【哲夫/Zeff】" , "4月2日" , ":0028" , "【克比/Koby】" , "5月13日" ,
3.2. 依据原生图数据库:Neo4j
3.2.1. Neo4j简介&Cypher查询示例
Neo4j[^12]是由 Neo 技能公司开发的图数据库.可以说,Neo4j 是现在盛行程度最高的图数据库产品.Neo4j 基 于特点图模型,其存储管理层为特点图的节点、节点特点、边、边特点等元素规划了专门的存储方案.这使得 Neo4j 在存储层关于图数据的存取功率优于联系数据库.
#####4.2.2. 项目实践
relation to triple
以实体联系常识图谱为例,首先咱们将之前取得的各个实体之间联系的数据,转化为Jena支撑解析的 N-Triple
三元组格局,命名空间前缀为 <http://kg.course/talkop-vivre-card/deepke/>
cd deepke-master
python utils/convert_vivrecard2deepke.py
导出的 N-Triple
格局的数据保存在 deepke-master/data/vivrecard/summary/vivrecard_ntriples.nt
,总共有1848个
启用 Neo4j
Neo4j的下载装置可以参阅: neo4j.com/download-th…
cd D:\neo4j\bin
neo4j.bat console
之后访问:http://localhost:7474/
就可以了
默许的用户名和暗码都是 neo4j
Cypher 开端是图数据库 Neo4j 中完结的特点图数据查询言语,是一种声明式的言语,用户只需求声明查什么,而不需求联系怎样查。
下面给出了运用Cypher在咱们构建的数据库上进行查询的示例
-
导入
CREATE INDEX ON :Resource(uri) CALL semantics.importRDF("file:///${PROJECT_PATH}/deepke-master/data/vivrecard/summary/vivrecard_ntriples.nt","N-Triples")
-
检查schema
call db.schema()
把resource屏蔽掉,就能清楚的看到schema了
-
查询前100个人
MATCH (n:ns0__人) RETURN n LIMIT 100
-
查询归于人的结点中,URI里边包含
薇薇
的结点MATCH (n:ns0__人) WHERE n.uri CONTAINS '薇薇' RETURN n.uri
n.uri “kg.course/talkop-vivr…” “kg.course/talkop-vivr…” “kg.course/talkop-vivr…” -
依据uri挑选姓名间最短途径
MATCH p=shortestPath( (n1)-[*]-(n2) ) WHERE n1.uri CONTAINS '斯摩格' and n2.uri CONTAINS '罗宾' RETURN p
-
依据姓名挑选德雷斯罗萨到司法岛里边四跳的途径
# 五跳内能到的一切途径 # 9312 多萝菲(Miss.圣诞快乐) # 9306 本贝克曼 MATCH p = ((n1)-[*4]-(n2)) WHERE n1.uri CONTAINS '司法岛' and n2.uri CONTAINS '德雷斯罗萨' RETURN p
可以发现这里边存在一些环路的状况,即同一个结点在途径中呈现两次
4. 常识抽取
DeepKE[^13]依据 Pytorch 的深度学习中文联系抽取处理套件。在这部分中咱们运用之前构建的联系抽取数据集和deepke,进行中文联系抽取实践
4.1. 数据转化&标示统计
在这部分,咱们需求完结以下三部分内容:
- 将咱们的标示成果转化为deepke所接纳的格局
- 为了保证联系散布均匀,将数据随机打乱
- 完结练习集、测验集、验证集的区分,现在按 7:2:1进行区分
运用 deepke-master/utils/convert_vivrecard2deepke.py
完结数据格局转化
cd deepke-master
python utils/convert_vivrecard2deepke.py
输出
总共有616个练习正样本,其间train、test、valid别离有:431/123/62个
输出的文件保存在 deepke-master/data/vivrecard/
中的 origin
和 summary
文件夹中
├── annot
│ └── outputs
│ └── formatted_fuseki_vivrecard_sentence_item.json # 对json文件进行缩进等格局化
├── origin # 输出转化得到deepke练习数据到该文件夹
│ ├── relation.csv
│ ├── test.csv
│ ├── train.csv
│ └── valid.csv
└── summary
├── all_sent.txt # 一切的语句
├── annot_entity_sent.txt # 被标记上实体的语句
├── annot_relation_sent.txt # 被标记上联系的语句
├── entities_type_name_dict.json # 标示数据中一切的实体类型,以及归于该类型的一切实体姓名
├── relation.csv # 标示数据中的存在的一切数据
├── unannot_entity_sent.txt # [未被]标记上实体的语句
└── unannot_relation_sent.txt # [未被]标记上联系的语句
4.2. 练习
在练习进程中咱们测验运用了deepke所供给的PCNN, rnn, gcn, capsule, transformer, bert 这些模型,epoch 设置为 50,num_relations
依据咱们数据集的实际状况修改为19,需求注意的是依据BERT的言语模型进行练习时,需求先在相关网页[^14]下载好预练习模型
新的数据集有22种联系(包含None),需求经过 num_relations
来更改
cd deepke-master
python main.py show_plot=False data_path=data/vivrecard/origin out_path=data/vivrecard/out num_relations=22 epoch=50 model=cnn
python main.py show_plot=False data_path=data/vivrecard/origin out_path=data/vivrecard/out num_relations=22 epoch=50 model=rnn
python main.py show_plot=False data_path=data/vivrecard/origin out_path=data/vivrecard/out num_relations=22 epoch=50 model=gcn
python main.py show_plot=False data_path=data/vivrecard/origin out_path=data/vivrecard/out num_relations=22 epoch=50 model=capsule
python main.py show_plot=False data_path=data/vivrecard/origin out_path=data/vivrecard/out num_relations=22 epoch=50 model=transformer
# lm bert layer=1
python main.py show_plot=False data_path=data/vivrecard/origin out_path=data/vivrecard/out num_relations=22 epoch=50 model=lm lm_file=~/ZJU_study/Knowledge_Graph/deepke/pretrained/ num_hidden_layers=1
# lm bert layer=2
python main.py show_plot=False data_path=data/vivrecard/origin out_path=data/vivrecard/out num_relations=22 epoch=50 model=lm lm_file=~/ZJU_study/Knowledge_Graph/deepke/pretrained/ gpu_id=0 num_hidden_layers=2
# lm bert layer=3
python main.py show_plot=False data_path=data/vivrecard/origin out_path=data/vivrecard/out num_relations=22 epoch=50 model=lm lm_file=/home/zenghao/ZJU_study/Knowledge_Graph/deepke/pretrained/ gpu_id=1 num_hidden_layers=3
4.3. 练习成果
PCNN | RNN | GCN | CAPSULE | TRANSFORMER | LM(BERT) LAYER=1 | LM(BERT) LAYER=2 | LM(BERT) LAYER=3 | |
---|---|---|---|---|---|---|---|---|
VALID | 80.11 | 83.87 | 55.91 | 75.27 | 82.26 | 89.79 | 90.86 | 89.78 |
TEST | 86.18 | 85.64 | 63.15 | 82.66 | 86.18 | 91.87 | 91.33 | 92.14 |
可以到依据bert的言语模型作用最好,显着由于其他模型。GCN的作用最差。这也说明在小规模数据上运用预练习的言语模型还是可以抽取到比较好的特征的。
但是在咱们后边关于实际数据的猜测成果发现,言语模型的泛化作用似乎不如PCNN模型的好
咱们猜测是由于咱们的数据存在长尾散布问题,模型可能趋向于猜测某些特定联系来作弊,已达到准确率提高的作用
5. 常识核算
5.1. 图核算
常识图谱的一个很重要的特征便是其的图结构,不同实体之间的结构自身就内含着许多的隐式的信息,可以被进一步的挖掘运用。
在这部分中,咱们参阅他人在类似范畴的实践[^15][^16],运用Neo4j供给的图算法,对咱们构建的实体联系常识图谱,用图算法进行一定的核算剖析,包含核算最短途径、要害结点、结点中心度、社区发现等。
5.1.1. 人物网络剖析
人物数量
万事以简略开端。先看看上图上由有多少人物:
MATCH (c:`ns0__人`) RETURN count(c)
count(c) |
---|
134 |
概要统计
统计每个人物触摸的其它人物的数目:
MATCH (c:`ns0__人`)-[]->(:`ns0__人`)
WITH c, count(*) AS num
RETURN min(num) AS min, max(num) AS max, avg(num) AS avg_characters, stdev(num) AS stdev
min | max | avg_characters | stdev |
---|---|---|---|
1 | 6 | 1.8374999999999997 | 1.1522542572790615 |
图(网络)的直径
网络的直径或许测底线或许最长最短途径:
// Find maximum diameter of network
// maximum shortest path between two nodes
MATCH (a:`ns0__人`), (b:`ns0__人`) WHERE id(a) > id(b)
MATCH p=shortestPath((a)-[*]-(b))
RETURN length(p) AS len, extract(x IN nodes(p) | split(x.uri, 'http://kg.course/talkop-vivre-card/deepke')[-1]) AS path
ORDER BY len DESC LIMIT 4
len | path |
---|---|
10 | [“/人/克拉巴特尔”, “/职务/管家”, “/人/克洛”, “/职务/船长”, “/人/甚平”, “/事情/顶上战役”, “/人/缇娜”, “/事情/国际会议”, “/人/Dr.古蕾娃”, “/人/乔巴”, “/人/Dr.西尔尔克”] |
9 | [“/人/Dr.西尔尔克”, “/人/乔巴”, “/人/Dr.古蕾娃”, “/事情/国际会议”, “/人/伊卡莱姆”, “/安排/草帽一伙”, “/人/库洛卡斯”, “/地址/巨大航路”, “/人/哥尔D罗杰”, “/人/西奇”] |
9 | [“/人/Dr.西尔尔克”, “/人/乔巴”, “/人/Dr.古蕾娃”, “/事情/国际会议”, “/人/缇娜”, “/安排/草帽一伙”, “/人/娜美”, “/安排/恶龙一伙”, “/人/哞哞”, “/人/卡里布”] |
9 | [“/人/克拉巴特尔”, “/职务/管家”, “/人/克洛”, “/职务/船长”, “/人/东利”, “/人/路飞”, “/人/克利克”, “/地址/巨大航路”, “/人/哥尔D罗杰”, “/人/西奇”] |
咱们能看到网络中有许多长度为9的途径。
最短途径
运用Cypher 的shortestPath函数找到图中恣意两个人物之间的最短途径。让咱们找出克洛克达尔和**加尔帝诺(Mr.3)**之间的最短途径:
MATCH p=shortestPath(
(n1)-[*]-(n2)
)
WHERE n1.uri CONTAINS '克洛克达尔' and n2.uri CONTAINS '加尔帝诺'
RETURN p
还可以对途径中的结点进行一些限制,例如途径中不能包含某种类型的结点
MATCH p=shortestPath((n1)-[*]-(n2))
WHERE n1.uri CONTAINS '克洛克达尔' and n2.uri CONTAINS '加尔帝诺' and id(n2) > id(n1) and NONE(n IN nodes(p) WHERE n:`ns0__安排`)
RETURN p
途径中只能包含某种类型的结点
例子:一切从索隆到强尼的1到3跳的途径中,只经过人物结点的途径
MATCH p=(n1)-[*1..3]-(n2)
WHERE n1.uri CONTAINS '索隆' and n2.uri CONTAINS '强尼' and all(x in nodes(p) where 'ns0__人' IN LABELS(x))
RETURN p
一切最短途径
联合斯摩格和一本松之间的最短途径可能还有其它途径,咱们可以运用Cypher的allShortestPaths函数来查找:
MATCH (n1:`ns0__人`), (n2:`ns0__人`) WHERE n1.uri CONTAINS '克洛克达尔' and n2.uri CONTAINS '加尔帝诺' and id(n2) > id(n1)
MATCH p=allShortestPaths((n1)-[*]-(n2))
RETURN p
5.1.2. 要害节点
在网络中,假如一个节点位于其它两个节点一切的最短途径上,即称为要害节点。下面咱们找出网络中一切的要害节点:
// Find all pivotal nodes in network
MATCH (a:`ns0__人`), (b:`ns0__人`) WHERE id(a) > id(b)
MATCH p=allShortestPaths((a)-[*]-(b)) WITH collect(p) AS paths, a, b
MATCH (c:`ns0__人`) WHERE all(x IN paths WHERE c IN nodes(x)) AND NOT c IN [a,b]
RETURN a.uri, b.uri, c.uri AS PivotalNode SKIP 490 LIMIT 10
a.uri | b.uri | PivotalNode |
---|---|---|
“kg.course/talkop-vivr…” | “kg.course/talkop-vivr…” | “kg.course/talkop-vivr…” |
“kg.course/talkop-vivr…” | “kg.course/talkop-vivr…” | “kg.course/talkop-vivr…” |
“kg.course/talkop-vivr…” | “kg.course/talkop-vivr…” | “kg.course/talkop-vivr…” |
“kg.course/talkop-vivr…” | “kg.course/talkop-vivr…” | “kg.course/talkop-vivr…” |
从成果表格中咱们可以看出风趣的成果:娜美和路飞是萨奇斯和诺琪高的要害节点。这意味着,一切联合萨奇斯和诺琪高的最短途径都要经过娜美和路飞。咱们可以经过可视化萨奇斯和诺琪高之间的一切最短途径来验证:
MATCH (n1:`ns0__人`), (n2:`ns0__人`) WHERE n1.uri CONTAINS '萨奇斯' and n2.uri CONTAINS '诺琪高' and id(n1) <> id(n2)
MATCH p=shortestPath((n1)-[*]-(n2))
RETURN p
5.1.3. 节点中心度
节点中心度给出网络中节点的重要性的相对衡量。有许多不同的方法来衡量中心度,每种方法都代表不同类型的“重要性”。
度中心性(Degree Centrality)
度中心性是最简略衡量,即为某个节点在网络中的联合数。在《海贼王》的图中,某个人物的度中心性是指该人物触摸的其他人物数。作者运用Cypher核算度中心性:
MATCH (c:`ns0__人`)-[]-()
RETURN split(c.uri, 'http://kg.course/talkop-vivre-card/deepke')[-1] AS character, count(*) AS degree ORDER BY degree DESC
character | degree |
---|---|
“/人/路飞” | 33 |
“/人/缇娜” | 20 |
“/人/娜美” | 19 |
“/人/山治” | 15 |
从上面可以发现,在《海贼王》网络中路飞和最多的人物有触摸。鉴于他是漫画的主角,咱们觉得这是有道理的。
介数中心性(Betweenness Centrality)
介数中心性:在网络中,一个节点的介数中心性是指其它两个节点的一切最短途径都经过这个节点,则这些一切最短途径数即为此节点的介数中心性。介数中心性是一种重要的衡量,由于它可以鉴别出网络中的“信息中间人”或许网络聚类后的联合点。
图中赤色节点是具有高的介数中心性,网络聚类的联合点。
为了核算介数中心性,需求装置 algo
库
CALL algo.betweenness.stream('ns0__人', 'ns1__遇见',{direction:'both'})
YIELD nodeId, centrality
MATCH (user:`ns0__人`) WHERE id(user) = nodeId
RETURN user.uri AS user,centrality
ORDER BY centrality DESC;
或许
CALL algo.betweenness.stream('ns0__人', null,{direction:'both'})
YIELD nodeId, centrality
MATCH (user:`ns0__人`) WHERE id(user) = nodeId
RETURN user.uri AS user,centrality
ORDER BY centrality DESC;
user | centrality |
---|---|
“kg.course/talkop-vivr…” | 759.0 |
“kg.course/talkop-vivr…” | 335.0 |
“kg.course/talkop-vivr…” | 330.0 |
NOTE:上面的是不考虑方向的,所以设置为 {direction:'both'}
。假如考虑方向,可以
- loading incoming relationships: ‘INCOMING’,’IN’,’I’ or ‘<‘
- loading outgoing relationships: ‘OUTGOING’,’OUT’,’O’ or ‘>’
紧度中心性(Closeness centrality)
紧度中心性是指到网络中一切其他人物的均匀间隔的倒数。在图中,具有高紧度中心性的节点在聚类社区之间被高度联合,但在社区之外纷歧定是高度联合的。
网络中具有高紧度中心性的节点被其它节点高度联合
MATCH (c:`ns0__人`)
WITH collect(c) AS characters
CALL algo.closeness.stream('ns0__人', null)
YIELD nodeId, centrality
RETURN algo.asNode(nodeId).uri AS node, centrality
ORDER BY centrality DESC
LIMIT 20;
node | centrality |
---|---|
“kg.course/talkop-vivr…” | 1.0 |
“kg.course/talkop-vivr…” | 1.0 |
“kg.course/talkop-vivr…” | 1.0 |
5.1.4. 社区发现
CALL algo.beta.louvain.stream(null, null, {
graph: 'huge',
direction: 'BOTH'
}) YIELD nodeId, community, communities
RETURN algo.asNode(nodeId).uri as name, community, communities
ORDER BY community ASC
name | community | communities |
---|---|---|
“kg.course/talkop-vivr…” | 151 | null |
“kg.course/talkop-vivr…” | 151 | null |
“kg.course/talkop-vivr…” | 151 | null |
“kg.course/talkop-vivr…” | 151 | null |
“kg.course/talkop-vivr…” | 151 | null |
“kg.course/talkop-vivr…” | 151 | null |
“kg.course/talkop-vivr…” | 151 | null |
“kg.course/talkop-vivr…” | 151 | null |
“kg.course/talkop-vivr…” | 151 | null |
可以看到,基本把瓦波尔那一系列的community给检测出来了,包含在磁鼓岛和黑暗磁鼓王国
5.1.5. PageRank
CALL algo.pageRank.stream('ns0__人', null, {iterations:20, dampingFactor:0.85})
YIELD nodeId, score
RETURN algo.asNode(nodeId).uri AS page,score
ORDER BY score DESC
page | score |
---|---|
“kg.course/talkop-vivr…” | 2.9112886658942436 |
“kg.course/talkop-vivr…” | 1.4952359730610623 |
“kg.course/talkop-vivr…” | 1.1878799288533628 |
5.2. 常识推理
TODO
6. 常识运用
6.1. 智能问答
在这部分中咱们参阅前人的作业[^17][^18],依据REfO[^19]完结了一个KBQA体系,首要流程为:解析输入的自然言语问句生成 SPARQL 查询,进一步恳求后台依据 TDB 常识库的 Apache Jena Fuseki 服务, 得到成果。代码和数据存放在 vivirecard-KB_query
目录下
6.1.1. 支撑的问题类型
- 关于生日/英文名/血型/星座/霸气/身高的查询
- 谁出生在哪里/出生在某个当地的有谁
6.1.2. 查询示例
运行 python query_main.py
就可以开端进行QA进程
cd vivirecard-KB_query
python query_main.py
直接输入问题,按回车后就会回来答案;当体系中没有对应常识时,会回来 I don't know. :(
;当体系无法理解问题时会回来 I can't understand. :(
-
雷利的身高是多少?
188cm
-
罗杰的血型是啥
S型
-
谁出生在风车村?
蒙其D路飞、玛琪诺、乔路叔&鸡婶、乌普斯拉普
-
出生在可可亚西村的有谁?
娜美、诺琪高、阿健、贝尔梅尔、Dr.纳克、萨姆
-
我想知道斯摩格的生日
3月14日
-
特朗普的生日是多少
I don’t know. :(
-
sasdasdasd
I can’t understand. :(
6.2. 常识图谱可视化
在这部分中,咱们参阅别人的作业[^20],运用D3[^21]对之前构建的实体联系常识图谱供给可视化交互功用,包含结点衔接联系可视化、查询相关结点信息。一起在这部分也整合了之间构建的人物特点常识图谱,供给了信息框的展示进程,相关的数据和代码存放在 visualization
目录下。整个可视化页面的交互进程如下面的[gif图]
可视化网页存放于 visualization/html/index.html
,可以经过 Microsoft Edge 浏览器直接翻开
假如需求在其他浏览器中翻开,可能会加载不出来可视化成果。这是由于跨域恳求在大多数浏览器中是禁止的,恳求不到json数据。因而需求用 WAMP/LAMP/MAMP 装备一个Web网络环境。
翻开后可视化界面如下所示,不同的颜色代表不同类型的实体,具有联系的实体会用白色的细线衔接,可以显着的看到有些实体与其他实体存在很多的衔接
点击左上角的形式切换按钮,咱们可以把结点展示从圆圈形式变换为文本形式,可以进行愈加细致的观察
选中某个结点后,将只会显现该节点以及与其直接相衔接的结点。特别的,假如该节点类型是人物,还会在页面右侧显现该人物的信息框
此外左边还供给了查找框的功用,可以方便咱们查找结点信息
码源下载见文末跳转
码源下载见文末跳转
更多优质内容请关注公号&知乎:汀丶人工智能;会供给一些相关的资源和优质文章,免费获取阅览。