语义网和关联数据(浅层)知识梳理

renyuneyun 2023年06月19日(周一) 1 mins

很早我就听说过语义网(Semantic Web;简称SW)这个概念,知道KDE(4)的Nepomuk引擎是基于SW技术构建的,再后来的Gnome Tracker也是。但直到读博之后才开始更经常接触相关知识,意识到它(的技术)现在更常出现的名称是关联数据(Linked Data;简称LD)或知识图谱(Knowledge Graph);而网络上其实也有很多SW知识库实例,如DBpediaWikidata这两个基于维基百科数据的相似但不同的项目。但由于相关知识很多,错综复杂,且我又不是专门做这个领域的,所以始终处于半懂不懂的状态。

不过好在我确是喜欢它的理念,于是在不断接触之下,尤其是加入了Tim Berners-Lee所在的EWADA项目之后,我现在终于建立起了一个相对明确的认识。虽然肯定还不完善,但也足以整理下来,帮助后来者(比如读了我之前写的《Solid——简介与体验》《论Web3.0和Web3》后进入Solid世界,或只是想了解语义网络的人)快速建立认识。

本文不会涉及特别具体的定义等,比如具体的语法。如果想要深入,请点击链接或善用搜索引擎去了解学习。

由于本文的性质,其内容不可避免会受我目前认识的局限;而我也会尽量随着我的认识的深入而不断更新。行文也比较散,想到什么写什么,没有按常规的结构进行,还请担待。

语义网、关联数据以及知识图谱——一点背景和历史

语义网(络)最初是为了提高Web的机器可读性以带来(机器/程序/Agent的)操作性而提出的对Web(万维网)的改进。虽然似乎并非是Tim最早提出,但Tim的确是支持者之一,而且也有很多相关贡献。

在此之上,语义网相关研究使用以及提出了大量的技术和方案,最典型的例如:

  • 描述手段RDF (Resource Description Framework)

    • 一种(或者说一类)很易理解和使用的结构化描述数据的方式

    • 本质上将数据组织成「图」结构

  • 本体(ontology)定义OWL (Web Ontology Language)

    • 定义类、属性、类的信息等,以供RDF文档使用

    • 某种意义上也算是描述了RDF文档节点的「形状」,但不是用来检验RDF文档的

  • 形状描述SHACLShEx

    • 更具体的描述形状的方案,且专门设计用来检验RDF文档是否合规
  • 推理规则SWRL(Semantic Web Rule Language)OWL的DL(Description Logic)

    • 描述如何从RDF文档中已有的信息自动推理出更多信息

    • 以逻辑为基础,具有多种理论保证和特点

  • 查询语言SPARQL

    • 类似SQL的易用的查询RDF文档(或者叫知识库)的语言
  • 给HTML增添语义的RDFa

    • 使得网页可以直接内嵌语义,方便Agent使用
  • 知识库或SPARQL节点,如Apache Jena

这一切研究本质上都是为了两个目的服务:1. 如何更好的组织和验证知识库;2.如何更好地使用知识库中的数据。研究者一般都不会忘掉语义网的大目标。不过出于种种原因,语义网的推广并不理想。于是后来,语义网这个词逐渐让位给了更直接的概念,即关联数据(Linked Data)。

这个「种种原因」的确很多,有技术上的,有实践上的,也有商业上的。我个人觉得商业上的因素最重,毕竟如果我们回头看看2004年以后的网络发展,整个互联网都是在逐步越来越封闭:先是还在基于万维网的Web 2.0平台化;然后是随着iPhone而泛滥的「App」这一理念,逐步删除任何互操作性的封闭平台。整个发展状况都和语义网所追求的互操作性互联性背道而驰,但偏偏这样又带来大量利润。

之所以关联数据(LD)可以作为语义网(SW)的替代用词,本质上其实是因为LD本身就是对SW最核心技术和标准的重新打包,但淡化了「努力全盘加装在现有Web上」这个目标。RDF本质上就是一个图,每个数据都是图上的一个节点,那么各个数据(节点)之间本身就是相互关联/链接的。LD就是强调要重视数据之间的这种关联性,使用RDF等一系列技术,而不是使用无关联性的纯文本,或是自行重新发明轮子造的弱化仿制版RDF。而且由于RDF中节点的ID本身是一个URI或URN,所以LD和Web的关系也没有斩断,而是可以静待等待时机成熟卷土重来。Tim的SoLiD(Social Linked Data)其实就是有感于平台垄断化的泛滥,而尝试使用LD来重建Web这个目标去的项目(参见《论Web3.0和Web3》)。

与此同时或稍晚一点,Google开始使用知识图谱(Knowledge Graph)这一名称来称呼其所搭建的(基于RDF的)知识库,以用来支持其搜索或AI/ML(尤其是NLP)技术。而随着AI/ML技术讨论的流行,知识图谱逐渐成为了绝大多数人首先乃至唯一听说过的SW和LD技术实例和用法。

「知识图谱」这个翻译在NLP或感知类AI的语境下没什么问题,但在理解概念时会让人的注意力有所偏差,尤其是其中的「谱」字比较误导人。其技术(及英文原文)的核心在于这里的「知识」是以「图」的形式存储/描述的,以区别于(例如)表格状的关系型数据库。其实在这个词广为使用前,从传统AI/逻辑而来的「知识库」应当是更常用的一个词。

虽说知识图谱并不算是和语义网的目的相悖,但似乎它用到的主要是RDF的图结构以及SPARQL等的查询功能,或许再加上个OWL或推理,至于其他内容则不太在乎——毕竟和他们的ML研究关系不大。不过如果你接触过知识图谱,那么其实你已经算是稍微接触了SW了。

但同时经过上面的梳理可以看到,语义网的目标和研究以及技术应用远远大于它。不要把一种实例当成唯一作用。

RDF和其他技术的关系

RDF可以说是SW最核心的技术。当然这句话不是说RDF必须是核心或者RDF就是完美的方案,而是对现状的一个总结。虽然人们讨论过RDF的种种问题,但整体而言它是相当优秀的方案,足以支撑其上的一系列研究。

RDF的要点就是使用subject predicate object主语 谓语 宾语)这样的三元组来描述事物,并集合大量的三元组来形成数据/知识库/知识图谱。在此之外,RDF还引入前缀(prefix)的概念,一是简化书写,二是和OWL相连接:一般而言我们预期前缀就是一个ontology。

这个「前缀」和「命名空间」(namespace)的概念很像。但在RDF标准中,前缀并不要求一定是个有效定义(比如一个OWL文档),而可以是任意东西;而命名空间一般都是一个有效的定义(域)。

当然在此之外,还有一些变体,用来解决特定的需求。比如在s p o的三元组上增加图(graph)形成四元组,用来进一步框定三元组的来源,以表达语义或优化推理。

RDF是一个理论框架,但实际使用则需要有实际的序列化表示。这里的选项有很多,而且一般都互相等价(除了那些支持额外特性的,这里不讨论),比较典型的例如:

  • RDF/XML语法:核心标准,理论上所有框架都支持,但不够适合人读写(XML写起来太费事);

  • Turtle语法:简练,适合人读写;

  • JSON-LD语法:特化的JSON,也许更适合网络使用。

SW和LD的许多相关技术都是基于RDF构建的,比如前面提到的那些:

  • OWL的作用是辅助描述RDF资源,而且同时OWL也序列化成RDF文档(某种很奇妙的互指涉/间接递归关系);

  • SHACL和ShEx都是用来描述RDF图的形状的;

  • SPARQL是用来查询RDF的知识库的;

  • SWRL或OWL DL描述如何从已有RDF中生成/演绎新的知识/信息。

这里的「基于」同时代表两方面的含义:1. 围绕、扩展及使用RDF的功能;2. 其本身表示成RDF。并不是每一项技术都同时去做这两面,但的确有不少这样的例子(如OWL、SHACL等;参考后文)。

Turtle、N3和OWL

如前面所说,Turtle是一种RDF的序列化形式,或者也可以称为一种语言。它的核心特点就是简洁,对人类友好。

N3也是一种语言,粗看之下和Turtle差不多。但N3和Turtle有很大不同,最主要的在于N3不只是序列化RDF,而还包含了其他内容,尤其是关于推理和查询的支持——你可以直接在N3中描写推理推则或者书写查询,且N3有对应的推理器;而RDF只是数据,没有别的。

我并不完全确定Turtle和N3谁先被提出,但Turtle的确可以被看作是N3的RDF描述部分的子集,或者说N3是对Turtle的扩展。

N3的另一特点是它支持标准/核心RDF之外的一些内容,比如对图的标注(类似RDF* (RDF Star),但语法不同),比如它特定的built-in的特定语法及语义(如log:collectAllIn临时的封闭世界假设查询,或是提供linear logic推理)。

需要注意的是,N3的推理规则需要全部在N3中写出,不会「继承」其他来源的推理规则。例如由于OWL是有效的RDF文档,N3中也可以引用OWL的概念,但并不自动具有OWL的推理定义,需要自行书写(或导入/粘贴)。

OWL、SHACL以及数据检查

OWL允许描述「类」和「属性」的信息,比如某个类是另一个类的子类,某个类拥有几个什么属性,以及它们的对象类型是什么,某个属性可以用在什么类上,等等。不同的研究者也开发了不同的OWL推理器,比如HermiT,可以用来推断类或个体(individual)的等价性,个体的类归属等。这样,OWL可以用来刻划多个不同定义之间的「同义」性,通过推理器提供互操作性(interoperability)。但是,一个很常见的误解(我就有过)是以为OWL可以检查某个知识库是否「有效」,即是否符合「类的定义」。

实际上,OWL基本上不能用来做这些检查。主要原因是OWL所基于的「开放世界假设」。

「开放世界假设」认为「当前知识库中的数据未必是完整的」。换句话说,如果当前知识库中类A的实例a只拥有一个pb属性,但A的定义中有两个pb属性,那么OWL会认为这是合法的数据,因为「少的那个pb属性可能是存在的,只不过不在当前知识库中」。

如果想进行这种检查,则需要使用SHACL。SHACL基于的是「封闭世界假设」,就是设计来检查数据的。另外还有个ShEx,也是用来描述形状的,也可以用来检查。我暂时没有详细了解过,不知道它和SHACL的关系是什么。

我还接触并使用过一个有意思的Python库,叫Owlready。它的主要功能是让Python的类和实例与OWL的类和个体之间相互链接,用法之一是从OWL的类定义生成(导入成)Python的类,很有意思。原则上说,OWL的功能比典型的OOP的类与实例的概念强大,所以里边必然有一些有意思的事情(包含但不限于推理)。整体而言,我很喜欢它的理念,而且希望有人可以开发「编译器」,来将OWL的类定义转成其他(尤其是编译型)语言的类定义,这样跨语言的时候就方便很多。

推理规则描述语言

在SW的世界中有许多的推理规则的描述语言,各不相同,这让我一度十分迷惑。虽然现在也没有完全弄懂,但至少有了一些认识。

好多语言,为什么?

在讨论这些语言的关系之前,首先我们要了解:为什么会有这些不同的语言?是因为研究人员或开发人员闲得慌么?

答案其实很简单:因为它们的能力各不相同,所以不得不有许多不同的语言。

下面一节会简单讨论几个我了解的例子,尤其是OWL、N3和Datalog。

于是很自然的一个衍生问题是:为什么不创建一个涵盖全部的语言?

答案很明确,但不一定直观:因为它们的一些特质互不兼容,如果全部支持,那么推理复杂度将不可接受。

这背后的原因则根植于不同的逻辑系统、不同的任务以及不同的复杂度。它们要么有严格的证明,要么有长期无法打破的猜测,并不是靠蛮力能解决的问题。

一个基本认识:越简单的越快,越复杂的越慢。

一些常见语言

说是「常见」语言,其实是我所知道的语言——虽然我所知道的肯定不全面,但既然我并不是资深人士,那么我能接触到的应当算是常见吧:

  • OWL(Web Ontology Language):以Description Logic为基的语言,以描述性的方式书写(/使用定义内的)规则

    • 开放世界假设

    • 有OWL (1)和OWL 2两个版本,都有自己的不同profile,但含义不同(参考阅读

      • OWL 2应当比OWL (1)更好用,各个意义上
    • OWL 2的三个Profile分别基于不同的DL,支持不同的功能,为不同的任务优化

  • SWRL(Semantic Web Rule Language):基于霍恩子句(Horn Clause)的语言,似乎比OWL (1)功能强大一点

    • 开放世界假设

    • 虽然叫「语义网络规则语言」,但它并不是「全语义网的标准」

  • N3:带查询的规则描述语言,大约是简化版的谓词逻辑/一阶逻辑

    • 开放世界假设,但部分语法支持临时的封闭世界假设
  • DatalogRDFox变体):类似Prolog的基于霍恩子句的语言,另支持内置语法和关键词

    • 封闭世界假设,使用negation-as-failure
  • SPARQL:本身是查询语言,但查询条件中可以实质上进行一定推理

    • 大约算是封闭世界假设

我的认识中,OWL是这些不同语言中推理功能最少的,SWRL比它稍微强一点。不过我没有完全弄明白各个Profile的实际能力区别,也没仔细研究过SWRL,所以无法具体比较。

N3完全覆盖了OWL和SWRL的能力,并且提供了更多的功能。

而Datalog则是另一种思路,尤其是它抛弃了开放世界假设,又基于Prolog的语法结构,所以理应有更强大的推理能力(指「可以表达的推理规则」及按这些规则推出的结论),尤其是可以表达「否」。

SPARQL不完全归属这个类别(见下一节),但使用它也可以从实质上进行推理,即从知识库中得出知识库中不存在的信息。它也支持表达「或」,以及表达「非」(似乎也是negation as failure)。其表达能力超过SWRL和OWL,也许可以和Datalog比一比。我不确定SPARQL和Datalog两者谁更强大,但仅以描述的易读性来看,Datalog更好读。

查询数据

前面主要讨论的是数据本身的事情:表示是什么,理念是什么,结构是什么,如何检查等等。但我们有数据的目的是为了使用数据,于是SW研究参考关系型数据库的SQL开发了SPARQL来查询RDF知识库。

SPARQL类似SQL,通过描述性的查询来从知识库中提取数据。SPARQL的「描述」是基于「模式匹配(pattern matching)」的,即从知识库中寻找和描述中相符合的三元组。

除了查询以外,类似SQL支持增删改查,SPARQL当然也支持修改知识库,且(由于图和RDF的特性)选项更丰富。在此之外,SPARQL还支持CONSTRUCT,用来直接从查询结果构建一个新的图(并返回,而非插入到知识库中)。另外,还记得我们前面提到的「开放世界假设」么?SPARQL也支持同时从多个地方查询,甚至是各执行一部分查询(即Federated Query,互联查询)。

SPARQL的功能由简单到复杂涵盖很多,我也不确定什么教程最合适,毕竟我并没有完全跟着教程学。我当时学习是找了个基础教程(现在不记得是谁了),然后就不断的搜相关功能如何实现,以及参考官方文档。所以其实迄今为止我也不算完全掌握了它,而只是会用以及熟悉它。

速度,还有我是否需要担心速度?

本节涉及我不够了解纯熟的理念,请谨慎阅读。

我印象中看到过Nepomuk被抛弃的一部分原因是项目经费不再拨款了,另一部分原因则是它的速度实在是有问题。

而且这也符合一般的感觉,那就是SW的工具都存在速度问题。虽然里面有业界使用人数少所以优化有限的因素,但始终有一个问题萦绕在心头,那就是:是不是SW有理论限制,速度无法上去?

答案其实是否定的。现在有许多人在改进其速度,尤其以RDFox为代表的知识库+推理引擎的速度更是数量级地优于Jena。

当然,这并不是说理论复杂度上限就不存在了。其实仔细想想,这个担心本身很有意思。SW的世界(比如OWL的DL)经常强调逻辑系统的选择及带来的速度,所以看SW的人也会担心这个问题。但事实上,这可以说是某种幸存者偏差(?应该有个更好的词?但我想不起来):如果你用同样的思维去考虑其他系统(比如编程语言),那么你更应该担心它们的复杂度是否爆表。

最经典的就是程序中的「停机问题」:给定一段程序,(在不执行的情况下通过分析代码)判定它何时会结束。我们已经知道,所有的图灵机(也就意味着所有的编程语言)都无法解决停机问题。换句话说,如果从理论上思考,在解决某一个推理问题(如「停机问题」所代表的「何时程序会结束」)时,它们的复杂度是无穷大。

这个复杂度和DL们经常在乎的复杂度根本就不可比,但似乎鲜有人因为在乎它而觉得所有程序都存在速度极差的问题。同理,也不应该因为SW相关研究因为明确说了一些推理工具的理论复杂度上限很高,而认为它就比不说明复杂度的东西更慢。

启航

本文从不同角度梳理了一些语义网和关联数据的相关知识,希望对新来者有所帮助。

当然如果你对SW和LD感兴趣,那么一个很自然的问题是:我该从哪里开始?

最简单的回答是:你需要用什么,就从哪开始。

而如果你暂时没有使用需求,而主要是对技术感兴趣,你可以去试试Wikidata的SPARQL接口,例如参考Wikibooks上的SPARQL一篇。这样你可以学习SPARQL,可以直接使用一个编辑器和端点,可以有实际的数据集。你大概也会对RDF可视化(即其图结构的可视化)感兴趣,例如试试这个工具。而RDF本身,不妨试试RDF各种表示的转换工具,比如:isSemantic的RDF转换器,或如果你更倾向于JSON也可以试试JSON-LD转换器。或者如果你暂时没特别确定的需求,那么也可以先用着Solid(比如参考《Solid——简介与体验》),在使用中很容易就接触到相关东西,逐渐学习。

但说实话,你应该已经看出来了,这个问题其实也不好回答。这是因为SW和LD相关技术比较散,多是研究性而非商业性的,所以「推广」方面存在一些门槛/障碍。这的确是个问题,希望未来有所改进。出于相似的原因,Tim为Solid成立了Inrupt,希望可以让推广更容易一些——的确有用,但并没有如魔法般的效果,一些事情还是需要水磨工夫。


Related posts:

您可以在Hypothesis上的該群組內進行評論,或使用下面的Disqus評論。