SKOS 相关

转自http://www.52ml.net/1560.html

 

第三章:受控词表的语义化表示

本章主要讲述如何采用SKOS对词表进行语义化表示。

3.1:语义网及其相关技术

Web 自诞生以来,到目前为止总共经历了两个阶段:Web 1.0和Web 2.0 。关于web 1.0与web 2.0的划分,起源于出版社经营者O’Reilly和MediaLive International之间的一场头脑风暴论坛。身为互联网先驱和O’Reilly副总裁,Dale Dougherty指出:“伴随着令人激动的新程序和新网站间惊人的规律性,互联网不仅远没有“崩溃”,甚至比以往更重要。更进一步说,那些得以活过泡沫破裂的公司之间似乎拥有某种相同点。难道是互联网泡沫破裂标志着互联网的一个转折点,因而导致了诸如“Web 2.0”这种运动?笔者同意这种说法,“Web 2.0”的概念由此诞生了。” Tim O’Reilly 撰文指出了Web 1.0和Web 2.0的区别:

wps_clip_image-11577

Web 1.0与Web 2.0的争论,起源于2001年的互联网泡沫。这场泡沫,导致了当时许多科技公司的倒闭,也让人们开始去思考互联网、Web等技术的未来发展。有了1.0和2.0之

分,那有没有Web 3.0呢?

2001年,Tim Berners-Lee等人人发表了《The Semantic Web》,这是Berners-Lee在1998年提出Semantic Web的想法之后,首次正式明确了Semantic Web的概念,也标志着Semantic Web的诞生。在某种程度上,Semantic Web被称为Web 3.0 。Semantic Web的核心是:通过给万维网上的文档 (如: HTML)添加能够被计算机所理解的语义(Meta data),从而使整个互联网成为一个通用的信息交换媒介。语义万维网通过使用标准、置标语言和相关的处理工具来扩展万维网的能力。

Berners-Lee提出了语义网堆栈模型,如下图:

图片2

该堆栈总分七层,分别为:URI层,XML层,RDF层,本体层,逻辑层,证明层和置信层。

Berners-Lee认为,可以用URI作为每一个资源的唯一标识符,借鉴XML的语法,采用资源描述框架(RDF)对信息和元数据进行描述。通过本体的描述,使得RDF里描述的每一个资源都具有可被机器读取和识别的意义。通过逻辑层,来对资源描述进行约束以及推理出新的知识。再通过证明层,证明和解释逻辑层推理的意义。而置信层则是对可信数据、服务和代理的认证。

(1)RDF

七层模型里,RDF是Semantic Web的基石。RDF,即Resources Description Framework,是由W3C开发的用于描述Web上的资源的一门语言标准。从开发之初,RDF就以机器可读可理解为目标,同时也让人更好理解其描述信息的意义。RDF有几个关键原则,一是三元组,如下图:

wps_clip_image-11874

Subject是主语,Predicate是谓语,亦有用property表示的,Object是宾语。主谓宾结合,具有极强的信息描述能力,能很好描述资源间的联系,从而达到部分语义。

多个三元组,则构成了图数据模型,这是RDF的第二个关键原则,如下图:

wps_clip_image-11929

这个图描述了Eric Miller这个人,全名是Eric Miller,邮箱是em@w3.org,最关键的是type,即这个图所描述的是一个人。

通过上图,笔者也可以看出RDF的第三个关键原则:以URI作为资源的唯一标识符。这样就可以确保每一个在Web上的资源都是唯一的,同时,如果该资源是Web上可获取的,那么笔者可以立刻获取到该资源。

RDF并不是一种格式,它是一门语言,只定义了几个关键的标准。具体的实现格式上,RDF有多种实现形式,如RDF/XML,N3,N-Triple等近十种格式。W3C官方推荐的标准是RDF/XML,上图所描述的Eric Miller的RDF/XML如下:

<?xml version="1.0"?>

<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"

             xmlns:contact="http://www.w3.org/2000/10/swap/pim/contact#">

<contact:Person rdf:about="http://www.w3.org/People/EM/contact#me">

    <contact:fullName>Eric Miller</contact:fullName>

    <contact:mailbox rdf:resource="mailto:em@w3.org"/>

    <contact:personalTitle>Dr.</contact:personalTitle>

  </contact:Person>

</rdf:RDF>

而N3格式则如下:

@prefix rdf:     <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .

@prefix contact:  <http://www.w3.org/2000/10/swap/pim/contact#> .

<http://www.w3.org/People/EM/contact#me>

a        contact:Person ;

      contact:fullName  "Eric Miller" ;

      contact:mailbox  <mailto:em@w3.org> ;

      contact:personalTitle "Dr." .

每种格式,均有其利弊,在后面的内容中将有详细叙述。

上面的RDF/XML格式,看上去和XML区别不大,那为什么不用XML而要用RDF呢?对此,Berners-Lee特意撰文回答了这些疑问。文中伯纳斯·李提到,XML对数据模型的描述,由于未采用三元组形式,描述同样的内容,可能出现不同的形式。比如上面的Eric Miller,用XML描述,可能会有:

<People>

<fullName>Eric Miller</fullName>

    <title>Dr</title>

</People>

或者

<People>

<detail>

<name>

     <fullName>Eric Miller</fullName>

</name>

<title>Dr</title>

    </detail>

<People>

这两种形式描述的都是同样的信息,却没有采用固定的模型。Dr这个title,到底是属于detail的呢,还是属于People的呢?除非你去查看XML Schema,否则无法判断。而RDF采用固定的三元组模型,则很好得解决了这个问题。无固定模型,导致的结果就是机器无法解析出意义,也就达不到机器可读可理解的地步了。

表面上看,没有固定模型的XML似乎更加灵活。但实际上,XML是一种具有Schema的语言,即和数据库里的表类似,要解析出两个元素的意义,需要根据Schema去解析才行。而RDF实际上则灵活多了,它是一种Schema less的语言,与当今流行的NoSql有点儿类似(此处注意RDF Schema与XML Schema的意义完全不同,RDF Schema是用于解释每一个资源的意义的)。既然是Schema less,两个RDF文档无需进行任何额外操作,存放在一起就可以无缝集成。另外,在XML里存放的资源,如果笔者要提取它,首先要找到这个XML,然后才能从中提取出资源信息来。而由于使用URI来标识所有的资源,在RDF中,一个资源的获取与其所在的RDF文档几乎没有关系,笔者只根据URI去查找数据。

在伯纳斯·李的设想中,未来互联网上所有的信息都将用RDF描述,机器不仅能读取这些信息,而且还能理解这些信息。因此,固定的三元组模型和URI做唯一标识符就显得非常重要了。

2)本体

Semantic Web的另一个关键要素是本体,目前的本体语言有OWL和RDFS,前者比较完备,也比较复杂。另外,需要注意的是,Semantic Web的本体也是RDF。也就是说,RDF是一种自我描述的语言,可以自我解释。这一点上,与XML Schema是一样的。

为什么RDF是机器可理解的?之前已经提到的一个关键因素是三元组,而另一个最重要的元素则是本体。实际上,RDF可以说是一门语言,兼具面向对象和逻辑编程的语言,以面向对象为主。笔者来看一下W3C官方文档里对skos:Concept的解释:“skos:Concept is an instance of owl:Class. ”,从面向对象编程来看这句话,意思就很明白了:owl:Class定义了一个类,而skos:Concept则是它的一个实例。然而,再来看一个例子:“<MyConcept> rdf:type skos:Concept .”,这里笔者定义了一个MyConcept,也就是一个skos:Concept的实例。这里无法理解为什么W3C的官方把skos:Concept定义为owl:Class的实例,依我看,其应该是owl:Class的子类才对,类似于Java里所有的类都继承于Object。这里暂且不深究这个问题。RDF构建时,就希望能用来描述世界上的资源,以面向对象的方式,则能很好地描述现实世界。如果学习过面向对象编程,就能从上面提到的几点明白RDF的可理解是什么回事了。Semantic Web是用本体来构建了许多的类,然后实例化这些类来描述现实的世界。当解析器遇到一个实例对象的时候,根据URI查找到类型定义,从而理解出这个实例对象是什么类型,比如描述的是只猫呢还是一只狗呢。

综上所述,RDF与本体在本质上,构建了一门语言,有语法,有关键词,有解释器。以主谓宾为三元组的模型使得其即具有固定的解析模式,同时主谓宾模式描述能力极强,能很好地描述现实世界。以URI为标识符,使得每一个实例,每一个资源都能具有唯一性的同时,实现了分布式的功能。即使两个东西不在一块,通过URI就能把他们链接到一起。而本体利用面向对象的特点,实现了资源描述的语义化,同时通过逻辑编程,达到逻辑推演的功能。

(3)SKOS

自1998年以来,图书情报界开始了对网络知识组织系统(Networked Knowledge Organization System,简称NKOS)的研究。随着语义网技术的出现,一些组织和机构开始采用语义格式对传统词表进行描述。联合国粮农组织(FAO)采用用OWL语言对多语言农业词表AGROVOC进行描述;深圳大学的曾新红等人采用OWL语言对《中国分类主题词表》进行描述。但OWL过于复杂,不适合受控词表。 2005年,W3C发布了基于RDFS/OWL建模的SKOS,即简单知识组织系统描述语言。为了更好更直观叙述SKOS,这里先给出一段简短的SKOS数据,这是汉语主题词表里关于“崩裂反应”的描述:

<rdf:RDF

    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"

    xmlns:skos="http://www.w3.org/2004/02/skos/core#"

    xmlns:ex="http://www.skos.shahuwang.com/skos/extention#"

    xmlns:dc="http://purl.org/dc/terms/"

    xmlns:xsd="http://www.w3.org/2001/XMLSchema#"

    xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#">

  <skos:Concept rdf:about="http://skos.shahuwang.com/CT/崩裂反应">

    <skos:prefLabel xml:lang="zh">崩裂反应</skos:prefLabel>

    <skos:broadMatch rdf:resource="http://www.skos.shahuwang.com/NCT_SCI/39AE31"/>

    <skos:broader rdf:resource="http://www.skos.shahuwang.com/CT/核反应"/>

    <skos:altLabel xml:lang="en">Break-up reactions</skos:altLabel>

    <skos:altLabel xml:lang="zh-Latn">Bēng liè fǎn yìng</skos:altLabel>

    <skos:broadMatch rdf:resource="http://www.skos.shahuwang.com/CT_SCI/32GC"/>

    <skos:broadMatch rdf:resource="http://www.skos.shahuwang.com/CLC/O571"/>

  </skos:Concept>

</rdf>

每一个主题词,均以一个Concept表示,prefLabel则指首选词,broader则是指上位类,altLabel则指拼音或英文等可选词。

SKOS是一套RDF vocabulary(即基于RDF的原则构建的标准),假如用编程语言来进行类比的话,RDF就像Java,而SKOS则是基于Java写出来的软件包。SKOS主要用来表示和描述叙词表、分类法,分类表等知识组织系统。由于其基于RDF,使得构建的知识数据是机器可读可理解的,而且可以无障碍与其他知识组织系统交换。SKOS的目标是让这些知识组织系统更容易交换和复用。值得注意的是,SKOS分为SKOS core和SKOS 扩展两种,后者弥补了SKOS在术语描述中的不足。

综上所述,Semantic Web技术为笔者提供了一个全新的资源描述与服务方案,利用RDF,笔者不仅能够像传统的XML或者MARC那样描述数据,还能使得这些数据是能被机器所理解的,从而更好地揭示术语或概念间的语义关系。而且,RDF可无缝集成的特点,令构建一个公共的术语注册平台提供了可能,同时各术语系统直接的交流也变得更加便利。配合Web Service技术,用可无缝集成的SKOS来描述术语词表,笔者便可将之前完全异构、无法集成的各术语系统连接起来,从而实现更好的服务和应用。

3.2:词表的语义化表示

如何将传统的术语词表转换为SKOS表示呢?该方面的研究,国内外已经有不少。这里以《汉语主题词表》为例,说明如何将受控词表采用SKOS语言进行描述。

如下表给出了《汉语主题词表》中的词汇属性与SKOS词汇之间的映射关系:

image

注释:

1:xmlns:skos="http://www.w3.org/2004/02/skos/core#" 表示W3C定义的SKOS标准语言;

2:xmlns:ex 表示对SKOS标准进行定制的扩展,命名空间待定

3:属性xml:lang="xx" 中的语言代码由《IETF BCP 47》标准定义

该映射关系表取自欧石燕老师研究的中文术语词表转换为SKOS文档的转换映射关系表中的一部分。后面的转换将主要参照此映射表进行转换。

下图则是传统汉语主题词表的数据库存储的部分:

wps_clip_image-12423

根据这个映射表,笔者就能将传统的汉语主题词表转换成SKOS表示了。但要在工程上实现大批量数据转换,以及后面的使用,则还有许多的问题需要探讨。首先,要解决的第一个问题是用何种格式进行表示数据。不管是先前说到的RDF还是SKOS,它们都不是一种数据表示格式,它们是一套标准,就像Unicode一样。而要把笔者的数据表示出来,则需要像UTF-8这样根据Unicode标准实现表示。因此,下面笔者将首先探讨RDF各种数据表示格式的优缺点,以及最终的选择。

在进行技术选型上,数据保存方式一直是重中之重。选择用SKOS来描述汉语主题词表,是确定了方向,就好像确定用MySql来进行存储。而选择什么RDF格式,就像如何设计MySql Schema一样,非常重要。

3.2.1:RDF各实现格式比较

即使从字面意思来看,RDF—–Resource Description Framework,也不是一种编码格式。RDF是一种语言,是一种标准,是一种框架,但确实不是XML这样的东西。目前,实现RDF的格式有RDF/XML, RDF/XML-ABBREV, N3,Turtle,N-Triple,N-Quads,TriG,TriX,RDFa,JSON-LD,RDF/JSON等几种比较流行的格式。RDFa是用于给HTML增加语义标签的,所以这里笔者不对其分析。有如此多的格式,就说明每种格式都有优势,也有其不足,所以才需要增加一种新的格式来解决遇到的问题。

首先,笔者需要对上述除RDFa之外的10种格式进行一个分类:

1:XML类型:RDF/XML,RDF/XML-ABBREV

2:N3类型:N3,Turtle,N-Triple,N-Quads,TriG,TriX

3:JSON类型:JSON-LD,RDF/JSON

下面将使用汉语主题词表中“葱白”一词的SKOS描述,展示各种格式间的区别。

RDF/XML是W3C的推荐标准格式,而RDF/XML-ABBREV则是当前最流行的Semantic Web开发工具包Jena所内置的一种格式,两者差异并不大,RDF/XML-ABBREV增加了对人的可读性,但是也因此牺牲了解析性能。如下是标准的RDF/XML格式示例:

<rdf:RDF

    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"

    xmlns:skos="http://www.w3.org/2004/02/skos/core#"

    xmlns:ex="http://www.skos.shahuwang.com/skos/extention#" >

  <rdf:Description rdf:about="http://skos.shahuwang.com/CT/葱白">

    <skos:altLabel xml:lang="zh-Latn">Cōng bái</skos:altLabel>

    <skos:altLabel xml:lang="en">Bulbus allii fistulosi</skos:altLabel>

    <ex:topBroader rdf:resource="http://www.skos.shahuwang.com/CT/中草药"/>

    <skos:broader rdf:resource="http://www.skos.shahuwang.com/CT/辛温解表药"/>

    <skos:prefLabel xml:lang="zh">葱白</skos:prefLabel>

    <rdf:type rdf:resource="http://www.w3.org/2004/02/skos/core#Concept"/>

  </rdf:Description>

</rdf:RDF>

而RDF/XML-ABBREV则如下所示:

<rdf:RDF

    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"

    xmlns:skos="http://www.w3.org/2004/02/skos/core#"

    xmlns:ex="http://www.skos.shahuwang.com/skos/extention#">

  <skos:Concept rdf:about="http://skos.shahuwang.com/CT/葱白">

    <skos:altLabel xml:lang="zh-Latn">Cōng bái</skos:altLabel>

    <skos:altLabel xml:lang="en">Bulbus allii fistulosi</skos:altLabel>

    <ex:topBroader rdf:resource="http://www.skos.shahuwang.com/CT/中草药"/>

    <skos:broader rdf:resource="http://www.skos.shahuwang.com/CT/辛温解表药"/>

    <skos:prefLabel xml:lang="zh">葱白</skos:prefLabel>

  </skos:Concept>

</rdf:RDF>

两者差异并不大,主要在Concept这有变化。

<skos:Concept rdf:about="http://skos.shahuwang.com/CT/葱白">

等同于RDF/XML的:

<rdf:Description rdf:about="http://skos.shahuwang.com/CT/葱白">

<rdf:type rdf:resource="http://www.w3.org/2004/02/skos/core#Concept"/>

也就是说,每一条Resource,在RDF/XML-ABBREV都被合并为一句,可读性上有所增加。所以对这两者的选择,并没有太大的区别。

虽然是W3C推荐的官方标准,RDF/XML却饱受批评,甚至被认为是阻碍RDF和Semantic Web进步的最大障碍。 Vuk Miličić 在其博客中提到:RDF/XML太过于复杂了,导致想学习RDF的人都被搞晕了。而且,同一个RDF图可以被序列化为多种形式,不同的工具可能序列化出不同的样子来,导致现成的XML工具对RDF/XML几乎无用。学了XML的形,却抛弃了XML众多有用的工具,得不偿失。而且,由于其复杂性,导致处理效率极度低下。

Leigh Dodds则更进一步指出,RDF/XML更严重的问题是数据模型与表现形式的不一致。XML的数据模型是树,而XML的形式也很好地体现了树形结构的思维。RDF的数据模型是图,但RDF/XML却采用了XML的树形结构,两者的不匹配,导致许多的冲突。当初之所以要设计RDF而不是采用XML,就是希望能更简单的描述Web上的资源。先如今,RDF/XML非但没有简化,反而增加了复杂度,使得实现一个RDF/XML Parser极其困难。

虽然RDF/XML有诸多的不足,但毕竟是目前W3C官方唯一的标准格式,所以在How to Publish Linked Data on the Web 一文中提到:你至少需要提供RDF/XML格式,因为它是唯一的标准,所有的Semantic Web工具都支持。同时,该文还建议,由于RDF/XML对人的可读性并不怎么好,所以你还需要提供Turtle数据格式。另外,为了支持XPath或Xquery等XML技术,最好也同时提供TriX格式。

现在来看N3类型这一组。这一组的关系稍显复杂,Turtle是N3的子集,N-Triple是Turtle的子集,TriG是Turtle的稍微扩展,同时比TriX更简洁和更可读。TriX现在的首页访问不了了,W3C没有为其建立页面,它就是结合RDF的Triple模型和XML的描述功能,使得Xpath等XML工具也能在RDF上使用。N-Quads则是对N-Triple的扩展。

N3是一种断言和逻辑语言,是RDF的超集,复杂程度较高,不太适合使用。TriG,TriX,N-Quads的API支持都比较不好,所以这里主要探讨Turtle和N-Triple两种格式。

“葱白”的Turtle格式示例如下:

@prefix ex:      <http://www.skos.shahuwang.com/skos/extention#> .

@prefix rdf:     <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .

@prefix skos:    <http://www.w3.org/2004/02/skos/core#> .

<http://skos.shahuwang.com/CT/葱白>

      a       skos:Concept ;

      ex:topBroader <http://www.skos.shahuwang.com/CT/中草药> ;

      skos:altLabel "Bulbus allii fistulosi"@en , "Cōng bái"@zh-Latn ;

      skos:broader <http://www.skos.shahuwang.com/CT/辛温解表药> ;

      skos:prefLabel "葱白"@zh .

很直白,也很好得体现了Triple模型。目前为止,Turtle被认为是最接近RDF理想格式的。其问题在于,这是一种全新的格式,也就需要为其设计全新的Parser,而目前这种格式在Semantic Web圈子之外几乎不为所知,所以工具支持不够。另外,其到现在还没有支持媒体类型。

N-Triple是对Turtle的进一步简化,使得几乎所有的语言都能对其进行解析,示例如下:

wps_clip_image-12556

N-Triple可谓是极度的简化,每一行就是一条Triple。这样子的好处就是处理速度极快,文件很大时,不需要把数据都加载进内存进行解析。而且,几乎所有的编程语言都能对其进行处理,不需要特殊的工具进行支持。但问题也来了,它不支持Unicode字符。如上面所示,所有的中文都被Jena转换为Unicode编码字符来表示。不同的工具可能在处理N-Triple上对待Unicode字符有不同的方式,这就导致极大的麻烦。而且,这样处理之后,几乎就失去了可读性。

RDF./JSON和JSON-DL是两种不同的格式,RDF/JSON几乎没有对JSON做多少改变,而JSON-DL则是对JSON的扩展,使得其更适合于Linked Data上的使用。由于Jena仍为对JSON-DL进行支持,所以这里只展示“葱白”的RDF/JSON示例:

{

  "http://skos.shahuwang.com/CT/葱白" : {

    "http://www.w3.org/2004/02/skos/core#altLabel" : [ {

      "type" : "literal" ,

      "value" : "Bulbus allii fistulosi" ,

      "lang" : "en"

    }

    , {

      "type" : "literal" ,

      "value" : "Cōng bái" ,

      "lang" : "zh-Latn"

    }

     ] ,

    "http://www.skos.shahuwang.com/skos/extention#topBroader" : [ {

      "type" : "uri" ,

      "value" : "http://www.skos.shahuwang.com/CT/中草药"

    }

     ] ,

    "http://www.w3.org/1999/02/22-rdf-syntax-ns#type" : [ {

      "type" : "uri" ,

      "value" : "http://www.w3.org/2004/02/skos/core#Concept"

    }

     ] ,

    "http://www.w3.org/2004/02/skos/core#broader" : [ {

      "type" : "uri" ,

      "value" : "http://www.skos.shahuwang.com/CT/辛温解表药"

    }

     ] ,

    "http://www.w3.org/2004/02/skos/core#prefLabel" : [ {

      "type" : "literal" ,

      "value" : "葱白" ,

      "lang" : "zh"

    }

     ]

  }

}

从上面的示例可以看出,整个文档的可读性降低了很多。之所以要提供JSON格式的RDF,是为了适应现代网络的发展。JSON已经成为互联网上最流行的数据交换格式,几乎所有的脚本语言都能很好支持JSON,Javascript更是原生支持JSON。当要发布Linked Data的时候,笔者往往采用Web Service的方式。而现在Web Service已经越来越多的使用JSON来进行数据交换了。而且JSON的解析效率非常高。

但是,JSON的问题和RDF/XML的问题非常相似,复杂,难以书写和阅读,树形结构与图模型的不匹配。同时,JSON对URI完全无法感知。

综上所述,各种格式均有其优势劣势。当前笔者所要实现的术语服务,有三个目标要实现:一是要标准化,使得其他组织的术语数据也能无缝集成。二是要提供良好的对人可读性。三是要使用Web Service发布服务。在目前没有任何一种RDF格式能一统天下的情况下,笔者将会提供RDF/XML,Turtle, RDF/JSON三种数据格式。RDF/XML作为统一的标准,与其他的术语数据进行集成时更方便。Turtle则提供了较好的对人阅读性,供人使用。此外,标准的RDF查询SPARQL语言是以Turtle为基础的,查询语言与数据模型的统一,对人的思维来讲是有极大的益处的。JSON则是Web Service的标准交换数据格式,这样其他人无须学习RDF,无须使用专门的RDF 工具也能够使用笔者的服务。另外,由于以上三种格式在传统词表转换为SKOS的时候,异常复杂,需要对RDF和Jena等工具非常熟悉方能做到。为了简化,笔者将会选择N-Triple作为转换的中介格式,后面将会有专门的论述。

现在已经确定了词表的存储格式,下面则需要探讨如何用工具实现批量转换,以及转换中所需要注意的问题。

3.2.2:批量转换的代码实现

学术界近些年对传统术语词表的语义转化做了大量的研究,也取得了不俗的成果。但这些研究在关于如何在工程上实现数据转换,却没有多少实质性的研究。在他们的论文里所展示的数据,多半是通过手工利用protege等编辑工具编写,而且无一例外的使用了RDF/XML格式。这些研究,既没有考虑到RDF/XML格式的缺陷,亦没有考虑到面对如此众多的术语词表,在工程上如何更好的进行语义转换。

美国国会图书馆将其《美国国会图书馆标题表》(Library of Congres Subject Headings,LSCH)的MARC格式数据转换成SKOS数据,其转换方式是将其“MARC21规范数据格式”先转换为MARCXML,然后再确定MARC相应字段与SKOS标签的对应关系,从而转换成SKOS数据。这种方式提供了个方向,但却没有把真正重要的地方展示出来。从XML转换为SKOS这一步如何实现?XML是树形结构数据,SKOS是图模型结构数据,虽然RDF/XML和XML非常相近,但是传统的制作XML的工具(JAXB等)却无法用于RDF的制作。图模型的RDF结构异常复杂,网状模型错综交织,即使传统术语格式与SKOS的对应问题已经解决,但是转换工作耗费更大的时间和金钱,SKOS所带来的好处都被工程实现上的难处所抵消。以欧石燕老师研究的汉语主题词表的SKOS表示为例,下图展示了放大器极其相关属性:

wps_clip_image-12667

如此这般,放大器的子类又有其子类,子类有其自身属性,一个图嵌着另一个图。光是搞明白这个图,就得费不少劲。而更麻烦的地方在于,RDF的制作与解析需要用到特殊的软件包,不同的软件包在制作和解析上有极大的差异。譬如当前最流行的两个工具包Jena和Sesame,虽然两者都是基于Java,但是理念有极大的差别。Jena以model,resource,statement,property为体系,而Sesame则以Repostitory,Graph,Tuple,Value,Statement为体系。除了Java,其他的编程语言均没有好一些的RDF解析器,处理理念相差就更大了。除了处理方式区别大之外,这些解析器均是以W3C标准的RDF/XML格式为基准的,由于RDF/XML极大的复杂性和误导性,要学会使用这些工具,起码得把RDF给搞明白了,这在工程实现上并不现实,要求工程师去学习Semantic Web那么多的内容,极不现实。

另外,目前已知的转换方式,如LSCH将MARC转换为XML再转换SKOS,其实现方式是找到MARC与SKOS的对应关系之后,再做一个模板,把数据硬塞进去。RDF的基石是什么?URI和三元组,显然LSCH的这种做法,把三元组这一RDF精髓抛弃得一干二净。当前所见的研究,均以RDF/XML格式为基准,甚至不少的研究者,就不知道RDF与RDF/XML之间的区别。以三元组构成结点,以结点构成图,以URI连接图,是RDF设计理念的基础,但是RDF/XML却是树形结构的,与RDF设计理念里的图差异极大。如前面所谈,三元组是RDF可被机器理解的基础,机器知道以固定的三元组模式去解析每一个结点,知道这三个结点所代表的subject,property,object,从而才能进一步理解。舍弃了三元组的概念,这种语义转换纯属为了转换而转换,并无多大意义。

全球最大的关联数据平台DBpedia对数据的处理格式上有极大的参考价值。DBpedia上有超过两亿个实体描述数据,大约有19亿条三元组(即结点)。DBpedia采取什么样的格式来保存数据?它既没有采用标准的RDF/XML格式,也没有采用现在最流行的Turtle格式,而是采用最精简的N-Triple格式。为什么采用N-Triple?因为N-Triple用这最精简的方式体现了RDF的两大基石理念:URI和三元组。同时,其无需特殊的软件包,普通的I/O处理就能够完成RDF数据的制作。对于普通的程序员来讲,你只要告诉他原始术语数据与SKOS标签的对应方式,他就能很快制作出RDF数据来。另外,N-Triple基于行的操作,使得I/O处理的效率极高,RDF/XML需要把一个文档完整载入内存方能构造成图,这对大的文档处理起来极其麻烦,而N-Triple格式毫无此担忧。

当然,N-Triple也不是完全没有缺点,比如对Unicode字符的支持就比较差,对XML数据类型的支持也比较弱。关于中文数据在N-Triple格式下的使用方式问题,后面将会有详细解释,现在先来看看N-Triple的官方定义标准。N-Triple是N3的一个子集,所以N3的处理工具,N-Triple也能用。一般建议用".nt"作为N-Triple文件的后缀,与N3以示区分。N-Triple的字符都编码为7-bit的US-ASCII编码。其EBNF(扩展巴斯卡范式)语法如下:

ntripleDoc  ::=  line*

line  ::=  ws* (comment | triple) ? eoln

comment  ::=  ‘#’ (character – ( cr | lf ) )*

triple  ::=  subject ws+ predicate ws+ object ws* ‘.’ ws*

subject  ::=  uriref | namedNode

predicate  ::=  uriref

object  ::=  uriref | namedNode | literal

uriref  ::=  ‘<‘ absoluteURI ‘>’

namedNode  ::=  ‘_:’ name

literal  ::=  ‘"’ string ‘"’

ws  ::=  space | tab

eoln  ::=  cr | lf | cr lf

space  ::=  #x20 /* US-ASCII space – decimal 32 */

cr  ::=  #xD /* US-ASCII carriage return – decimal 13 */

lf  ::=  #xA /* US-ASCII linefeed – decimal 10 */

tab  ::=  #x9 /* US-ASCII horizontal tab – decimal 9 */

string  ::=  character* with escapes. Defined in section Strings

name  ::=  [A-Za-z][A-Za-z0-9]*

absoluteURI  ::=  ( character – ( ‘<‘ | ‘>’ | space ) )+

character  ::=  [#x20-#x7E] /* US-ASCII space to decimal 127 */

N-Triple文档里,每一行就是一条Statement,或者称为三元组。每个资源都用完整URI表示,同时用<>括号括住,三元组之间用空格隔开,每一行以原点句号“.”结尾,如下图:

wps_clip_image-12726

上面所展示的RDF数据,与下面的RDF/XML所表示的数据是一模一样的:

wps_clip_image-12805

从上面的例子可以看出,使用N-Triple,几乎只要记住几个概念就可以了。

下面笔者来看看汉语主题词表的数据库存储示例,下图取自汉语主题词表:

wps_clip_image-12876

从上面看,汉语主题词表是非常典型的三元组模型。款目词,属性,属性值刚好构成三元组的subject,property,object。其实,几乎所有的词表或者术语数据,都能转换成这样的三元组模型。而三元组模型通过N-Triple可极方便简单转换为RDF数据。参考欧石燕老师制作的汉语主题词表与SKOS标签对应关系表,用Jena制作出了如下的N-Triple数据(为了更好显示三元组模型,此处特意用图片展示)。

wps_clip_image-12912

对应代码的主要部分如下:

wps_clip_image-12958

先前已经多次提到N-Triple的缺点——不支持Unicode编码。对于这个问题的解决,W3C官方给出的建议是先将非Unicode字符转换为Unicode编码的形式,然后再构建N-Triple。实际上,在实际编程过程中,笔者发现,利用Jena其实可以以更好的方式解决这个问题,但也仅有Jena能够实现这个目的,其他的Semantic Web工具包均不行,这也是这个解决方案的不足之处。譬如:

<http://skos/CT/葱白> <http://w3/skos/core#prefLabel> "葱白"@zh .

这样一条N-Triple三元组,Jena是可以读取并进行解析的,解析之后,Jena会把非Unicode字符转换为标准的N-Triple格式中的Unicode编码。因此,利用Jena,笔者可以在制作N-Triple数据的时候,保持更好的可读性,从而极大方便数据交流。

实际上,使用N-Triple还有另外一个问题,即前缀问题。在N-Triple是,是没有设置前缀缩写的,所有URI都是全部写出来的,这对于查询非常不方便。不过,Jena可以极为优秀地解决这些问题,通过把N-Triple数据读取进来构建一个model,Jena可以对这个model进行非常丰富而有意义的操作,比如设置前缀、转换数据格式等。

笔者在转换汉语主题词表的过程中,还发现了些问题。以下图的两个词为例,布莱尔模型是叙词,其代项是布莱尔相规则,亦即布莱尔相规则是一个非叙词。它们两个都同存在同一个数据库表中。在欧老师所做的映射关系里,非叙词不能作为一个skos:Concept存在于转换好的文档之中。

wps_clip_image-13017

为解决这个问题,笔者先将叙词从数据库抽取出来,构造完整的skos:Concept。然后抽取出非叙词,由于分类号范畴号等其与对应的叙词是一样的,所以只需要三个数据:非叙词的中文,英文和拼音。笔者将这三个数据作为叙词的skos:altLabel。转换好的数据如下图所示:

wps_clip_image-13059

转换完毕之后,又发现了新的问题。现实情况是:一个叙词有多个非叙词,那么在skos:altLabel里将会呈现多个非叙词的数据,非叙词甲与非叙词乙的英文都放在同一个skos:altLabel里,如何区分这个英文是属于乙的还是属于甲的呢?另外,很多的叙词,是有多个英文名和多个拼音的,假如按照上面的转换关系,即英文用prefLabel,那么有些叙词将出现两个英文的prefLabel,这是违反了SKOS的完整性约束的,显然不行。此时,利用标准的SKOS已经无法解决这个问题了,因为在SKOS的定义里,altLabel和prefLabel都只能是字符串,或者说literal value,而且同一种语言的prefLabel,只能有一个。

所幸W3C已经提供了解决方案,即skos-xl,该标准提供了对标准的SKOS的lexical entities的扩展。所谓的lexical entities,主要指prefLabel,altLabel和hiddenLabel这三个标签,它们在标准的SKOS里都只能用字符串。而skos-xl对其进行扩展之后,这三个标签都能变成实体,从而具有更好的表达能力。如下图,磁天平这个叙词除了磁环秤这个代项之外,还有另一个代项:磁秤,根据skos-xl构建的RDF如下:

CT:磁天平

      a       skos:Concept ;

      skos:altLabel skosxl:磁环秤 , skosxl:磁秤 ;

      skos:broadMatch CLC:TB972 , <http://www.example.com/CT_SCI/Concept#81E> , <http://www.example.com/NCT_SCI/Concept#61AN> , CLC:TB971 ;

      skos:broader CT:天平 , CT:测磁仪器 ;

      skos:prefLabel "磁天平"@zh ;

      skosxl:altLabel <http://www.example.com/temp/Concept#磁环秤> , <http://www.example.com/temp/Concept#磁秤> ;

      skosxl:prefLabel <http://www.example.com/temp/Concept#Magnetic balances> , <http://www.example.com/temp/Concept#Cí tiān píng> .

<http://www.example.com/temp/Concept#磁环秤>

      a       skosxl:Label ;

      skosxl:literalForm "磁环秤"@zh , "Magnetic balances"@en , "Cí huán chèng"@zh-Latn .

<http://www.example.com/temp/Concept#磁秤>

      a       skosxl:Label ;

      skosxl:literalForm "磁秤"@zh , "Magnetic balances"@en , "Cí chèng"@zh-Latn .

<http://www.example.com/temp/Concept#Magnetic balances>

      a       skosxl:Label ;

      skosxl:literalForm "Magnetic balances"@en .

<http://www.example.com/temp/Concept#Cí tiān píng>

      a       skosxl:Label ;

      skosxl:literalForm "Cí tiān píng"@zh-Latn .

从上可以看出,利用skos-xl可以很好地解决叙词有多个非叙词的混淆问题。不过,skos-xl虽然解决了这个问题,但是其却增加了其他的问题,比如其增加了工程实现的复杂度,同时,如上方式做出来的词表,进行查询的时候,查询方式就与标准的SKOS写成的有很大不同。因此,在最终实现上,两者要选其一,而不能混合使用。由于汉语主题词表里,有不少叙词拥有多个非叙词,因此,最终转换方式上,笔者将采用skos-xl的解决方案。

除了上面所提到的利用N-Triple格式,可以高效将传统术语数据转换为SKOS的方法之外,有人提出了利用JPA(Java Persistence API)的方式,利用面向对象的知识,将RDF和SPARQL转换为程序员熟悉的JPA模式,让程序员无需学习RDF等知识,就能制作、存储和查询RDF数据。Empire正是这样的一个项目。通过程序员熟悉的JPA,Empire让程序员利用他们熟悉的工具做东西,可以说对Semantic Web的发展有极大的促进作用。之所以本文不采取Empire作为首选的转换方式,一是因为这个项目依旧不成熟,网上文档极少。二是这个项目严重依赖于Java,在这一点上就不如N-Triple。笔者希望,术语服务系统的构建是自由的,除了数据用RDF表示,存储用Triple Storage,查询用SPARQL,其他的并不会做硬性的要求。

上面笔者已经能够成功批量将汉语主题词表转换为SKOS了,但还有一个问题需要解决,即如何证明你的SKOS数据转换是正确的。W3C在定义SKOS的时候,为SKOS提供了一个OWL本体,该本体里描述了SKOS的一些基本原则概念,也声明了许多的完整性约束原则,合格的SKOS数据都不能违反这些原则。譬如,对于prefLabel这个标签来说,一个Concept里面,只允许存在一个同语言的prefLabel,假如已经出现了一个汉字的prefLabel,就不能再出现另一个了。 http://www.w3.org/2009/08/skos-reference/skos.rdf 这是W3C所写的SKOS的OWL文件,上面是关于SKOS的本体定义。在W3C的网站上,SKOS Reference详细列出了关于SKOS的62条完整性约束。这62条既包含了SKOS Core,也包括了skos-xl。完整的约束可以到 http://www.w3.org/TR/skos-reference/ 查看。

通过搜索,找到这篇文章:Integrity constraints in SKOS,其在文章中介绍了两种方式来进行完整性约束的验证,一个是通过SPARQL的ASK查询,一个是通过使用TopQuadrant所开发的SPIN工具进行完整性验证。在文中,作者主要介绍了用SPARQL进行完整性约束。作者举例如下:

:Concept1 skos:prefLabel "love"@en ;

            skos:prefLabel "adoration"@en .

这是一段违反完整性约束的SKOS,因为英文的prefLabel有两个,在SKOS里是不允许的。作者通过一段SKOS检测出了这个问题:

ASK

{

{SELECT ?lang (count(?lang) as ?nr )

WHERE

  {?subject skos:prefLabel ?label .

   LET (?lang := lang(?label))}

   GROUP BY ?lang}

FILTER (?nr > 1)}

这种方法堪称是没有方法下比较好的方法了。RDF是Schema less的语言,OWL又是基于开放世界假设的,即认为存在就是合理的,所以对于完整性方面的约束基本上没有。而SKOS由于应用领域的需求,又需要较多的完整性约束。但是通过SPARQL的这种方式,需要对SPARQL极为精通才行,如上所示,这个比较简单的完整性约束的SPARQL就不那么简单了,何况是后面更复杂的那些呢。也正是由于现实工作中有极大的约束需求,所以TopQuadrant公司开发了SPIN(SPARQL Inferencing Notation ),专门用于基于RDF的如SKOS一类的词表的完整性约束实现。 http://topbraid.org/spin/api/1.2.0/index.html 此处可以下载到SPIN API,而http://topbraid.org/spin/skosspin 则可以下载到实现了SKOS完整性约束的SPIN文件。通过这两者的搭配,少量代码就能实现完整性约束的功能,下面是核心代码:

wps_clip_image-13402

提供一段违反了SKOS完整性约束的SKOS数据如下:

<skos:Concept rdf:about="http://www.example.com/CT/冲击熔岩">

<skos:prefLabel xml:lang="zh">冲击熔岩</skos:prefLabel>

<skos:prefLabel xml:lang="zh">熔岩</skos:prefLabel>

</skos:Concept>

代码运行后,得到如下结果:

Constraint violations:

-at <http://www.example.com/CT/冲击熔岩>:Constraint S14: a resource has no more than one value of skos:prefLabel per language tag (@zh).

如上可看出,SPIN检查出了错误的地方。该SKOS文件违反了S14这条约束。用这个SPIN来检测笔者做出来的SKOS文件,显示没有违反完整性约束。

RDF不似传统的数据格式,不能像关系数据库那样用SQL语言进行查询,也不能像XML那样用XSLT来进行查询。更关键的是,RDF数据的特殊性以及其要实现的语义识别和无缝集成,都使得传统的关系数据库存储方式不得奏效。目前主流的存储RDF数据的数据库是triplestore,标准的查询语言是sparql。Triplestore是一类数据库的统称,主要用来存储和查询三元组的。在W3C的这个页面上 http://www.w3.org/2001/sw/wiki/Category:Triple_Store 列举了当前实现的Triplestore,而根据目前的情况来看, AllegroGraph,Bigdata, Virtuoso, Sesame, TDB, Stardog, Oracle,Owlim是当前比较好的Triplestore,但其中只有TDB和Sesame是免费的,其他的几个顶多提供功能有限制的免费版。各家的Triplestore功能各有优劣,商业的Triplestore主要在速度、大数据量、推理功能上有较大优势。 http://www.w3.org/wiki/RdfStoreBenchmarking W3C提供了各个Triplestore的性能测试与对比。

由于是科研项目,笔者将选用免费开源的TDB作为笔者的存储。为什么选TDB不选Sesame?主要是因为TDB与Jena结合得更好。Jena最初是由惠普实验室开发的一套Semantic Web工具包,被公认为是最好用的。后Jena被Apache接收为孵化器项目,由Apache基金会的工作人员做了较大修改之后,成为Apache的顶级项目。现在的Jena文档丰富,社区使用者较多,功能实现上较好。TDB曾经是Jena的一个附属项目,现在已经集成到Jena工具包里,成为了Jena的一部分。

由于当前网络上所见的性能测试与对比,多是2011年之前的。这两年里,Sesame和TDB都有了非常大的改进,所以这里无法提供两者详细对比的数据。从个人使用经验上来看,TDB提供了更好的数据加载功能,面对大量数据时表现更好。而Sesame则在查询上表现更好,同时具备一定推理功能。

其实后面提到的一个框架,完全可以屏蔽底层的存储,所以最终你选择TDB还是Sesame,关系并不大,根据自己的需求做技术选型即可。

3.5:词表数据的查询

存储选取好之后,就需要确定查询语言。毫无疑问,首选是SPARQL。SPARQL是W3C定义的一套RDF查询语言,和RDF/XML一样是唯一的标准,因此所有的Triplestore都内置SPARQL引擎,支持SPARQL查询。在功能上,SPARQL与SQL有点儿像,而在语法上,SPARQL则与Turtle挺相似的,譬如下面语句可以查询到一个“葱白”一词的prefLabel:

Select *

Where{ CT:葱白 skos:prefLabel ?p}

Where里面的语句和Turtle是相似的,而且SPARQL利用里函数式语言的模式匹配,即这里的CT:葱白 skos:prefLabel ?p 会匹配Triplestore里类似于这样的三元组,然后将匹配到的值绑定到?p上返回,再继续匹配下一个。不过说实在的,这样的实现原理,也导致SPARQL的性能确实比较低下。

3.6:小结

上面一下子就提到了非常多的技术,很显然,即使SKOS再有优势,也会因为实施这一整套技术的难度而得不偿失。更何况,管理术语词表的机构一般在技术积累上都比较薄弱,让他们撤换掉原来的系统,而去用Semantic Web这一套显然不太可能。一门技术要得到流行,必须是足够简单的,或者在这个环境里,只有这门技术能行得通,如JavaScript。SKOS对于术语服务来说,是功能增强,而不是唯一选择。所以,如果构建这一系列技术的工程不能简单的话,那么SKOS要想被接受,显然是不太可能的。因此,寻找一条简单的道路,让基于SKOS的术语服务更加流行很重要。

本文转载自:沙湖王
posted @ 2017-02-20 15:54  啃苹果  阅读(1047)  评论(0)    收藏  举报