实践篇(一):数据准备和本体建模

实践篇(一):数据准备和本体建模

通过前面几篇文章的介绍,读者应该对知识图谱,其相关概念,以及语义网技术栈中的RDF,RDFS/OWL有了一定的了解。然而,之前我们都是在介绍一些概念性的东西。实践才出真知,理论掌握得再好,不能解决实际问题也只是纸上谈兵。因此,笔者准备开一个实践篇,结合理论篇,让读者能够从无到有构建一个领域知识图谱,并在其上搭建一个基于知识图谱的问答小程序。demo比较简单,问答实现是基于模板匹配和正则表达式,整个流程是为了让读者对知识图谱及其相关应用有个直观的认识。

本文作为实践篇第一篇文章,首先介绍我们使用的数据、数据来源和数据获取方法;其次,基于数据内部关系,介绍如何以自顶向下的方式构建本体结构。

一、数据准备

实践篇使用的数据是与电影相关的。基本统计数据如下:

1. 演员数量:505人

2. 电影数量:4518部

3. 电影类型:19类

4. 人物与电影的关系:14451

5. 电影与类型的关系:7898

演员的基本信息包括:姓名、英文名、出生日期、死亡日期、出生地、个人简介。

电影的基本信息包括:电影名称、电影简介、电影评分、电影发行日期、电影类型。

数据是从“The Movie Database (TMDb”网站获取的,官方提供注册用户API KEY用于查询和下载数据。我本来打算从豆瓣获取电影数据,但现在豆瓣API已经关闭了个人用户申请入口。

本实例数据获取方法:以周星驰为初始入口,获取其出演的所有电影;再获取这些电影的所有参演演员;最后获取所有参演演员所出演的全部电影。经过去重处理,我们得到了505个演员的基本信息和4518部电影的基本信息。数据保存在mysql中,其ER图如下:


读者可以直接下载我们获取到的数据,或者用我们提供的脚本自己从网站获取额外的数据,再或者根据自己的需要重新编写脚本。

二、本体建模

本体的构建大体有两种方式:自顶向下和自底向上。

1. 开放域知识图谱的本体构建通常用自底向上的方法,自动地从知识图谱中抽取概念、概念层次和概念之间的关系。这也很好理解,开放的世界太过复杂,用自顶向下的方法无法考虑周全,且随着世界变化,对应的概念还在增长。

2. 领域知识图谱多采用自顶向下的方法来构建本体。一方面,相对于开放域知识图谱,领域知识图谱涉及的概念和范围都是固定或者可控的;另一方面,对于领域知识图谱,我们要求其满足较高的精度。现在大家接触到的一些语音助手背后对接的知识图谱大多都是领域知识图谱,比如音乐知识图谱、体育知识图谱、烹饪知识图谱等等。正因为是这些领域知识图谱来满足用户的大多数需求,更需要保证其精度。


本实例是一个电影领域的知识图谱,我们采用自顶向下的方法来构建本体结构。首先介绍下我们使用的工具protégé(点击进入官网下载):

Protégé,又常常简单地拼写为“Protege”,是一个斯坦福大学开发的本体编辑和知识获取软件。开发语言采用Java,属于开放源码软件。由于其优秀的设计和众多的插件,Protégé已成为目前使用最广泛的本体论编辑器之一(来自维基百科)。


打开protege,看到和下图类似的界面。在Ontology IRI中填写我们新建本体资源的IRI。读者可以填写自己的符合标准的IRI。

点击“Entities”tab标签,选择“Classes”标签。在这个界面,我们创建电影知识图谱的类/概念。注意,所有的类都是“Thing”的子类。最左边红色小方框中的按钮用于创建当前选中类的子类,中间的按钮用于创建兄弟类(平行类),最右边的按钮删除当前选中的类。我们创建了三个类,“人物”、“电影”、“类别”。右下方的界面是用于描述该类的一些特性,例如:"disjoint of"是用于表示该类与哪些类是互斥的。本例中,三个类都是互斥的。也就是说,一个实例只能是三个类中的一个。我们没有在protege中显式地定义互斥关系,读者可以自己定义。


接下来我们切换到"Object Properties"页面,我们在此界面创建类之间的关系,即,对象属性。这里我们创建了三个对象属性,"hasActedIn"表示某人参演了某电影,因此我们在右下方的3号矩形框中定义该属性的"domain"是人,4号框定义"range"是电影。这个很好理解,"domain"表示该属性是属于哪个类的,"range"表示该属性的取值范围。2号框表示该属性的逆属性是"hasActor",即,有了推理机,尽管我们的RDF数据只保存了A出演了B,我们在查询的时候也能得到B的演员有A。1号方框中是一些描述该属性的词汇,我们在上一篇文章中已经介绍过,这里不再赘述。同理,我们定义另外两个属性,这里不再展示。


最后,我们切换到"Data properties",我们在该界面创建类的属性,即,数据属性。其定义方法和对象属性类似,除了没有这么丰富的描述属性特性的词汇。其实不难理解,这些描述特性的词汇是传递、对称、反对称、自反等,表明其必定有指向其他资源或自身的边,而我们之前提到过,数据属性相当于树的叶子节点,只有入度,而没有出度。


其实区分数据属性和对象属性还有一个很直观的方法,我们观察其"range",取值范围即可。对象属性的取值范围是类,而数据属性的取值范围则是字面量,如下图。


protege也支持以可视化的方式来展示本体结构。我们点击"Window"选项,在"Tabs"中选择"OntoGraf",然后"Entities"旁边就多了一个标签页。在右侧窗口中移动元素,可以很直观地观察本体之间的关系。

在这个小节,我们简单地介绍了如何用protege自顶向下地构建知识图谱的本体结构。对于Protege更详细的操作和介绍,请参考这篇文档


总结

这篇文章介绍了接下来实践中使用的数据,以及如何利用protege,根据我们的数据来进行本体建模。数据、代码以及本体文件我都上传到了github。之后实践篇涉及到的所有文件我都会放在该项目中。下一篇实践文章将介绍关系数据库中的数据转换为RDF的几种方法,让读者学会如何把存在Mysql中的电影数据转为RDF格式的数据。

编辑于 2017-12-27

文章被以下专栏收录

    目前,网上关于知识图谱的学习资源比较少,关于如何在现实生活场景中应用知识图谱技术的资源更少。出于科普和交流的目的,我创建了此专栏。本专栏主要介绍知识图谱所涉及到的一些相关概念、技术,并结合实践让读者能够构建一个轻量的知识图谱和搭建基于知识图谱的应用。