参考图书: web3.0与Semantic Web编程(中文版) Web 3.0与Semantic Web编程 英文版 随书代码下载
一、信息建模
在语义Web上,信息的建模主要通过三种语言来完成:
- RDF(资源描述框架)——定义了底层的数据模型,并且为语义Web层次结构图中其他更高层次的复杂特性奠定了基础。
- RDF Schema(RDFS,RDF框架)
- OWL Web本体语言
在软件系统中,信息的建模尤为重要,信息建模中对现实世界对象及其属性的描述方式决定了系统所能执行的操作和系统所能解决的问题。支撑语义Web技术的信息模型的设计目标是为了使数据共享和互操作更加便捷。数据共享的问题可以分解为两个重要的子问题——语法的共享和语义的共享。语法的共享主要表现为对数据的访问,语义的共享主要表现为将信息整合到当前所使用系统的数据结构中。
1.1 语义网的信息模型——资源描述框架(RDF)
在语义网上,信息被表示成陈述断言集合(a set of assertions called statements),一个陈述可以看成是由“主语”“谓语”“宾语”组成的三元组。主语是描述对象,谓语描述主语和宾语之间的关系。以每个陈述的主语和宾语作为节点,以谓语为边,这种形式的声明自然而然地形成了一个有向图——这就是语义网所使用的数据模型,通常通过RDF的语言来对其进行形式化。
资源描述框架(RDF)是用于描述网络资源的 W3C 标准,可以通过菜鸟教程上面的介绍对RDF有更深入的了解。 节点:Resources and Literals RDF图中的节点构成陈述中的主语和宾语,节点主要有两种类型——资源和文字。资源可以表示任何可以被命名的东西,其名称采用了国际化资源标识符(Internationalized Resource Identifiers)的形式。 边:Predicates 谓语(Predicates)也称作属性,用来表示资源之间的关联。
1.2 RDF序列化——RDF Serializations
RDF是表示信息的强大工具,但是它是抽象的工具,虽然有助于人类进行分析,但是并不适用于应用程序进行信息交换。序列化提供了一种将抽象模型转换为具体格式的方法,从而使RDF切实可用于信息交换。目前,最常用的三种序列化格式为RDF/XML、Turtle(Terse RDF Triple Language)、N-triple。RDF/XML是一种表示RDF三元组的XML语法,它是RDF序列化的唯一标准交换语法。Turtle是精简版的RDF三元组语言,其可读性较好,是专门为RDF设计的。N-triple是Turtle的一种简化版本。
序列化格式 | 示例 |
---|---|
RDF/XML | |
Turtle | |
N-triple |
1.3 小试牛刀:使用Jena读取RDF序列化格式
import java.io.*;
import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdf.model.ModelFactory;
public class readRDF {
public static void main(String[] args) {
String inputFileName = null;
String outputFileName = null;
String inputFileFormat = null;
String outputFileFormat = null;
FileOutputStream outputStream = null;
FileInputStream inputStream = null;
if (args.length != 4) {
System.err.println("Usage: java RDFSerializer <input file> <output file> <input format> <output format>");
System.err.println("Valid format strings are: RDF/XML, N3, TURTLE, and N-TRIPLE");
return;
}
inputFileName = args[0];
outputFileName = args[1];
inputFileFormat = args[2];
outputFileFormat = args[3];
try {
inputStream = new FileInputStream(inputFileName);
outputStream = new FileOutputStream(outputFileName);
}
catch (FileNotFoundException e) {
System.err.println("'" + outputFileName + "' is an invalid file name");
return;
}
Model rdfModel = ModelFactory.createDefaultModel();
rdfModel.read(inputStream, null, inputFileFormat);
rdfModel.write(outputStream, outputFileFormat);
try {
outputStream.close();
}
catch (IOException e) {
System.err.println("Error writing to file");
return;
}
}
}
在这一长串的代码中,核心的代码其实只有3行,这3行代码实现了所有的RDF操作:
Model rdfModel = ModelFactory.createDefaultModel();
rdfModel.read(inputStream, null, inputFileFormat);
rdfModel.write(outputStream, outputFileFormat);
首先,Jena创建了一个空图rdfModel
,第二行使用流中的三元组填充该图,使用解析器就能读出给定的RDF格式。第三行将RDF图序列化为使用指定输出格式表达的流。
1.4 RDF中的空白节点
空白节点用于表示存在变量(existential variables)。 RDF提供了数据共享的高效结构,但是RDF只能支持二元谓词,一个RDF陈述只能表达两个资源之间的关系,而无法表示多个资源之间的关系。比如,如果想要使用RDF来表达生活在某个省某个城市的某个人,那么无法使用一条陈述将一个资源既关联到城市,又关联到省份——因为RDF只允许使用二元谓词。一种解决方案就是使用residensInCity
和residensInProvince
两个谓语来表示。但是,当一个人有两个或者多个居住地的时候,就无法确定哪个城市是从属于哪个州了。解决这一问题比较恰当的办法是创建一个表示住址的资源,将住址和人关联起来,然后将城市和州都和住址连接起来——这时,这个“住址”资源就可以作为空白节点。如果没有空白节点,RDF就会要求处于中介位置的住址节点拥有一个可解析的全球性名称,而空白节点并不需要提供这样的名称。 事实上,从知识图谱的角度来看,空白节点允许模糊知识的存在。
This might have been useful if you defined what having sufficient knowledge to give a proper URI was. A definition of what that is, or guidelines for that, might be the actual answer to the question. It seems to me that the key thing you don’t know about a blank node is whether it is the same node as another node in another RDF graph. This is what the URI gives it. It is unclear to me if you are supposed to know for sure that it is a different node than another blank node in the same RDF graph, though that would make sense. It seems to me the blank node only has local identity. ——EricS
1.5 RDF中的组织构造
RDF为信息分组提供了几种构造。 RDF Containers (RDF容器) RDF定义了3种资源类型,可以理解为资源的集合。
RDF容器 | 用法 |
---|---|
rdf:Bag | 用于表示无序的资源分组 |
rdf:Seq | 用于保存一个有序的集合 |
rdf:Alt | 类似于无序的集合,描述等价选项的集合 |
RDF Lists (RDF列表) RDF列表有助于组织资源集合,以这种方式组织,即使RDF图合并,资源集合也不会改变。
二、融入语义
在第一节中,介绍了RDF这样没有限制的描述信息的模型,虽然RDF有灵活的表达能力,但如果单独使用,则无法对隐藏在各种描述之后的含义或语义提供有力支持。因此,开发人员和用户需要一些能够表达富语义的描述概念和关系的方式,以便能够进行有效的信息交换。RDF Schema(RDFS)和OWL Web本体语言都提供了这样的功能。语义是将领域知识融入到RDF数据中的关键,它可以使信息描述更为丰富且更有意义。 语义网提出的初衷之一就是改善现有搜索引擎的搜索能力。目前的搜索引擎大多采用关键词匹配的方式,只能将用户查询和Internet上的文档内容进行基于语法的模式匹配,并通过一些添加的特性来改进性能和准确度。换句话说,基于关键字的搜索引擎并不是直接回答你的问题,而是通过关键字定位到相应的信息,让用户自行寻找答案。 为了能够向RDF加入恰当的语义,就需要以某种方式来定义一个预定义的词汇集,同时确定描述信息的语义。
2.1 词汇表、分类法和本体
概念 | 图示 | 说明 |
---|---|---|
词汇表 | 词汇表是预先定义好的术语的集合 | |
分类法 | 分类法通过添加术语之间的关系扩展了词汇表 | |
本体 | 本体使用预先定义好的、保留词汇表中的术语来定义具体领域上的概念和概念之间的关系。本体实际上既可以是一个词汇表或者分类法,也可以是其他的某种体系。它的特别之处在于其术语是一个富语义的、基于逻辑的形式化模型,用于描述某个知识领域。 |
语义网将模式语言和本体语言组合到一起来提供术语表、分类法和本体的功能。RDF Schema(RDFS)为RDF提供了一个特定的词汇表,该词汇表可以用于定义类和属性的分类法,以及对属性定义域和值域进行简单的描述。OWL Web本体语言为定义本体提供了一种富表达力的语言,能够捕捉领域知识和语义。 可以参考这篇文章:知识图谱里的知识表示:RDFs和OWL
2.2 本体简介
2.2.1 分布式知识
分布式知识:在认知逻辑中表达的一种认知事实。指在一组智能体中,所有成员的知识合取后所能推出的新知识。
为了在分布式知识模型中进行有效推理,需要提出两个非常重要的假设——开放世界假设(the open world assumption)和命名不唯一假设(the no unique names assumption)。 开放世界假设假设没有规定的陈述都是未知的。百度百科上的两个例子可以很好地理解开放世界假设和封闭世界假设中的不同推理结果:
陈述: "Mary"是"法国"的"公民"。
提问: Mary 是加拿大公民吗?
"封闭世界"(比如 SQL 或 XML)回答: 否。
"开放世界"回答: 不知道(Mary 可能有双重国籍)。
在封闭世界中,因为没有声明Mary是加拿大公民,所以回答为否(假);而在开放世界中,对于未知的陈述只能回答不知道。 命名不唯一假设是指除非有明确的说明,否则使用相同URI标识的资源是相同的。
2.2.2 本体的元素
参考文档:OWL 2 Web Ontology LanguageQuick Reference Guide (Second Edition) 参考文档:OWL2 Web本体语言快速参考指南
- 本体首部(Ontology Header)
本体首部是对本体本身的描述,一般会包含注释(comment)、标签(label)、版本信息和本体导入陈述。本体导入陈述可以确定当前的本体文档参考了其他哪些本体。
属性 | 作用 |
---|---|
owl:imports |
描述了导入该本体所参考的本体集合 |
owl:priorVersion owl:backwardCompatibleWith owl:incompatibleWith |
版本属性,为本体的版本管理奠定了基础。 |
- 标注(Annotations)
标注是使用标注属性来描述资源的陈述。下面列出了最常用的一些OWL中预定义的标注属性。
属性 | 作用 |
---|---|
rdfs:label |
主题资源的标签或简要描述。 |
rdfs:comment |
关于主题资源的评论。 |
owl:versionInfo |
关于主题本体或资源版本的信息。经常用于嵌入源代码控制元数据。 |
rdfs:seeAlso |
用于描述另一个可能保存关于同一主题资源信息的资源,不是很常用。 |
rdfs:isDefinedBy |
用于描述另一个定义当前主题资源的资源,同样不是很常用。 |
owl:AnnotationProperty |
定义补充的标注属性。 |
- 基本分类(Basic Classification)
在OWL中,有两个基本类——owl:Thing
和owl:Nothing
,所有的类都由这两个类派生而来。owl:Thing
表示所有物体的类,owl:Nothing
表示空类,是每个类的子类。
rdf:type
指明了资源的分类。在本体描述中,具有共同特征的事物被归为同一类(owl:Class
),类的成员(个体)同样可以通过rdf:type
来定义。例如:
@prefix ex: <http://example.org/>.
# Canine and Human are owl classes
ex:Canine rdf:type owl:Class.
ex:Human rdf:type owl:Class.
# Daisy is an instance of the class Canine
ex:Daisy rdf:type ex:Canine.
# Ryan is an instance of the class Human
ex:Ryan rdf:type ex:Human.
在上面这段描述中,首先rdf:type
和owl:Class
一起声明了ex:Canine
是一个类,然后通过rdf:type
声明个体ex:Daisy
是属于类ex:Canine
的成员。 类和类之间的继承/包含关系通过rdfs:subClassOf
来定义。Class1 rdfs:subClassOf Class2
意味着:
- 属性(Properties)
OWL属性用于确立资源之间的关系。OWL属性的两个基本类是owl:ObjectProperty
(表示左右个体之间关系的类)和owl:DatatypeProperty
(所有个体和文字值之间关系的类)。并且,可以使用rdfs:domain
和rdfs:range
描述属性的定义域和值域。 OWL还提供了多种描述属性的方式:
属性 | 说明 |
---|---|
rdfs:subPropertyOf |
对属性进行分类 |
owl:topObjectProperty |
顶属性,表示最一般的属性。作用是将所有可能的个体对连接起来。 |
owl:topDataProperty |
顶属性,表示最一般的属性。作用是将所有可能的个体和所有的文字连接起来。 |
owl:bottomObjectProperty |
底属性,表示最特殊的属性。作用是不连接任何个体对。 |
owl:bottomDataProperty |
底属性,表示最特殊的属性。作用是不连接任何个体和任何文字。 |
- 描述属性
OWL提供了很多描述属性(向属性添加语义)的方式。 (1)逆属性——owl:inverseOf
Property1 owl:inverseOf Property2
表示:
- 属性
Property1
描述的关系恰好为Property2
的逆,例如haschild
和hasparent
; - 如果存在陈述
(Entity1 Property1 Entity2)
,那么一定存在陈述(Entity2 Property2 Entity1)
; - 如果存在陈述
(Entity2 Property1 Entity1)
,那么一定存在陈述(Entity1 Property2 Entity2)
。
(2) 不相交属性 两个属性property1
和property2
不相交是指不存在这样的两条陈述:主语和宾语都一样,但是第一条的谓语是property1
,而第二条的谓语是property2
。对于不相交属性的声明有两种方式。第一种是构造一个在两个属性之间的确定关系——owl:propertyDisjointWith
:
@prefix ex: <http://example.org/>.
...
ex:hasMother rdf:type owl:ObjectProperty.
ex:hasFather rdf:type owl:ObjectProperty.
ex:hasMother owl:propertyDisjointWith ex:hasFather.
第二种是构造一种集合,声明集合中的元素均不相交——owl:AllDisjointProperties
:
@prefix ex: <http://example.org/>.
...
ex:hasMother rdf:type owl:ObjectProperty.
ex:hasFather rdf:type owl:ObjectProperty.
[] rdf:type owl:AllDisjointProperties;
owl:members (
ex:hasMother
ex:hasFather
).
(3) 属性链(Property Chains) OWL 2引入了属性链的构造,其思想是使用一个由属性构成的链将一组资源链接起来。例如:
@prefix ex: <http://example.org/>.
...
# Define each of the relationships
ex:hasUncle rdf:type owl:ObjectProperty.
ex:hasParent rdf:type owl:ObjectProperty.
ex:hasBrother rdf:type owl:ObjectProperty.
# Describe the uncle relationship situation
exRyan ex:hasParent ex:Jean.
ex:Jean rdf:type ex:Human;
ex:hasBrother ex:Doug.
# Define that the property chain is a subproperty of the uncle relationship
[] rdfs:subPropertyOf ex:hasUncle;
owl:propertyChain (
ex:hasParent
ex:hasBrother
).
属性链可以是任意长度的。但是需要注意的是,属性链仅仅能作为子属性关系的一部分来使用,不能被应用于任何其他的属性关系中(如逆属性、等价关系和不相交关系等)。 (4)对称属性、自反属性和传递属性
(5)键(Keys) 描述了个体和属性之间的关系,从而使属性值能够唯一确定个体。
- 数据类型(Datatypes)
数值类型的约束:
- 属性约束(Value Restrictions)
值约束:
基数约束:
受限基数约束:
2.3 常见的基础本体(Foundational Ontology)
当重用或者扩展一个本体时,通常需要某个本体作为特定领域本体的基础,这样的一个作为基础的本体称作基础本体(Foundational Ontology)。基础本体创建了一种环境,在这种环境中,不同知识领域共享公共的根概念集合,能够从宽度和特殊性上充实本体,这对于每个具体应用程序来说都非常重要。这样,多个领域就可以在本体层上实现信息共享,而不管每个本体是如何扩展的。 常见的基础本体:
- Basic Formal Ontology (BFO)
- Cyc and OpenCyc
- Descriptive Ontology for Linguistic and Cognitive Engineering
- (DOLCE)
- Dublin Core Metadata Initiative
- Friend of a Friend (FOAF)
- GeoRSS
- Suggested Upper Merged Ontology (SUMO)
- OWL Time
三、现实世界中的知识建模
前面提到的RDF是数据模型,OWL是本体语言,是描述语义和定义知识模型的工具。因此,需要一个集成组件的框架来提供RDF信息的存储和检索功能,以及对OWL语义的解释。 语义Web框架有多种不同的用途,包括数据库转换和集成、领域知识建模、验证、分析,甚至还涉及到信息的存储和检索。对于一般知识库来说,语义Web框架通常包含3种组件:存储组件(STORAGE)、访问组件(ACCESS)和推理(INFERENCE)组件。
3.1 常见语义Web程序设计框架:
框架 | 描述 |
---|---|
4Suite | 一款开源的、面向python的XML和RDF处理程序库。 |
Jena | jena是一个java 的API,用来支持语义网的有关应用,学习jena需要了解XML 、RDF、 Ontology、OWL等方面的知识。这本书主要是基于Jena进行程序设计的。 |
Sesame | 广泛使用的RDF框架和服务器,提供了SPARQL结构和一个HTTP服务器接口。该框架中包含了多种存储机制和推理机制,而且支持加入自定义机制。 |
OWL API | 使用Java编写的用于OWL的API工具,提供基于OWL2函数语法构建的OWL API,其中包含一个可用于多种推理机的通用接口。 |
RAP RDF API | RAP是一款开源的RDF API 和软件套件,用于在PHP环境下存储、查询和操作RDF。 |
Redland | 使用C语言编写的RDF程序集合,并且有使用多种其他语言开发的版本,提供了RDF API、解析器和查询接口。 |
LinqToRDF | 一种面向.NET的语义WEB框架,基于微软的语言级集成查询(LINQ)框架(一种与语言无关的查询和数据处理系统)。 |
3.2 RDF存储组件实现
很多语义Web框架都允许插入自己的RDF存储组件,如Jena和Sesame。下面是常用的RDF存储方式或者项目:
存储实现 | 说明 |
---|---|
AllegroGraph | 有免费的精简版和付费的完整版。有Java和Lisp语言两种版本。提供SPARQL接口和基于RDFS的推理。 |
Mulgara | 开源的、使用JAVA编写的RDF存储,提供了一个SPARQL查询处理器,其前身是Kowari项目。 |
OpenLink Virtuoso | 提供了基于关系数据库的RDF存储,有开源版本也有商业版本,支持将SPARQL嵌入到SQL中,将其作为访问存储于知识库找那个的RDF数据的方法。 |
Oracle 11g | 目前相关信息较少。 |
OWLIM | 支持对RDFS和OWL子集的推理。其提供的工具为GraphDB。 |
Parliament | 基于C++的RDF存储实现,采用了高效的基于磁盘的存储,但是推理功能比较有限。 |
3.3 RDF检索组件实现
大多数语义Web框架都提供了SPARQL接口或者API以实现对知识库信息的访问。目前并没有其他比较好的检索组件。
3.4 RDF推理组件实现——选择正确的推理方法
推理引擎是能够基于知识库中已有的内容推理出新信息的系统。很多语义网框架都采用基于规则的推理引擎来执行推理。这些引擎通过将知识库中所包含的断言和一个逻辑规则集合组合起来推导断言或者执行某些动作。规则包含两个部分——规则的条件和规则的结论,可以构成一条if-then陈述。 基于规则的推理机中执行推理主要有两种形式——正向链接推理(又称为数据驱动推理)和反向链接推理(又称为目标驱动推理)。将这两种推理方式组合在一起,就是混合推理。有两张图可以表示正向链接推理和反向链接推理之间的区别。
正向链接推理 | 反向链接推理 |
---|---|
从图中可以看到,在正向链接推理过程中,推理从已有事实出发,通过已有事实推出新知识。反向链接推理想要确定知识库中是否包含事实10(即从结论出发),如果反向推理过程中需要事实不满足,则说明不包含事实10。 常见的推理引擎如下:
推理引擎 | 说明 |
---|---|
FaCT++ | 基于C++的开源推理机,支持OWL DL的一个较大的子集。 |
Hermit | 基于JAVA的OWL推理机,可以将其集成到protege或者OWL API的JAVA应用程序中使用。 |
KAON2 | 是一款基于JAVA的框架,主要面向OWL DL本体方面的操作和推理,它支持OWL DL的一个较大子集。 |
Pellet | 一款开源的基于JAVA的OWL DL 推理引擎,能够支持大多数OWL构造,包括OWL2构造的引入。这是一款成熟的推理机,有着良好的客户服务支持,并且能够支持OWL的最新特性。 Github项目:Pellet: An Open Source OWL DL reasoner for Java |
RacerPro | 一款商用推理机。 |
Vampire | 一阶逻辑公式证明器,需要获取商业证明才能使用。 |