接上篇文章,这篇文章也是基于知乎专栏 https://zhuanlan.zhihu.com/knowledgegraph 的学习笔记。本文主要是梳理一遍专栏中实战的内容,以及就自己遇到的问题备注一下解决方案。感谢原up主与下面热心提供解决问题方案的知乎网友们。
文章目录
(一)数据准备和本体建模
原文:https://zhuanlan.zhihu.com/p/32389370
1. 数据准备(将sql文件导入MySQL)
从博主的github上下载原始数据,在data文件夹中。把数据文件导入mysql。具体方法:
preprocess: 用编辑器打开sql文件,把所有的CHARSET=utf8mb4改为CHARSET=utf8。(避免后面不必要的麻烦)
-
打开Navicat,在自己创建的数据库上右键选择“打开链接”后选择“运行SQL文件”:
-
选择data文件夹里的sql文件,选择编码方式,开始导入(编码设为utf8,避免之后一些不必要的麻烦):
3. 完成后产生一张名为kg_demo_movie的数据库,打开内有五张表,如图:
以上。数据准备完成。
2. 本体建模
即上篇文章说到的owl的部分,搭建大类之间的关系,使用工具Protégé(点击进入官网下载)。
- 点击“Download now”—“Download for Desktop”得到压缩包,解压即可。解压后打开直接运行Protege.exe进入如下界面,把红框中内容改为如图,这是我们新建本体资源的IRI(Internationalized Resource Identifiers)
- 点击“Entities”标签,选择“Classes”,在owl Thing下面创建子类。“Genre”“People”“Movie”,中间三个小红框分别是"创建子类"“创建平行类”“删除当前选中的类”(从左至右)。右边的“Description Genre”下面可以按需设置类的特性。
- 在“Object properties”中可以设置类之间的关系(即连接两个实体的那条线),右边设置线发起(Domains)和指向(Range)的实体。即这段关系的主题与取值范围。也可以设置关系与关系间的相反,相等等性质。以在日后的推理中发挥作用。
- 最后设置数据属性。选择“Data properties”。设置方法与上面类似,不同的是数据相当于树的叶子节点,不指向谁,所以他们的“ranges”是数值类型。
6. 选择“Window”选项选择“Tabs”,打开“OntoGraf”,再选择“OntoGraf”,拖拽标签可以让实体关系可视化。
- 把实体文件保存为ontology.owl,以便随后使用。
(二)把MySQL中的数据转为RDF
原文:https://zhuanlan.zhihu.com/p/32552993
通过D2RQ(点击打开网址)来实现转化,下载压缩包(我下的是d2rq-0.8.1.tar.gz),解压,进入目录。
运行如下命令生成默认mapping文件:
generate-mapping -u root -o kg_demo_movie_mapping.ttl -p 123456 jdbc:mysql:///kg_demo_movie
“-u”后面是mysql的用户名,“-o”后面是保存的文件名,“-p”后面是mysql的密码(如果没有就不用输入“-p”及后面的内容),jdbc:mysql:///kg_demo_movie指定我们要映射的数据库。于是生成了默认的mapping文件:
@prefix map: <#> .
@prefix db: <> .
@prefix vocab: <vocab/> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix xsd: <XML Schema> .
@prefix d2rq: <http://www.wiwiss.fu-berlin.de/suhl/bizer/D2RQ/0.1#> .
@prefix jdbc: <http://d2rq.org/terms/jdbc/> .
map:database a d2rq:Database;
d2rq:jdbcDriver "com.mysql.jdbc.Driver";
d2rq:jdbcDSN "jdbc:mysql:///kg_demo_movie";
d2rq:username "root";
d2rq:password "123456";
jdbc:autoReconnect "true";
jdbc:zeroDateTimeBehavior "convertToNull";
.
# Table genre
map:genre a d2rq:ClassMap;
d2rq:dataStorage map:database;
d2rq:uriPattern "genre/@@genre.genre_id@@";
d2rq:class vocab:genre;
d2rq:classDefinitionLabel "genre";
.
map:genre__label a d2rq:PropertyBridge;
d2rq:belongsToClassMap map:genre;
d2rq:property rdfs:label;
d2rq:pattern "genre #@@genre.genre_id@@";
.
map:genre_genre_id a d2rq:PropertyBridge;
d2rq:belongsToClassMap map:genre;
d2rq:property vocab:genre_genre_id;
d2rq:propertyDefinitionLabel "genre genre_id";
d2rq:column "genre.genre_id";
d2rq:datatype xsd:integer;
.
map:genre_genre_name a d2rq:PropertyBridge;
d2rq:belongsToClassMap map:genre;
d2rq:property vocab:genre_genre_name;
d2rq:propertyDefinitionLabel "genre genre_name";
d2rq:column "genre.genre_name";
.
# Table movie
map:movie a d2rq:ClassMap;
d2rq:dataStorage map:database;
d2rq:uriPattern "movie/@@movie.movie_id@@";
d2rq:class vocab:movie;
d2rq:classDefinitionLabel "movie";
.
map:movie__label a d2rq:PropertyBridge;
d2rq:belongsToClassMap map:movie;
d2rq:property rdfs:label;
d2rq:pattern "movie #@@movie.movie_id@@";
.
map:movie_movie_id a d2rq:PropertyBridge;
d2rq:belongsToClassMap map:movie;
d2rq:property vocab:movie_movie_id;
d2rq:propertyDefin