本文正在参加「Python主题月」,详情查看 活动链接
开篇
作为资深海贼迷,硬是刷了几遍动画漫画,很多细节还不如本文要展示的项目强力。本文阿婆主带来海贼王全人物的知识图谱,先感受下:
本项目为开源项目,需要更多细节可以在文末找到地址。让我们一起见证下python高手是怎么练成的吧。
注:
- 版本要求python 3.6+
- 本文有诸多资源地址,想做知识库的可以好好参考下思路
本文你可以得到
- 知识图谱的设计逻辑
- 如果通过各种渠道的有效耦合组成预期的知识图谱
- 相信你可以举一反三写个《火影忍者》,或其他你喜欢的动漫都知识图谱
海贼王简介
《航海王》是日本漫画家尾田荣一郎作画的少年漫画作品,于1997年7月22日在集英社《周刊少年Jump》开始连载。改编的电视动画《航海王》于1999年10月20日起在富士电视台首播。
2012年5月11日,《航海王》获得第41回日本漫画家协会赏。
本作被吉尼斯世界纪录官方认证为“世界上发行量最高的单一作者创作的系列漫画”。2017年7月21日,日本纪念日协会通过认证,将每年的7月22日设立为“ONE PIECE纪念日”。
项目全貌
有点长,可以点击目录跳过本部分,有需要的小伙伴可以看看全貌
|--visualization
| |--html
| | |--index.html
| | |--test_vizdata_vivrecard_relation.json
| | |--alignment_vizdata_vivrecard_relation.json
| | |--vizdata_vivrecard_relation.json
| | |--vizdata_vivrecard_avpair.json
|--vivirecard-KB_query
| |--question_temp.py
| |--query_main.py
| |--test_sparql.py
| |--jena_sparql_endpoint.py
| |--external_dict
| | |--csv2txt.py
| | |--__init__.py
| | |--vivre_zhpname.csv
| | |--person_name.txt
| | |--movie_title.csv
| | |--onepiece_hierarchy_place_terminology.txt
| | |--movie_title.txt
| | |--vivire_ntriples2zhpname.py
| | |--person_name.csv
| | |--vivre_zhpname.txt
| | |--onepiece_place_terminology.txt
| |--data
| | |--talkop_vivre_card
| | | |--14-(201809初始套装+1张追加卡)-entities_avpair.json
| | | |--11-(201906水之都CP9+德岛竞技场)-predicate_key_list.txt
| | | |--12-(201903初始套装Vol2-16张主卡)-entities_avpair.json
| | | |--preprocessed-5-(201902空岛住民+新鱼人海贼团).txt
| | | |--13-(201811可可亚西村+大监狱)-entities_id_name_list.txt
| | | |--preprocessed-8-(201905水之都+德岛).txt
| | | |--file_prefix.json
| | | |--preprocessed-4-(201908杰尔马66+大妈团).txt
| | | |--skill.txt
| | | |--7-(201904空岛+PH岛)-entities_id_name_list.txt
| | | |--6-(201907恐怖船+象岛)-entities_avpair.json
| | | |--8-(201905水之都+德岛)-predicate_key_list.txt
| | | |--13-(201811可可亚西村+大监狱).txt
| | | |--13-(201811可可亚西村+大监狱)-predicate_key_list.txt
| | | |--9-(201812阿拉巴斯坦+白胡子海贼团)-entities_avpair.json
| | | |--preprocessed-7-(201904空岛+PH岛).txt
| | | |--9-(201812阿拉巴斯坦+白胡子海贼团)-entities_id_name_list.txt
| | | |--9-(201812阿拉巴斯坦+白胡子海贼团)-predicate_key_list.txt
| | | |--preprocessed-10-(201901鱼人岛居民+巴洛克社).txt
| | | |--preprocessed-6-(201907恐怖船+象岛).txt
| | | |--6-(201907恐怖船+象岛)-entities_id_name_list.txt
| | | |--preprocessed-12-(201903初始套装Vol2-16张主卡).txt
| | | |--summary_predicate_set.txt
| | | |--4-(201908杰尔马66+大妈团)-entities_id_name_list.txt
| | | |--14-(201809初始套装+1张追加卡)-entities_id_name_list.txt
| | | |--14-(201809初始套装+1张追加卡).txt
| | | |--ntriples_talkop_vivre_card.nt
| | | |--9-(201812阿拉巴斯坦+白胡子海贼团).txt
| | | |--3-(201810东海的猛者们+超新星集结)-predicate_key_list.txt
| | | |--8-(201905水之都+德岛).txt
| | | |--5-(201902空岛住民+新鱼人海贼团).txt
| | | |--6-(201907恐怖船+象岛)-predicate_key_list.txt
| | | |--11-(201906水之都CP9+德岛竞技场)-entities_id_name_list.txt
| | | |--10-(201901鱼人岛居民+巴洛克社)-entities_id_name_list.txt
| | | |--12-(201903初始套装Vol2-16张主卡).txt
| | | |--4-(201908杰尔马66+大妈团)-entities_avpair.json
| | | |--8-(201905水之都+德岛)-entities_id_name_list.txt
| | | |--7-(201904空岛+PH岛)-entities_avpair.json
| | | |--5-(201902空岛住民+新鱼人海贼团)-predicate_key_list.txt
| | | |--8-(201905水之都+德岛)-entities_avpair.json
| | | |--summary_entities_id_name_list.txt
| | | |--3-(201810东海的猛者们+超新星集结)-entities_avpair.json
| | | |--5-(201902空岛住民+新鱼人海贼团)-entities_id_name_list.txt
| | | |--10-(201901鱼人岛居民+巴洛克社)-predicate_key_list.txt
| | | |--preprocessed-13-(201811可可亚西村+大监狱).txt
| | | |--4-(201908杰尔马66+大妈团)-predicate_key_list.txt
| | | |--preprocessed-9-(201812阿拉巴斯坦+白胡子海贼团).txt
| | | |--4-(201908杰尔马66+大妈团).txt
| | | |--3-(201810东海的猛者们+超新星集结)-entities_id_name_list.txt
| | | |--11-(201906水之都CP9+德岛竞技场)-entities_avpair.json
| | | |--7-(201904空岛+PH岛).txt
| | | |--preprocessed-11-(201906水之都CP9+德岛竞技场).txt
| | | |--3-(201810东海的猛者们+超新星集结).txt
| | | |--preprocessed-14-(201809初始套装+1张追加卡).txt
| | | |--5-(201902空岛住民+新鱼人海贼团)-entities_avpair.json
| | | |--10-(201901鱼人岛居民+巴洛克社)-entities_avpair.json
| | | |--12-(201903初始套装Vol2-16张主卡)-entities_id_name_list.txt
| | | |--14-(201809初始套装+1张追加卡)-predicate_key_list.txt
| | | |--6-(201907恐怖船+象岛).txt
| | | |--11-(201906水之都CP9+德岛竞技场).txt
| | | |--12-(201903初始套装Vol2-16张主卡)-predicate_key_list.txt
| | | |--7-(201904空岛+PH岛)-predicate_key_list.txt
| | | |--13-(201811可可亚西村+大监狱)-entities_avpair.json
| | | |--10-(201901鱼人岛居民+巴洛克社).txt
| |--question2sparql.py
| |--word_tagging.py
|--LICENSE.md
|--cndbpedia
| |--filter_moelgirl_cndbpedia_entities_mapping_file.py
| |--get_onepiece_cndbpedia_avpair.py
| |--avpair2ntriples_onepiece_cndbpedia.py
| |--get_onepiece_cndbpedia_entities.py
| |--parse_raw_moegirl_onepiece_entries.py
| |--data
| | |--moelgirl_cndbpedia_entities_mapping.json
| | |--processed_moegirl_onepiece_entries.txt
| | |--query_avpair_entities_list.txt
| | |--raw_moegirl_onepiece_entries.txt
| | |--cndbpedia_onepiece_entities_list.txt
| | |--query_avpair_cndbpedia_onepiece_results.json
| | |--query_avpair_entities_mapping.json
| | |--query_avpair_keys_list_file.txt
| | |--moelgirl_cndbpedia_api_no_results_mention_name_list.txt
| | |--filter_out_entities_mapping.json
| | |--ntriples_cndbpedia_onepiece.nt
|--index.html
|--deepke-master
| |--metrics.py
| |--vocab.py
| |--LICENSE
| |--requirements.txt
| |--test
| | |--test_cnn.py
| | |--test_serializer.py
| | |--test_embedding.py
| | |--test_attention.py
| | |--test_rnn.py
| | |--test_vocab.py
| | |--test_transformer.py
| |--preprocess.py
| |--images
| | |--APCNN.jpg
| | |--Capsule.png
| | |--Bert.png
| | |--CNN.png
| | |--GCN.png
| | |--Transformer2.png
| | |--LSTM.jpg
| | |--Transformer1.png
| | |--PCNN.jpg
| |--module
| | |--Attention.py
| | |--GCN.py
| | |--Capsule.py
| | |--Embedding.py
| | |--__init__.py
| | |--__pycache__
| | | |--Embedding.cpython-37.pyc
| | | |--GCN.cpython-37.pyc
| | | |--Transformer.cpython-37.pyc
| | | |--Capsule.cpython-37.pyc
| | | |--RNN.cpython-37.pyc
| | | |--Attention.cpython-37.pyc
| | | |--CNN.cpython-37.pyc
| | | |--__init__.cpython-37.pyc
| | |--CNN.py
| | |--Transformer.py
| | |--RNN.py
| |--predict.py
| |--utils
| | |--discoveralign_related_entity.py
| | |--convert_vivrecard2deepke.py
| | |--__init__.py
| | |--__pycache__
| | | |--nnUtils.cpython-37.pyc
| | | |--ioUtils.cpython-37.pyc
| | | |--__init__.cpython-37.pyc
| | |--get_vivrecard_rawdata.py
| | |--nnUtils.py
| | |--convert_baiduke2deepke.py
| | |--check_data.py
| | |--ioUtils.py
| |--models
| | |--PCNN.py
| | |--GCN.py
| | |--Capsule.py
| | |--BasicModule.py
| | |--__init__.py
| | |--__pycache__
| | | |--GCN.cpython-37.pyc
| | | |--Transformer.cpython-37.pyc
| | | |--LM.cpython-37.pyc
| | | |--BiLSTM.cpython-37.pyc
| | | |--Capsule.cpython-37.pyc
| | | |--PCNN.cpython-37.pyc
| | | |--BasicModule.cpython-37.pyc
| | | |--__init__.cpython-37.pyc
| | |--Transformer.py
| | |--LM.py
| | |--BiLSTM.py
| |--__pycache__
| | |--preprocess.cpython-37.pyc
| | |--dataset.cpython-37.pyc
| | |--serializer.cpython-37.pyc
| | |--metrics.cpython-37.pyc
| | |--vocab.cpython-37.pyc
| | |--trainer.cpython-37.pyc
| |--README.md
| |--dataset.py
| |--.gitignore
| |--.github
| | |--CODE_OF_CONDUCT.md
| | |--CONTRIBUTING.md
| | |--ISSUE_TEMPLATE
| | | |--feature_request.md
| | | |--bug_report.md
| | | |--question_consult.md
| |--serializer.py
| |--trainer.py
| |--main.py
| |--tutorial-notebooks
| | |--GCN.ipynb
| | |--PCNN.ipynb
| | |--img
| | | |--Bert.png
| | | |--GCN.png
| | | |--PCNN.jpg
| | |--LM.ipynb
| | |--data
| | | |--valid.csv
| | | |--test.csv
| | | |--train.csv
| | | |--relation.csv
| |--data
| | |--vivrecard
| | | |--alignment
| | | | |--json_entity_mapping.json
| | | | |--alignment_vizdata_vivrecard_relation.json
| | | | |--raw_entity_mapping.txt
| | | |--origin
| | | | |--valid.csv
| | | | |--test.csv
| | | | |--train.csv
| | | | |--relation.csv
| | | |--annot
| | | | |--fuseki_vivrecard_sentence_item.txt
| | | | |--outputs
| | | | | |--fuseki_vivrecard_sentence_item.ann
| | | | | |--fuseki_vivrecard_sentence_item.json
| | | | | |--formatted_fuseki_vivrecard_sentence_item.json
| | | |--raw
| | | | |--fuseki_vivrecard_sentence_dict.json
| | | | |--fuseki_vivrecard_sentence_item.txt
| | | | |--fuseki_vivrecard.csv
| | | |--summary
| | | | |--annot_relation_sent.txt
| | | | |--entities_type_name_dict.json
| | | | |--unannot_relation_sent.txt
| | | | |--all_sent.txt
| | | | |--vizdata_vivrecard_relation.json
| | | | |--vivrecard_ntriples.nt
| | | | |--unannot_entity_sent.txt
| | | | |--relation.csv
| | | | |--annot_entity_sent.txt
| |--conf
| | |--embedding.yaml
| | |--config.yaml
| | |--train.yaml
| | |--model
| | | |--lm.yaml
| | | |--cnn.yaml
| | | |--transformer.yaml
| | | |--capsule.yaml
| | | |--rnn.yaml
| | | |--gcn.yaml
| | |--preprocess.yaml
| | |--hydra
| | | |--output
| | | | |--custom.yaml
| |--pretrained
| | |--readme.md
|--docs
| |--CHANGELOG.md
| |--images
| | |--graph (3).png
| | |--graph (2).png
| | |--soogif-5m.gif
| | |--graph.png
| | |--graph (1).png
| | |--relation-freq.png
| | |--viz1.jpg
| | |--viz3.jpg
| | |--viz2.jpg
| |--report.md
| |--report.pdf
|--README.md
|--talkop
| |--parse_vivire_card_webpage.py
| |--preprocess_vivre_card
| | |--preprocess_8_vivre_card.py
| | |--preprocess_EX_CHARACTERS.py
| | |--preprocess_12_vivre_card.py
| | |--preprocess_5_vivre_card.py
| | |--preprocess_11_vivre_card.py
| | |--preprocess_6_vivre_card.py
| | |--preprocess_14_vivre_card.py
| | |--preprocess_7_vivre_card.py
| | |--preprocess_10_vivre_card.py
| | |--preprocess_4_vivre_card.py
| | |--preprocess_13_vivre_card.py
| | |--preprocess_9_vivre_card.py
| |--parse_vivire_card_catalog.py
| |--summary_talkop_vivre_card.py
| |--parse_processed_manual_talkop_vivre_card.py
| |--data
| | |--original_manual_talkop_vivre_card
| | | |--13-(201811可可亚西村+大监狱).txt
| | | |--14-(201809初始套装+1张追加卡).txt
| | | |--9-(201812阿拉巴斯坦+白胡子海贼团).txt
| | | |--8-(201905水之都+德岛).txt
| | | |--5-(201902空岛住民+新鱼人海贼团).txt
| | | |--12-(201903初始套装Vol2-16张主卡).txt
| | | |--4-(201908杰尔马66+大妈团).txt
| | | |--7-(201904空岛+PH岛).txt
| | | |--3-(201810东海的猛者们+超新星集结).txt
| | | |--6-(201907恐怖船+象岛).txt
| | | |--11-(201906水之都CP9+德岛竞技场).txt
| | | |--10-(201901鱼人岛居民+巴洛克社).txt
| | |--talkop_vivre_card_webpage
| | | |--talkop_vivire_card_catalog.json
| | | |--8-【TalkOP汉化】海贼王资料集生命卡ONEPIECE图鉴全图翻译(201905水之都+德岛)
| | | | |--8-【TalkOP汉化】海贼王资料集生命卡ONEPIECE图鉴全图翻译(201905水之都+德岛).html
| | | |--13-【TalkOP汉化】海贼王资料集生命卡ONEPIECE图鉴全图翻译(201811可可亚西村+大监狱)
| | | | |--13-【TalkOP汉化】海贼王资料集生命卡ONEPIECE图鉴全图翻译(201811可可亚西村+大监狱).html
| | | |--9-【TalkOP汉化】海贼王资料集生命卡ONEPIECE图鉴全图翻译(201812阿拉巴斯坦+白胡子海贼团)
| | | | |--9-【TalkOP汉化】海贼王资料集生命卡ONEPIECE图鉴全图翻译(201812阿拉巴斯坦+白胡子海贼团).html
| | | |--3-【TalkOP汉化】海贼王资料集生命卡ONEPIECE图鉴全图翻译(201810东海的猛者们+超新星集结)
| | | | |--3-【TalkOP汉化】海贼王资料集生命卡ONEPIECE图鉴全图翻译(201810东海的猛者们+超新星集结).txt
| | | | |--3-【TalkOP汉化】海贼王资料集生命卡ONEPIECE图鉴全图翻译(201810东海的猛者们+超新星集结).html
| | | |--4-【TalkOP汉化】海贼王资料集生命卡ONEPIECE图鉴全图翻译(201908杰尔马66+大妈团)
| | | | |--4-【TalkOP汉化】海贼王资料集生命卡ONEPIECE图鉴全图翻译(201908杰尔马66+大妈团).html
| | | | |--4-【TalkOP汉化】海贼王资料集生命卡ONEPIECE图鉴全图翻译(201908杰尔马66+大妈团)_files
| | | | | |--zhounianqing1.gif
| | | | | |--avatar(5).php
| | | | | |--2018new_zuohengheng_thumb.png
| | | | | |--userinfo.gif
| | | | | |--sleepy.gif
| | | | | |--thread-prev.png
| | | | | |--2018new_taikaixin_org.png
| | | | | |--avatar(14).php
| | | | | |--share.js.下载
| | | | | |--upload.js.下载
| | | | | |--2018new_kuxiao_thumb.png
| | | | | |--shutup.gif
| | | | | |--avatar(9).php
| | | | | |--avatar(22).php
| | | | | |--2018new_yinxian_org.png
| | | | | |--2018new_xixi_thumb.png
| | | | | |--kiss.gif
| | | | | |--namepost.small.gif
| | | | | |--TB1_3FrKVXXXXbdXXXXXXXXXXXX-129-128.png
| | | | | |--avatar(18).php
| | | | | |--nc.js.下载
| | | | | |--jquery-1.8.3.min.js.下载
| | | | | |--caomao.gif
| | | | | |--slide_share.css
| | | | | |--avatar(19).php
| | | | | |--handshake.gif
| | | | | |--avatar(23).php
| | | | | |--shangfangbaojian.gif
| | | | | |--avatar(8).php
| | | | | |--qq.gif
| | | | | |--thread-next.png
| | | | | |--2018new_xiaoku_thumb.png
| | | | | |--2018new_xiaoerbuyu_org.png
| | | | | |--f(2).txt
| | | | | |--avatar(15).php
| | | | | |--call.gif
| | | | | |--bump.small.gif
| | | | | |--avatar(4).php
| | | | | |--shocked.gif
| | | | | |--avatar(24).php
| | | | | |--none.gif
| | | | | |--putong.png
| | | | | |--pn_post.png
| | | | | |--faq.gif
| | | | | |--at.js.下载
| | | | | |--avatar(3).php
| | | | | |--hot_2.gif
| | | | | |--024515qk9jvria44ysd322.png
| | | | | |--wenshen.gif
| | | | | |--avatar(12).php
| | | | | |--meilihao.gif
| | | | | |--fav.gif
| | | | | |--2018new_leimu_org.png
| | | | | |--094711mzmnonn42d200dmv.gif
| | | | | |--rec_add.gif
| | | | | |--home.php
| | | | | |--avatar(13).php
| | | | | |--titter.gif
| | | | | |--smilies.js.下载
| | | | | |--star_level1.gif
| | | | | |--2018new_xinsui_thumb.png
| | | | | |--avatar(2).php
| | | | | |--smile.gif
| | | | | |--oshr.png
| | | | | |--2018new_ku_org.png
| | | | | |--star_level3.gif
| | | | | |--saved_resource(1).html
| | | | | |--oculus.css
| | | | | |--avatar(25).php
| | | | | |--style_14_widthauto.css
| | | | | |--star_level2.gif
| | | | | |--10.png
| | | | | |--biggrin.gif
| | | | | |--qq_big.gif
| | | | | |--2018new_doge02_org.png
| | | | | |--guanliyuan.png
| | | | | |--kx.png
| | | | | |--checkonline.small.gif
| | | | | |--print.png
| | | | | |--fengche.gif
| | | | | |--avatar.php
| | | | | |--2018new_shuai_thumb.png
| | | | | |--2018new_jiyan_org.png
| | | | | |--common_smilies_var.js.下载
| | | | | |--shaoshao.gif
| | | | | |--logo3.png
| | | | | |--hug.gif
| | | | | |--nc.css
| | | | | |--tongue.gif
| | | | | |--avatar(10).php
| | | | | |--funk.gif
| | | | | |--lol.gif
| | | | | |--xiong.gif
| | | | | |--2018new_zuoyi_org.png
| | | | | |--dizzy.gif
| | | | | |--forum_viewthread.js.下载
| | | | | |--zrt_lookup.html
| | | | | |--avatar(1).php
| | | | | |--hm.js.下载
| | | | | |--seditor.js.下载
| | | | | |--avatar(11).php
| | | | | |--2018new_ye_thumb.png
| | | | | |--kele.gif
| | | | | |--ajax.js.下载
| | | | | |--fj_btn.png
| | | | | |--style.css
| | | | | |--sad.gif
| | | | | |--cry.gif
| | | | | |--f.txt
| | | | | |--yinghua.gif
| | | | | |--sweat.gif
| | | | | |--loveliness.gif
| | | | | |--2018new_chongjing_org.png
| | | | | |--style_14_forum_viewthread.css
| | | | | |--2018new_wu_thumb.png
| | | | | |--victory.gif
| | | | | |--f(1).txt
| | | | | |--collection.png
| | | | | |--qq_share.png
| | | | | |--avatar(16).php
| | | | | |--2018new_guolai_thumb.png
| | | | | |--2018new_touxiao_org.png
| | | | | |--colorroger2018 .gif
| | | | | |--2018new_ruo_thumb.png
| | | | | |--pn_reply.png
| | | | | |--2018new_nu_thumb.png
| | | | | |--avatar(7).php
| | | | | |--curse.gif
| | | | | |--forum.js.下载
| | | | | |--shy.gif
| | | | | |--2018new_good_thumb.png
| | | | | |--2018new_ok_org.png
| | | | | |--huffy.gif
| | | | | |--avatar(20).php
| | | | | |--nu.png
| | | | | |--rec_subtract.gif
| | | | | |--mad.gif
| | | | | |--common.js.下载
| | | | | |--12344279923_utf8.js.下载
| | | | | |--2.jpg
| | | | | |--saved_resource.html
| | | | | |--avatar(21).php
| | | | | |--forumlink.gif
| | | | | |--font_992399_xgto9646zx.css
| | | | | |--oculus_nc.js.下载
| | | | | |--style_14_common.css
| | | | | |--ng.png
| | | | | |--3.jpg
| | | | | |--avatar(6).php
| | | | | |--colorroger2019.gif
| | | | | |--2018new_tianping_thumb.png
| | | | | |--avatar(17).php
| | | | | |--html5notification.js.下载
| | | | | |--ym.png
| | | | | |--arw_r.gif
| | | |--14-【TalkOP汉化】海贼王资料集生命卡ONEPIECE图鉴全图翻译(201809初始套装+1张追加卡)
| | | | |--14-【TalkOP汉化】海贼王资料集生命卡ONEPIECE图鉴全图翻译(201809初始套装+1张追加卡).html
| | | |--5-【TalkOP汉化】海贼王资料集生命卡ONEPIECE图鉴全图翻译(201902空岛住民+新鱼人海贼团)
| | | | |--5-【TalkOP汉化】海贼王资料集生命卡ONEPIECE图鉴全图翻译(201902空岛住民+新鱼人海贼团).html
| | | |--6-【TalkOP汉化】海贼王资料集生命卡ONEPIECE图鉴全图翻译(201907恐怖船+象岛)
| | | | |--6-【TalkOP汉化】海贼王资料集生命卡ONEPIECE图鉴全图翻译(201907恐怖船+象岛).html
| | | |--talkop_vivire_card_catalog.html
| | | |--2-【TalkOP汉化】海贼王资料集生命卡ONEPIECE图鉴完全版汉化(201810东海+超新星篇)
| | | | |--2-【TalkOP汉化】海贼王资料集生命卡ONEPIECE图鉴完全版汉化(201810东海+超新星篇).html
| | | |--7-【TalkOP汉化】海贼王资料集生命卡ONEPIECE图鉴全图翻译(201904空岛+PH岛)
| | | | |--7-【TalkOP汉化】海贼王资料集生命卡ONEPIECE图鉴全图翻译(201904空岛+PH岛).html
| | |--processed_manual_talkop_vivre_card
| | | |--14-(201809初始套装+1张追加卡)-entities_avpair.json
| | | |--11-(201906水之都CP9+德岛竞技场)-predicate_key_list.txt
| | | |--12-(201903初始套装Vol2-16张主卡)-entities_avpair.json
| | | |--preprocessed-5-(201902空岛住民+新鱼人海贼团).txt
| | | |--13-(201811可可亚西村+大监狱)-entities_id_name_list.txt
| | | |--preprocessed-8-(201905水之都+德岛).txt
| | | |--file_prefix.json
| | | |--preprocessed-4-(201908杰尔马66+大妈团).txt
| | | |--skill.txt
| | | |--7-(201904空岛+PH岛)-entities_id_name_list.txt
| | | |--6-(201907恐怖船+象岛)-entities_avpair.json
| | | |--8-(201905水之都+德岛)-predicate_key_list.txt
| | | |--13-(201811可可亚西村+大监狱).txt
| | | |--13-(201811可可亚西村+大监狱)-predicate_key_list.txt
| | | |--9-(201812阿拉巴斯坦+白胡子海贼团)-entities_avpair.json
| | | |--preprocessed-7-(201904空岛+PH岛).txt
| | | |--9-(201812阿拉巴斯坦+白胡子海贼团)-entities_id_name_list.txt
| | | |--9-(201812阿拉巴斯坦+白胡子海贼团)-predicate_key_list.txt
| | | |--preprocessed-10-(201901鱼人岛居民+巴洛克社).txt
| | | |--preprocessed-6-(201907恐怖船+象岛).txt
| | | |--6-(201907恐怖船+象岛)-entities_id_name_list.txt
| | | |--preprocessed-12-(201903初始套装Vol2-16张主卡).txt
| | | |--summary_predicate_set.txt
| | | |--4-(201908杰尔马66+大妈团)-entities_id_name_list.txt
| | | |--14-(201809初始套装+1张追加卡)-entities_id_name_list.txt
| | | |--14-(201809初始套装+1张追加卡).txt
| | | |--ntriples_talkop_vivre_card.nt
| | | |--9-(201812阿拉巴斯坦+白胡子海贼团).txt
| | | |--3-(201810东海的猛者们+超新星集结)-predicate_key_list.txt
| | | |--8-(201905水之都+德岛).txt
| | | |--5-(201902空岛住民+新鱼人海贼团).txt
| | | |--6-(201907恐怖船+象岛)-predicate_key_list.txt
| | | |--11-(201906水之都CP9+德岛竞技场)-entities_id_name_list.txt
| | | |--10-(201901鱼人岛居民+巴洛克社)-entities_id_name_list.txt
| | | |--12-(201903初始套装Vol2-16张主卡).txt
| | | |--4-(201908杰尔马66+大妈团)-entities_avpair.json
| | | |--8-(201905水之都+德岛)-entities_id_name_list.txt
| | | |--7-(201904空岛+PH岛)-entities_avpair.json
| | | |--5-(201902空岛住民+新鱼人海贼团)-predicate_key_list.txt
| | | |--8-(201905水之都+德岛)-entities_avpair.json
| | | |--summary_entities_id_name_list.txt
| | | |--3-(201810东海的猛者们+超新星集结)-entities_avpair.json
| | | |--5-(201902空岛住民+新鱼人海贼团)-entities_id_name_list.txt
| | | |--10-(201901鱼人岛居民+巴洛克社)-predicate_key_list.txt
| | | |--preprocessed-13-(201811可可亚西村+大监狱).txt
| | | |--4-(201908杰尔马66+大妈团)-predicate_key_list.txt
| | | |--preprocessed-9-(201812阿拉巴斯坦+白胡子海贼团).txt
| | | |--vizdata_vivrecard_avpair.json
| | | |--4-(201908杰尔马66+大妈团).txt
| | | |--3-(201810东海的猛者们+超新星集结)-entities_id_name_list.txt
| | | |--11-(201906水之都CP9+德岛竞技场)-entities_avpair.json
| | | |--7-(201904空岛+PH岛).txt
| | | |--preprocessed-11-(201906水之都CP9+德岛竞技场).txt
| | | |--3-(201810东海的猛者们+超新星集结).txt
| | | |--preprocessed-14-(201809初始套装+1张追加卡).txt
| | | |--5-(201902空岛住民+新鱼人海贼团)-entities_avpair.json
| | | |--10-(201901鱼人岛居民+巴洛克社)-entities_avpair.json
| | | |--12-(201903初始套装Vol2-16张主卡)-entities_id_name_list.txt
| | | |--14-(201809初始套装+1张追加卡)-predicate_key_list.txt
| | | |--6-(201907恐怖船+象岛).txt
| | | |--11-(201906水之都CP9+德岛竞技场).txt
| | | |--12-(201903初始套装Vol2-16张主卡)-predicate_key_list.txt
| | | |--7-(201904空岛+PH岛)-predicate_key_list.txt
| | | |--13-(201811可可亚西村+大监狱)-entities_avpair.json
| | | |--10-(201901鱼人岛居民+巴洛克社).txt
| |--avpair2ntriples_talkop_vivre_card.py
|--.gitignore
|--.gitattributes
复制代码
项目介绍
ONEPICE-KG 是一个面向《海贼王》领域数据的知识图谱项目。
本项目内容包括数据采集、知识存储、知识抽取、知识计算、知识应用五大部分
-
数据采集
本次项目主要采集构建了两个知识图谱和一个关系抽取数据集
- 人物知识图谱:主要包含各个人物的信息
- 关系抽取数据集:标注出自然语言中存在的实体以及他们之间的关系
- 实体关系知识图谱:构建《海贼王》中各个实体之间关系的知识图谱
-
知识存储
尝试使用了三元组数据库Apace Jena和原生图数据库Neo4j,并分别使用RDF结构化查询语言SPARQL和属性图查询语言Cypher,在知识图谱上进行查询。
-
知识抽取
基于之间构建的关系抽取数据集,利用deepke中提供的工具进行关系抽取实践,测试了包括PCNN、GCN、BERT等模型在我们构建数据集上的效果
-
知识计算
- 图计算:在Neo4j上对实体关系知识图谱进行了图挖掘,包括最短路径查询、权威结点发现、社区发现等
- 知识推理:在Apache Jena上对关系知识图谱进行了知识推理,补全了一部分的数据
-
知识应用
- 智能问答:基于REfO实现一个对于《海贼王》中人物的知识库问答系统(KBQA)。
- 可视化图片:通过D3对实体关系图片进行可视化,并整合了人物知识图谱中的信息,进行展示。
目录树,内有注释,解释作用
|--visualization # 知识图谱可视化
| |--html
|--vivirecard-KB_query # 智能问答
| |--external_dict
| |--data
| | |--talkop_vivre_card
|--cndbpedia # 原始的半结构化词条数据
| |--data
|--deepke-master # 基于 Pytorch 的深度学习中文关系抽取处理套件
| |--test
| |--images
| |--module
| | |--__pycache__
| |--utils
| | |--__pycache__
| |--models
| | |--__pycache__
| |--__pycache__
| |--.github
| | |--ISSUE_TEMPLATE
| |--tutorial-notebooks
| | |--img
| | |--data
| |--data
| | |--vivrecard
| | | |--alignment
| | | |--origin
| | | |--annot
| | | | |--outputs
| | | |--raw
| | | |--summary
| |--conf
| | |--model
| | |--hydra
| | | |--output
| |--pretrained
|--docs # 文档
| |--images
|--talkop # talkop论坛采集半结构化的知识
| |--preprocess_vivre_card
| |--data
| | |--original_manual_talkop_vivre_card
| | |--talkop_vivre_card_webpage
| | |--processed_manual_talkop_vivre_card
复制代码
1. 数据采集
1.1. 数据采集来源
数据主要来源为两个:
- 从别的知识图谱中获取已经存在的知识信息
- 从相关网页中爬取解析半结构化的自然语言文本信息
人物知识图谱的抽取用的是CN-DBpedia,由复旦大学知识工场实验室研发、维护的大规模通用领域结构化百科知识,作为通用知识图谱来源
1.2. 人物知识图谱构建
1.2.1.构建实体(人名/地名等)词汇库
抓取萌娘百科粉丝列出的人名/地名等,直接用其源代码,放在cndbpedia/data/raw_moegirl_onepiece_entries.txt
|group1= 草帽海贼团
|list1 = [[路飞娘|蒙奇·D·路飞]] • <!--
-->[[罗罗诺亚·索隆]] • <!--
-->[[娜美(海贼王)|娜美]] • <!--
-->[[烏索普]] • <!--
-->[[山治]] • <!--
-->[[托尼托尼·乔巴]] • <!--
-->[[妮可·罗宾]] • <!--
-->[[弗兰奇]] • <!--
-->[[布鲁克]]
|group2 = 王下七武海
|list2 = {{Navbox subgroup
|groupstyle = background:#00FFFF;
|group1 = 现任
|list1 = [[乔拉可尔·米霍克]] • <!--
-->[[巴索罗米·熊]] • <!--
-->[[波雅·汉库克]] • <!--
-->[[巴基]] • <!--
-->[[爱德华·威布尔]]
……
复制代码
解析命令:
python cndbpedia/parse_raw_moegirl_onepiece_entries.py
复制代码
结果输出到:cndbpedia/data/processed_moegirl_onepiece_entries.txt
,共509
个词条名
Baby-5
G1支部
G8要塞
Miss.双手指
Miss.情人节
Miss.星期一
Miss.星期五
Miss.父亲节
Miss.黄金周
Mr.11
Mr.13
Mr.4
Mr.5
Mr.7
Mr.9
T彭恩
X·德雷克
七水之都
三角海流
世界政府
东利
东吉特
……
复制代码
1.2.2.获取实体(人名/地名等)列表
利用知识工厂提供的API,
举个栗子:
shuyantech.com/api/cndbped…
{
"status": "ok",
"ret": [
"蒙奇·d·路飞(日本漫画《航海王》中的男主角)",
"蒙奇·d·路飞(日本漫画《航海王》的角色)",
"蒙奇·d·路飞",
"蒙奇·d·路飞(《海贼无双》系列的角色)",
"蒙奇·d·路飞(动作类游戏《海贼无双》系列的角色)"
]
}
复制代码
写个脚本把构建实体(人名/地名等)词汇库采集的人名列表全部跑一遍:
python cndbpedia/get_onepiece_cndbpedia_entities.py
复制代码
总共获取了1014个不同的实体名,结果保存在 cndbpedia/data
文件夹
cndbpedia_onepiece_entities_list.txt
:保存了所有识别出的人名,毕竟有些名字找不到,例如:
爱德华·纽盖特(《航海王燃烧意志》游戏角色)
爱德华·纽盖特(日本漫画《海贼王》中的角色)
爱莎(《弑神者!》中的弑神者之一)
爱莎(《海贼王》中的角色)
爱莎(艾尔之光游戏人物)
复制代码
moelgirl_cndbpedia_entities_mapping.json
:保存类似:
"爱德华·纽盖特": [
"爱德华·纽盖特",
"爱德华·纽盖特(日本漫画《海贼王》中的角色)",
"爱德华·纽盖特(《航海王燃烧意志》游戏角色)"
],
"爱莎": [
"千田爱莎",
"爱莎(《海贼王》中的角色)",
"爱莎(艾尔之光游戏人物)",
"爱莎(《弑神者!》中的弑神者之一)"
],
复制代码
1.2.3.筛选实体(人名/地名等)列表
名字都会重名的,类似的:
{
"status": "ok",
"ret": [
"凯莉·布鲁克",
"布鲁克(西班牙2010年拍摄电影)",
"布鲁克(奥地利城市穆尔河畔布鲁克缩写)",
"布鲁克(广告策划师)",
"布鲁克(游戏《赛尔号》中的精灵)",
"布鲁克(温力铭演唱歌曲)",
"布鲁克(日本动漫《海贼王》中的人物)",
"布鲁克"
]
}
复制代码
这么多布鲁克,我们只要海贼王的数据,预设包含海贼王,航海王,海贼,航海,onepiece,one piece,动漫,漫画
才是我们要的目标数据
python cndbpedia/filter_moelgirl_cndbpedia_entities_mapping_file.py
复制代码
同样保存在cndbpedia/data
文件夹
筛选结果:在509
个词条中有162
个词条没有对应的实体名,这些词条被保存在 moelgirl_cndbpedia_api_no_results_mention_name_list.txt
;
如:shuyantech.com/api/cndbped… 即为没对应的实体名
{
"status": "ok",
"ret": []
}
复制代码
- 有11个词条虽然有实体名,但不符合我们的预设
filter_out_entities_mapping.json
{
"status": "ok",
"ret": [
"玛丽亚·卡拉斯",
"卡拉斯(美籍希腊女高音歌唱家)",
"卡拉斯(游戏星际争霸2中的虚拟人物)",
"卡拉斯(捷克足球运动员)"
]
}
复制代码
- 剩余336个词条中,都有对应的,共357个,因为一对多
列表:query_avpair_entities_list.txt
baby-5
miss.情人节
mr.1
mr.11
mr.13
……
复制代码
字典:query_avpair_entities_mapping.json
{
"Baby-5": [
"baby-5"
],
"Miss.情人节": [
"miss.情人节"
],
"Mr.11": [
"mr.11"
],
"Mr.13": [
"mr.13"
],
……
复制代码
1.2.4.获取图谱中对应实体的三元组知识
同样利用知识工厂提供的API,根据前面query_avpair_entities_list.txt
实例列表,获取图谱中对应实体的三元组知识
python cndbpedia/get_onepiece_cndbpedia_avpair.py
复制代码
保存在 cndbpedia/data/query_avpair_cndbpedia_onepiece_results.json
,如:
……
"蒙奇·D·路飞": {
"蒙奇·d·路飞(日本漫画《航海王》的角色)": {
"中文名": "蒙奇·D·路飞",
"外文名称": "Monkey D. Luffy",
"其他名": "第五位海上皇帝",
"配音": "杨天翔(中国大陆)",
"登场作品": "《ROMANCE DAWN》漫画",
"生日": "5月5日(日本儿童节)",
"年龄": "17岁→19岁",
"性别": "男",
"血型": "F型",
"身高": "172cm→174cm",
"体重": "45kg",
"恶魔果实": "橡胶果实",
"故乡": "东海-哥亚王国-风车村",
"代表地区": "冲绳县",
"代表动物": "猴子",
"代表颜色": "红色",
"代表数字": "01、56(日文56和橡胶同音)、09",
"代表国家": "巴西",
"代表花朵": "波斯菊",
"悬赏金": "15亿贝里",
"喜欢的岛屿": "有肉的岛屿",
"喜欢的季节": "夏天",
"喜欢的食物": "所有美食,首选是肉",
"讨厌的食物": "加雅岛上的樱桃派",
"身上味道": "烤肉的味道",
"CATEGORY_ZH": "人物",
"DESC": "蒙奇·D·路飞,日本漫画《航海王》及其衍生作品中的主角,外号“草帽”路飞,草帽一伙、草帽大船团船长,极恶的世代之一。橡胶果实能力者的橡胶人,悬赏金15亿贝里。梦想是找到传说中的One Piece,成为海贼王。\n路飞性格积极乐观,爱憎分明,而且十分重视伙伴,不甘屈居于他人之下,对任何危险的事物都超感兴趣。和其他传统的海贼所不同的是,他并不会为了追求财富而杀戮,而是享受着身为海贼的冒险和自由。"
}
},
……
复制代码
cndbpedia/data/query_avpair_keys_list_file.txt
:为所有属性名称列表
1.2.5.抽取网页中半结构化的知识
生命卡(vivre card)是海贼王官方整理发布的角色资料图鉴,包含着丰富的角色信息。国内的粉丝翻译成了中文,发布在talkop bbs。
抽取流程
由于格式较为固定,直接模式匹配(正则匹配)。人工删除不相关文本、采集、正则匹配、人工校验(循环步骤,对照predicate调整模板):
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的格式保存
汇总结果
在上面部分中,我们分别抽取了各个网页中人物实体的属性信息,现在将这些信息进行进一步的汇总
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的汇总
1.3. 关系抽取数据集构建
-
标注数据来源:在前面构建的人物知识图谱中,有一项重要的属性是历史信息,记录着每个人物在故事中的时间线以及对应的故事。每个人的历史信息记录着其与其他实体之间交互的信息,我们可以利用它来构建我们垂直领域内的关系抽取数据集
-
标注工具:精灵标注助手
-
构建方法:自底向上构建,在构建过程中逐步构建整个图谱的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
数据集统计信息
-
实体类型:一共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个
1.4. 实体关系知识图谱构建
在进行关系抽取数据集的标注过程中,我们将标注的实体和关系单独导出,构建《海贼王》实体关系数据集
在上述过程中,一共标注了307个不同的实体,569个不同结点间的关系
cd deepke-master
python utils/convert_vivrecard2deepke.py
复制代码
输出的实体关系数据保存在 deepke-master/data/vivrecard/summary/vizdata_vivrecard_relation.json
,可用于后续进行知识图谱可视化,具体参见知识图谱可视化
2. 知识存储
2.1. 基于RDF 三元组数据库:Apache Jena
2.1.1. Jena 简介
Jena 是 Apache 顶级项目,其前身为惠普实验室开发的 Jena 工具包。Jena 是语义 Web 领域主要的开源框 架和 RDF 三元组库,较好地遵循了 W3C 标准,其功能包括:RDF 数据管理、RDFS 和 OWL 本体管理、SPARQL 查询处理等。Jena 具备一套原生存储引擎,可对 RDF 三元组进行基于磁盘或内存的存储管理.同时,具有一套基 于规则的推理引擎,用以执行 RDFS 和 OWL 本体推理任务。
2.1.2. 项目实践
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,上传数据集就可以查询了
2.1.3. SPARQL查询示例
SPARQL 是 W3C 制定的 RDF 知识图谱标准查询语言。SPARQL 从语法上借鉴了 SQL。SPARQL 查询的 基本单元是三元组模式(triple pattern),多个三元组模式可构成基本图模式(basic graph pattern)。SPARQL 支持多 种运算符,将基本图模式扩展为复杂图模式(complex graph pattern)。SPARQL 1.1 版本引入了属性路径(property path)机制以支持 RDF 图上的导航式查询。
下面给出了使用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日" ,
复制代码
2.2. 基于原生图数据库:Neo4j
2.2.1. Neo4j简介
Neo4j 是由 Neo 技术公司开发的图数据库。可以说 Neo4j 是目前流行程度最高的图数据库产品。Neo4j 基 于属性图模型,其存储管理层为属性图的节点、节点属性、边、边属性等元素设计了专门的存储方案.这使得 Neo4j 在存储层对于图数据的存取效率优于关系数据库。
2.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
2.2.3. Cypher查询示例
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 复制代码
.png)
-
根据名字筛选德雷斯罗萨到司法岛里面四跳的路径
# 五跳内能到的所有路径 # 9312 多萝菲(Miss.圣诞快乐) # 9306 本·贝克曼 MATCH p = ((n1)-[*4]-(n2)) WHERE n1.uri CONTAINS '司法岛' and n2.uri CONTAINS '德雷斯罗萨' RETURN p 复制代码
可以发现这里面存在一些环路的情况,即同一个结点在路径中出现两次
3. 知识抽取
DeepKE 基于 Pytorch 的深度学习中文关系抽取处理套件。在这部分中我们利用之前构建的关系抽取数据集和deepke,进行中文关系抽取实践。
3.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 # [未被]标记上关系的句子
复制代码
3.2. 训练
在训练过程中我们尝试使用了deepke所提供的PCNN, rnn, gcn, capsule, transformer, bert 这些模型,epoch 设置为 50,num_relations
根据我们数据集的实际情况修改为19,需要注意的是基于BERT的语言模型进行训练时,需要先在相关网页下载好预训练模型
新的数据集有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
复制代码
3.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模型的好
我们猜测是由于我们的数据存在长尾分布问题,模型可能趋向于预测某些特定关系来作弊,已达到准确率提高的效果
4. 知识计算
4.1. 图计算
知识图谱的一个很重要的特征就是其的图结构,不同实体之间的结构本身就内含着许多的隐式的信息,可以被进一步的挖掘利用。
在这部分中,我们参考他人在类似领域的[实践](www.macalester.edu/~abeverid/t… ↩︎)([参考](www.maa.org/sites/defau… ↩︎)),利用Neo4j提供的图算法,对我们构建的实体关系知识图谱,用图算法进行一定的计算分析,包括计算最短路径、关键结点、结点中心度、社区发现等。
4.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
复制代码
4.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
复制代码
从结果表格中我们可以看出有趣的结果:娜美和路飞是萨奇斯和诺琪高的关键节点。这意味着,所有联结萨奇斯和诺琪高的最短路径都要经过娜美和路飞。我们可以通过可视化萨奇斯和诺琪高之间的所有最短路径来验证:
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
复制代码
4.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 |
4.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给检测出来了,包括在磁鼓岛和黑暗磁鼓王国
4.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. 知识应用
5.1. 智能问答
在这部分中我们参考前人的工作,研究,基于REfO实现了一个KBQA系统,主要流程为:解析输入的自然语言问句生成 SPARQL 查询,进一步请求后台基于 TDB 知识库的 Apache Jena Fuseki 服务, 得到结果。代码和数据存放在 vivirecard-KB_query
目录下
5.1.1. 支持的问题类型
- 对于生日/英文名/血型/星座/霸气/身高的查询
- 谁出生在哪里/出生在某个地方的有谁
5.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. 🙁
5.2. 知识图谱可视化
在这部分中,我们参考别人的工作,利用D3对之前构建的实体关系知识图谱提供可视化交互功能,包括结点连接关系可视化、查询相关结点信息。同时在这部分也整合了之间构建的人物属性知识图谱,提供了信息框的展示过程,相关的数据和代码存放在 visualization
目录下。整个可视化页面的交互过程如下面的gif图所示:
可视化网页存放于 visualization/html/index.html
,可以通过 Microsoft Edge 浏览器直接打开
如果需要在其他浏览器中打开,可能会加载不出来可视化结果。这是因为跨域请求在大多数浏览器中是禁止的,请求不到json数据。因此需要用 WAMP/LAMP/MAMP 配置一个Web网络环境。
打开后可视化界面如下所示,不同的颜色代表不同类型的实体,具有关系的实体会用白色的细线连接,可以明显的看到有些实体与其他实体存在大量的连接
点击左上角的模式切换按钮,我们可以把结点展示从圆圈模式变换为文本模式,能够进行更加细致的观察
选中某个结点后,将只会显示该节点以及与其直接相连接的结点。特别的,如果该节点类型是人物,还会在页面右侧显示该人物的信息框
此外左侧还提供了搜索框的功能,可以方便我们查找结点信息