知识图谱的简述:
在百度或者Google搜索一个历史人物,都会出现其对象的小名片,而不是直接显示一堆需要你点进去的超链接,这些小名片就是应用知识图谱来制作的。
知识图谱跟语义网络非常的相似,但也有很多不同的地方,语义网络更侧重于描述概念与概念之间的关系,而知识图谱则更偏重于描述实体之间的关联。如下面的两张图片所示,可以看出语义网络的缺点如下:
- 边和节点的值没有标准,完全是由用户自己定义。
- 多源数据融合比较困难,因为没有标准。
- 无法区分概念节点和对象节点。
- 无法对节点和边的标签进行定义。
- 知识图谱是由一些相互连接的实体和他们的属性构成的。换句话说,知识图谱是由一条条知识组成,每条知识表示为一个SPO三元组(Subject-Predicate-Object)。
在知识图谱中,我们用RDF形式化地表示这种三元关系。RDF(Resource Description Framework),即资源描述框架,是W3C制定的,用于描述实体/资源的标准数据模型。RDF图中一共有三种类型,International Resource Identifiers(IRIs),blank nodes 和 literals。下面是SPO每个部分的类型约束: - Subject可以是IRI或blank node。
- Predicate是IRI。
- Object三种类型都可以。
IRI我们可以看做是URI或者URL的泛化和推广,它在整个网络或者图中唯一定义了一个实体/资源,和我们的身份证号类似。
literal是字面量,我们可以把它看做是带有数据类型的纯文本,比如我们在第一个部分中提到的罗纳尔多原名可以表示为"Ronaldo Luís Nazário de Lima"^^xsd:string。
blank node简单来说就是没有IRI和literal的资源,或者说匿名资源。
我们其实可以认为知识图谱就包含两种节点类型,资源和字面量。借用数据结构中树的概念,字面量类似叶子节点,出度为0。"罗纳尔多·路易斯·纳萨里奥·德·利马"作为字面量,是不能有指向外部节点的边的,况且之前的图并不能直观地体现知识图谱中资源/实体(用IRI表示)这样一个极其重要的概念。
用更正式的说法,知识图谱是由本体(Ontology)作为Schema层,和RDF数据模型兼容的结构化数据集。Tom Gruber把本体定义为“概念和关系的形式化描述”,分别指实体的类层次和关系层次。我们以上篇文章罗纳尔多知识图为例,我们用IRI唯一标志的节点都是某个类的一个实例,每一条边都表示一个关系。罗纳尔多是一个人,里约热内卢是一个地点,我们用RDF来表示就是:
www.kg.com/person/1 rdf:type kg:Person.
www.kg.com/place/10086 rdf:type kg:Place.
关系我们也称为属性(Property),根据是实体和实体之间的关系还是实体和数据值之间的关系分为对象属性(Object Property)和数据属性(Data Property)。在图中,罗纳尔多和里约热内卢的关系(本例中是对象属性)与罗纳尔多和全名的关系(本例中是数据属性)用RDF就可以表示为:
www.kg.com/person/1 kg:hasBirthPlace www.kg.com/place/10086
www.kg.com/person/1 kg:fullName "Ronaldo Luís Nazário de Lima"^^xsd:string
这里kg:Person,kg:Place,kg:hasBirthPlace,kg:fullName是我们在Ontology中定义好的类和关系。
RDF,RDFS与OWL
RDF表现形式
RDF(Resource Description Framework),即资源描述框架,其本质是一个数据模型(Data Model)。它提供了一个统一的标准,用于描述实体/资源。简单来说,就是表示事物的一种方法和手段。RDF形式上表示为SPO三元组,有时候也称为一条语句(statement),知识图谱中我们也称其为一条知识。
RDF由节点和边组成,节点表示实体/资源、属性,边则表示了实体和实体之间的关系以及实体和属性的关系
RDF序列化方法
RDF的表示形式和类型有了,那我们如何创建RDF数据集,将其序列化(Serialization)呢?换句话说,就是我们怎么存储和传输RDF数据。目前,RDF序列化的方式主要有:RDF/XML,N-Triples,Turtle,RDFa,JSON-LD等几种。
- RDF/XML,顾名思义,就是用XML的格式来表示RDF数据。之所以提出这个方法,是因为XML的技术比较成熟,有许多现成的工具来存储和解析XML。然而,对于RDF来说,XML的格式太冗长,也不便于阅读,通常我们不会使用这种方式来处理RDF数据。
- N-Triples,即用多个三元组来表示RDF数据集,是最直观的表示方法。在文件中,每一行表示一个三元组,方便机器解析和处理。开放领域知识图谱DBpedia通常是用这种格式来发布数据的。
- Turtle, 应该是使用得最多的一种RDF序列化方式了。它比RDF/XML紧凑,且可读性比N-Triples好。RDFa, 即“The Resource Description Framework in Attributes”,是HTML5的一个扩展,在不改变任何显示效果的情况下,让网站构建者能够在页面中标记实体,像人物、地点、时间、评论等等。也就是说,将RDF数据嵌入到网页中,搜索引擎能够更好的解析非结构化页面,获取一些有用的结构化信息。读者可以去这个页面感受一下
- RDFa,其直观展示了普通用户看到的页面,浏览器看到的页面和搜索引擎解析出来的结构化信息。
- JSON-LD,即“JSON for Linking Data”,用键值对的方式来存储RDF数据。
下面,我们结合罗纳尔多知识图的例子,给出其N-Triples和Turtle的具体表示。
Example1 N-Triples:
<http://www.kg.com/person/1> <http://www.kg.com/ontology/chineseName> "罗纳尔多·路易斯·纳萨里奥·德·利马"^^string.
<http://www.kg.com/person/1> <http://www.kg.com/ontology/career> "足球运动员"^^string.
<http://www.kg.com/person/1> <http://www.kg.com/ontology/fullName> "Ronaldo Luís Nazário de Lima"^^string.
<http://www.kg.com/person/1> <http://www.kg.com/ontology/birthDate> "1976-09-18"^^date.
<http://www.kg.com/person/1> <http://www.kg.com/ontology/height> "180"^^int.
<http://www.kg.com/person/1> <http://www.kg.com/ontology/weight> "98"^^int.
<http://www.kg.com/person/1> <http://www.kg.com/ontology/nationality> "巴西"^^string.
<http://www.kg.com/person/1> <http://www.kg.com/ontology/hasBirthPlace> <http://www.kg.com/place/10086>.
<http://www.kg.com/place/10086> <http://www.kg.com/ontology/address> "里约热内卢"^^string.
<http://www.kg.com/place/10086> <http://www.kg.com/ontology/coordinate> "-22.908333, -43.196389"^^string.
用Turtle表示的时候我们会加上前缀(Prefix)对RDF的IRI进行缩写。同一个实体拥有多个属性(数据属性)或关系(对象属性),我们可以只用一个subject来表示,使其更紧凑。即,将一个实体用一个句子表示(这里的句子指的是一个英文句号“.”)而不是多个句子,属性间用分号隔开。
Example2 Turtle:
@prefix person: <http://www.kg.com/person/> .
@prefix place: <http://www.kg.com/place/> .
@prefix : <http://www.kg.com/ontology/> .
person:1 :chineseName "罗纳尔多·路易斯·纳萨里奥·德·利马"^^string;
:career "足球运动员"^^string;
:fullName "Ronaldo Luís Nazário de Lima"^^string;
:birthDate "1976-09-18"^^date;
:height "180"^^int;
:weight "98"^^int;
:nationality "巴西"^^string;
:hasBirthPlace place:10086.
place:10086 :address "里约热内卢"^^string;
:coordinate "-22.908333, -43.196389"^^string.
RDF的表达能力
RDF的表达能力有限,无法区分类和对象,也无法定义和描述类的关系/属性。我的理解是,RDF是对具体事物的描述,缺乏抽象能力,无法对同一个类别的事物进行定义和描述。就以罗纳尔多这个知识图为例,RDF能够表达罗纳尔多和里约热内卢这两个实体具有哪些属性,以及它们之间的关系。但如果我们想定义罗纳尔多是人,里约热内卢是地点,并且人具有哪些属性,地点具有哪些属性,人和地点之间存在哪些关系,这个时候RDF就表示无能为力了。不论是在智能的概念上,还是在现实的应用当中,这种泛化抽象能力都是相当重要的;同时,这也是知识图谱本身十分强调的。RDFS和OWL这两种技术或者说模式语言/本体语言(schema/ontology language)解决了RDF表达能力有限的困境
RDF的“衣服”—— RDFS/OWL
之所以说RDFS/OWL是RDF的“衣服”,因为它们都是用来描述RDF数据的。为了不显得这么抽象,我们可以用关系数据库中的概念进行类比。用过Mysql的读者应该知道,其database也被称作schema。这个schema和我们这里提到的schema language十分类似。我们可以认为数据库中的每一张表都是一个类(Class),表中的每一行都是该类的一个实例或者对象(学过java等面向对象的编程语言的读者很容易理解)。表中的每一列就是这个类所包含的属性。如果我们是在数据库中来表示人和地点这两个类别,那么为他们分别建一张表就行了;再用另外一张表来表示人和地点之间的关系。RDFS/OWL本质上是一些预定义词汇(vocabulary)构成的集合,用于对RDF进行类似的类定义及其属性的定义。
Notice: RDFS/OWL序列化方式和RDF没什么不同,其实在表现形式上,它们就是RDF。其常用的方式主要是RDF/XML,Turtle。另外,通常我们用小写开头的单词或词组来表示属性,大写开头的表示类。数据属性(data property,实体和literal字面量的关系)通常由名词组成,而对象数据(object property,实体和实体之间的关系)通常由动词(has,is之类的)加名词组成。剩下的部分符合驼峰命名法。为了将它们表示得更清楚,避免读者混淆,之后我们都会默认这种命名方式。读者实践过程中命名方式没有强制要求,但最好保持一致。
轻量级的模式语言——RDFS
RDFS,即“Resource Description Framework Schema”,是最基础的模式语言。还是以罗纳尔多知识图为例,我们在概念、抽象层面对RDF数据进行定义。下面的RDFS定义了人和地点这两个类,及每个类包含的属性。
我们这里只介绍RDFS几个比较重要,常用的词汇:
- rdfs:Class. 用于定义类。
- rdfs:domain. 用于表示该属性属于哪个类别。
- rdfs:range. 用于描述该属性的取值类型。
- rdfs:subClassOf. 用于描述该类的父类。比如,我们可以定义一个运动员类,声明该类是人的子类。
- rdfs:subProperty. 用于描述该属性的父属性。比如,我们可以定义一个名称属性,声明中文名称和全名是名称的子类。
其实rdf:Property和rdf:type也是RDFS的词汇,因为RDFS本质上就是RDF词汇的一个扩展。我们在这里不罗列进去,是不希望读者混淆。RDFS其他的词汇及其用法请参考W3C官方文档。
Example3 RDFS:
df:type rdf:Property;
rdfs:domain :Person;
rdfs:range xsd:string .
:career rdf:type rdf:Property;
rdfs:domain :Person;
rdfs:range xsd:string .
:fullName rdf:type rdf:Property;
rdfs:domain :Person;
rdfs:range xsd:string .
:birthDate rdf:type rdf:Property;
rdfs:domain :Person;
rdfs:range xsd:date .
:height rdf:type rdf:Property;
rdfs:domain :Person;
rdfs:range xsd:int .
:weight rdf:type rdf:Property;
rdfs:domain :Person;
rdfs:range xsd:int .
:nationality rdf:type rdf:Property;
rdfs:domain :Person;
rdfs:range xsd:string .
:hasBirthPlace rdf:type rdf:Property;
rdfs:domain :Person;
rdfs:range :Place .
:address rdf:type rdf:Property;
rdfs:domain :Place;
rdfs:range xsd:string .
:coordinate rdf:type rdf:Property;
rdfs:domain :Place;
rdfs:range xsd:string .
为了让读者更直观地理解RDF和RDFS/OWL在知识图谱中所代表的层面,我们用下面的图来表示例子中的数据层和模式层。
Data层是我们用RDF对罗纳尔多知识图的具体描述,Vocabulary是我们自己定义的一些词汇(类别,属性),RDF(S)则是预定义词汇。从下到上是一个具体到抽象的过程。图中我们用红色圆角矩形表示类,绿色字体表示rdf:type,rdfs:domain,rdfs:range三种预定义词汇,虚线表示rdf:type这种所属关系。另外,为了减少图中连线的交叉,我们只保留了career这一个属性的rdf:type所属关系,省略了其他属性的此关系。
RDFS的扩展——OWL
RDFS本质上是RDF词汇的一个扩展。后来人们发现RDFS的表达能力还是相当有限,因此提出了OWL。我们也可以把OWL当做是RDFS的一个扩展,其添加了额外的预定义词汇。OWL,即“Web Ontology Language”,语义网技术栈的核心之一。OWL有两个主要的功能:
- 提供快速、灵活的数据建模能力。
- 高效的自动推理。
schema层的描述语言换为OWL后,层次图表示为:
数据属性用青色表示,对象属性由蓝色表示。罗纳尔多这个例子不能展现OWL丰富的表达能力,我们这里简单介绍一下常用的词汇:
描述属性特征的词汇
- owl:TransitiveProperty. 表示该属性具有传递性质。例如,我们定义“位于”是具有传递性的属性,若A位于B,B位于C,那么A肯定位于C。
- owl:SymmetricProperty. 表示该属性具有对称性。例如,我们定义“认识”是具有对称性的属性,若A认识B,那么B肯定认识A。
- owl:FunctionalProperty. 表示该属性取值的唯一性。 例如,我们定义“母亲”是具有唯一性的属性,若A的母亲是B,在其他地方我们得知A的母亲是C,那么B和C指的是同一个人。
- owl:inverseOf. 定义某个属性的相反关系。例如,定义“父母”的相反关系是“子女”,若A是B的父母,那么B肯定是A的子女。
本体映射词汇(Ontology Mapping)
- owl:equivalentClass. 表示某个类和另一个类是相同的。
- owl:equivalentProperty. 表示某个属性和另一个属性是相同的。
- owl:sameAs. 表示两个实体是同一个实体。
本体映射主要用在融合多个独立的Ontology(Schema)。举个例子,张三自己构建了一个本体结构,其中定义了Person这样一个类来表示人;李四则在自己构建的本体中定义Human这个类来表示人。当我们融合这两个本体的时候,就可以用到OWL的本体映射词汇。回想我们在第二篇文章中提到的Linked Open Data,如果没有OWL,我们将无法融合这些知识图谱。
用OWL对罗纳尔多知识图进行语义层的描述:
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix : <http://www.kg.com/ontology/> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
### 这里我们用词汇owl:Class定义了“人”和“地点”这两个类。
:Person rdf:type owl:Class.
:Place rdf:type owl:Class.
### owl区分数据属性和对象属性(对象属性表示实体和实体之间的关系)。
### 词汇owl:DatatypeProperty定义了数据属性,owl:ObjectProperty定义了对象属性。
:chineseName rdf:type owl:DatatypeProperty;
rdfs:domain :Person;
rdfs:range xsd:string .
:career rdf:type owl:DatatypeProperty;
rdfs:domain :Person;
rdfs:range xsd:string .
:fullName rdf:type owl:DatatypeProperty;
rdfs:domain :Person;
rdfs:range xsd:string .
:birthDate rdf:type owl:DatatypeProperty;
rdfs:domain :Person;
rdfs:range xsd:date .
:height rdf:type owl:DatatypeProperty;
rdfs:domain :Person;
rdfs:range xsd:int .
:weight rdf:type owl:DatatypeProperty;
rdfs:domain :Person;
rdfs:range xsd:int .
:nationality rdf:type owl:DatatypeProperty;
rdfs:domain :Person;
rdfs:range xsd:string .
:hasBirthPlace rdf:type owl:ObjectProperty;
rdfs:domain :Person;
rdfs:range :Place .
:address rdf:type owl:DatatypeProperty;
rdfs:domain :Place;
rdfs:range xsd:string .
:coordinate rdf:type owl:DatatypeProperty;
rdfs:domain :Place;
rdfs:range xsd:string .
本体映射主要用在融合多个独立的Ontology(Schema)。举个例子,张三自己构建了一个本体结构,其中定义了Person这样一个类来表示人;李四则在自己构建的本体中定义Human这个类来表示人。当我们融合这两个本体的时候,就可以用到OWL的本体映射词汇。如果没有OWL,我们将无法融合这些知识图谱。
<http://www.zhangsan.com/ontology/Person> rdf:type owl:Class .
<http://www.lisi.com/ontology/Human> rdf:type owl:Class .
<http://www.zhangsan.com/ontology/Person> owl:equivalentClass <http://www.lisi.com/ontology/Human> .
更多的OWL词汇和特性请参考[W3C官网文档](OWL Web Ontology Language Overview)。