上一篇已经对 Answer 系统的基本原理做了简单的分析和介绍,接下来的两篇文章将介绍 Answer 系统中的本体构建模块。本体构建模块完成的主要功能是爬取百度百科页面的数据并基于规则构建起本体库。
本体库是整个系统的关键知识来源,是实现同名实体识别、实体别名识别等功能的关键。
但在讲解本体构建模块的实现之前,需要对诸如"本体"、"RDF/RDFS"、"OWL"等概念和"WebMagic"、"Jena"等涉及到的技术做一下基本介绍。
何为本体
本体概念最早源自于哲学领域,是事物的本源和根本。
从哲学中的本体论上讲,我们所看到的,所听到的和所感觉到的一切都只是事物的一种现象表示。
比如我们说一朵玫瑰是红色的,并不表示红色是这朵玫瑰的自身具有的根本属性,因为颜色只是光线带给我们的一种视觉效果。
同样的,我们闻到的玫瑰的香味、触摸玫瑰花时的触感都只是一种感官上的印象,是我们的感官对玫瑰的一种表达。人们对玫瑰的所有描述都只是一种符号,对它的所有认识都只是一种现象,而这些符号和表象都将指向玫瑰的本源。
因此在哲学本体论并认为玫瑰这个事物根本或事物本源是客观存在的,但同时也是不可认知的,这个事物本源并称之为本体。
当然在计算机领域引入本体之后,并没有这么高层次的概念和理解。在计算机领域中我们将本体定义成一种计算机可操作、可理解、可计算的概念。目前业内有许多关于本体的定义,其中最受认可的是 Studer 给出的理解:
An ontology is a formal, explicit specification of a shared conceptualization.”
本体是共享概念模型的明确的形式化规范说明。
其中定义了本体几层含义。
-
概念模型
本体是对现实世界概念模型的表达和说明 -
明确
所定义的概念、概念相关的属性以及概念之间的关系等都必须具有明确的含义 -
形式化
不同于哲学领域的定义,计算机领域的本体是形式化的,是计算机能够理解和处理的 -
共享
是领域公认的概念和知识,能够相互分享和操作
简而言之,计算机世界中的本体就是利用计算机描述语言如 RDF/RDFS/OWL 等(可以采用 XML、JSON 等语法格式实现)去对现实世界中的概念进行说明定义,也就是用计算机可理解的数据模型来描述现实中的"本体",而在构建的过程中要注意其共享性和规范性。
本体构建语言
如前所说,我们希望在计算机世界里构建并描述现实世界中的概念,那么我们就需要一些规范、标准、强大的本体构建语言(也可称为本体标记语言或本体表示语言)。
目前已有很多不同的本体构建语言,而主流的本体构建语言主要有 RDF/RDFS、OWL 等。
-
RDF
资源定义框架(Resource Description Framework),简称为 RDF,是 W3C 提出的 Web 元数据描述语言标准。它能够描述互联网资源之间的关系,其语法格式也以可扩展标记语言 XML 为基础。其主要由一系列的三元组组成,三元组的主要形式为“主体-谓语-客体”,这里的谓语并不局限于动词,而是表达主体和客体之间的关系。
例如"周星驰-年龄-xx" 这一个三元组中,"周星驰"是三元组中的主体,"年龄"(属性名)是谓语,"xx"(属性值)就是客体。 -
RDFS
RDFS 是在 RDF 的基础上对其进行了适当扩展,相对于 RDF,RDFS 能够描述类与类之间、属性与属性之间的层次关系、资源之间的关系,因此 RDFS 具有更加强大表达能力。例如 subClassOf 表达类与类之间的父子关系,subPropertyOf 表达属性与属性之间的父子关系。 -
OWL
OWL 是 Web Ontology Language 的缩写,其中文含义即为网络本体语言。W3C 设计了三种不同程度的 OWL 子语言,分别为 OWL Lite、OWL DL 和 OWL Full,三种语言在本体描述能力上依次增强,并且高表达能力语言可兼容低表达能力语言,我们可根据不同的应用场景选择不同程度的表达语言。
利用上述语言就可以构建本体库,并在本体库表达一些知识,如下所示(使用 OWL 构建):
<?xml version="1.0"?>
<Ontology xmlns="http://www.w3.org/2002/07/owl#"
xml:base="http://www.semanticweb.org/yue/ontologies/2018/2/untitled-ontology-5"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:xml="http://www.w3.org/XML/1998/namespace"
xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
ontologyIRI="http://www.semanticweb.org/yue/ontologies/2018/2/untitled-ontology-5">
<Prefix name="owl" IRI="http://www.w3.org/2002/07/owl#"/>
<Prefix name="rdf" IRI="http://www.w3.org/1999/02/22-rdf-syntax-ns#"/>
<Prefix name="xml" IRI="http://www.w3.org/XML/1998/namespace"/>
<Prefix name="xsd" IRI="http://www.w3.org/2001/XMLSchema#"/>
<Prefix name="rdfs" IRI="http://www.w3.org/2000/01/rdf-schema#"/>
<Declaration>
<ObjectProperty IRI="#妻子"/>
</Declaration>
<Declaration>
<NamedIndividual IRI="#周杰伦"/>
</Declaration>
<Declaration>
<Class IRI="#人"/>
</Declaration>
<Declaration>
<NamedIndividual IRI="#昆凌"/>
</Declaration>
<ClassAssertion>
<Class IRI="#人"/>
<NamedIndividual IRI="#周杰伦"/>
</ClassAssertion>
<ClassAssertion>
<Class IRI="#人"/>
<NamedIndividual IRI="#昆凌"/>
</ClassAssertion>
<ObjectPropertyAssertion>
<ObjectProperty IRI="#妻子"/>
<NamedIndividual IRI="#周杰伦"/>
<NamedIndividual IRI="#昆凌"/>
</ObjectPropertyAssertion>
</Ontology>
<!-- Generated by the OWL API (version 4.2.8.20170104-2310) https://github.com/owlcs/owlapi -->
上述 OWL 语言表达了以下现实知识:
-
存在着名为"妻子"的对象属性
如下所示:<Declaration> <ObjectProperty IRI="#妻子"/> </Declaration>
- 对象属性:对象之间的关系称之为对象属性,如 "周杰伦-妻子-昆凌",其中 "妻子" 为两个对象实体之间的关系,称之为对象属性。
- 数据属性:如 "周星驰-年龄-xx" 中的 "年龄" 是 "周星驰" 和数据 xx 之间的关系,这种关系称为数据属性。
-
存在着 "人" 这个类型
如下所示:<Declaration> <Class IRI="#人"/> </Declaration>
-
存在着 "周杰伦" 这个对象实体
如下所示:<Declaration> <NamedIndividual IRI="#周杰伦"/> </Declaration>
-
存在着 "昆凌" 这个对象实体
如下所示:<Declaration> <NamedIndividual IRI="#昆凌"/> </Declaration>
-
"周杰伦" 属于人这个类型
如下所示:<ClassAssertion> <Class IRI="#人"/> <NamedIndividual IRI="#周杰伦"/> </ClassAssertion>
-
"昆凌" 属于人这个类型
如下所示:<ClassAssertion> <Class IRI="#人"/> <NamedIndividual IRI="#昆凌"/> </ClassAssertion>
-
"周杰伦" 的妻子是 "昆凌",即 "周杰伦-妻子-昆凌"
如下所示:<ObjectPropertyAssertion> <ObjectProperty IRI="#妻子"/> <NamedIndividual IRI="#周杰伦"/> <NamedIndividual IRI="#昆凌"/> </ObjectPropertyAssertion>
本体操作框架 Jena
现在我们已经有了 RDF、RDFS 和 OWL 等本体构建语言来构建本体库了,但是我们该如何对这些语言描述的数据进行查询、插入、删除、更新等操作呢?自然是需要写相应的程序来解析和操作这些 RDF / RDFS / OWL 数据。
但像这种底层需求的功能自然已经有相应的轮子以供高层应用开发者使用。Jena 便是这样一款满足我们需求的开源框架,它提供了一系列强大的 API 实现对本体库的插入、查询等操作。
关于 Jena 的下载和详细 API 文档等可参见官网 Apache Jena
爬虫框架 WebMagic
有了 RDF、OWL 等本体库构建语言以及对本体库进行查询操作的 Jena 之后,我们就可以编写程序向本体库中插入或更新各种 "知识" 了。
但是这些 "知识" 来源于哪里?又该如何生成?这里又是一块深不见底的坑,也是目前学术界比较活跃的研究领域,尤其是从非结构文本中提取知识。
当前版本的 Answer 采用最简单最土的方式——数据来源于半结构化的百度百科,并基于规则,通过定义规则的方式来进行分类、插入属性、建立对象之间关系等,从而生成一系列的知识插入到本体库中。
那么这里自然需要一个爬虫去抓取百度百科的数据,这里采用开源的 Java 爬虫框架 WebMagic,关于 WebMagic 的使用教程和文档请查看官方网站 http://webmagic.io/
下一篇
下一篇讲解本体构建模块的实现。
汪
汪.