2002-08-21 10:35
知识管理的基本XML和RDF技术(三):语义知识
Uche Ogbuji (
本专栏文章是这个系列的第三部分,它演示了如何通过合并 WordNet 同义词集将语义知识添加到 RDF 应用程序。有了添加的
WordNet 词汇数据库知识,可以一次性搜索具有相关概念的一组 RDF
数据,而不是一次只能搜索一个关键字。如同演示问题跟踪器应用程序所示,那意味着搜索一次以获得符合“selection”概念的实例,而不是对“vote”、“choice”、“vote”以及
86 个其它的相关术语进行单独查找。专栏作家 Uche Ogbuji 用 Python
编写的示例代码演示了这项技术。
既然我已经在以前的专栏文章里概述了从 XML 应用程序抽取数据到 RDF
模型中去的基本技术,那么可以继续获取这一工作所带来的好处。如果最近没有阅读过前两个专题,则在继续向下读之前,可能需要回顾一下它们(请参阅本专栏文章右侧“内容”表中“相关内容”这一部分中的链接)。
您可能会想起演示应用程序是管理以 XML 格式表示的事件数据的问题跟踪器。至此,本专栏已经涉及了从这些数据抽取 RDF 的技术,以及查询结果 RDF 模型的基本技术。现在,让我们来仔细研究一个实例,来说明为什么这些努力是非常有价值的。
WordNet 简介
WordNet
是普林斯顿大学的一个项目。该项目被称为“英语词汇数据库”,它是这样一个系统,通过将同义词的集合集中到称为同义词集(synonym
sets)或同义集(synsets)的组中来描述和分类单词和概念。我不能过分吹捧这一重要的长期项目,该项目代表了如此有前景的产业。因为它的开放性意味着实际上任何开发人员都可以使用它,所以它十分重要。WordNet
有“不受限制的”许可证。它很象 BSD 许可证,因为唯一真正的限制是不可以盗用普林斯顿大学的商标来宣传 WordNet 的任何派生产品。
必须指出的是,智力劳动的一些最重要的成果被自由用于公益事业总是件好事。这些天,我们经常听到太多有关一些组织企图通过免费获取公共知识但又拒绝无偿做出贡献来获取可能有问题的利润的新闻。
WordNet 目前的版本是 1.7,它包括一个表示成千上万名词的同义集词汇表。同义集是有关大量概念(包括上义关系(hyponyms))、其它概念类型的概念以及子类(上义关系(hypernym)是下义关系的超类)。WordNet 还包含相似但不同义的概念之间的映射。
普林斯顿分发的 WordNet 本身是作为用于各种平台的数据文件和命令行查询工具。许多项目都对 WordNet 进行了更改和增强,并且由于它表示了构造如此良好的资源网络,所以 RDF 社区对采用 WordNet 尤为积极。几个相关的项目包括 Dan Brickley 的用于 Web 的 WordNet,和 Jonathan Borden 博士的将其改写成可浏览的 XHTML 格式。在本文中,我使用了从 WordNet 数据库到 RDF 的直接转换,感谢 Sergey Melnik 和 Stefan Decker,和 Brickley 和 Borden 一样,他们俩都忙碌于 RDF 社区。我所提到的大多数项目(包括这里使用的 Melnik 和 Decker RDF 转换)仍然是基于 WordNet 1.6。
安装 WordNet/RDF
本专栏举例说明了使用 RDF 工具和
WordNet RDF 模型将语义特性添加到 RDF 构建的问题跟踪器。可以使用任何 RDF 工具,对其作一些更改来遵循该过程。我将使用我公司的开放源码
4Suite 的 4RDF。以 RDF 形式表示的 WordNet 非常巨大,因此将使用 4RDF 的持久数据库后端来管理 WordNet。4RDF
允许在内存中管理这些模型(这也是到目前为止本系列中一直使用的方法),它也允许在持久存储(以平面文件的形式存储的诸如 PostgreSQL 和 Oracle
这样的 SQL DBMS 中,或存储在我所编写的实验性定制 RDF 后端 Mangrove 中)中管理模型。因为 Mangrove 将可能在 4Suite
的下一个发行版本 0.12.0 中首次出现,而它在发行之前是不能出现的,所以本专栏文章中的示例使用 PostgreSQL。PostgreSQL
是开放源代码,企业级的关系数据库,许多 Linux 的分发版(distribution)都带有它,并且还有可供许多其它平台使用的包。
要安装它,请首先下载 WordNet/RDF 文件。我必须修正几个地方,因为 wordnet_hyponyms-20010201.rdf 文件被毁坏。
我将 58268 行和109228 行进行修改。
接下来,(对于语义问题跟踪器)将名词和下义关系数据库 WordNet RDF 文件添加到基于 PostgreSQL 名为 sit 的 RDF 模型:
清单 1. 将 WordNet RDF 文件添加到名为 sit 的数据库 RDF 模型中
$ 4rdf --driver=Postgres --dbName=sit wordnet_nouns-20010201.rdf
$ 4rdf --driver=Postgres --dbName=sit wordnet_hyponyms-20010201.rdf
如同在清单 1 中所见到的一样,必须指定 Postgres 驱动程序,这需要指定数据库名称。如果具有该名称的数据库不存在,那么将创建该数据库;如果该数据库存在,将向该数据库中添加生成的语句。
在返回到问题跟踪器之前,请试着在目前所创建的 WordNet 模型上运行简单的测试脚本。
清单 2:练习 WordNet RDF 模型的小测试程序(wn-test.py)
from Ft.Rdf.Drivers import Postgres
from Ft.Rdf import Model, Util
WN_RDF_BASE = "http://www.cogsci.princeton.edu/~wn/schema/"
def Test():
db = Postgres.GetDb('wordnet')
db.begin()
m = Model.Model(db)
print "Size of the model (number of statements): ", m.size()
print "Synonyms of the word 'knowledge':"
noun = Util.GetSubject(m, WN_RDF_BASE+'wordForm', 'knowledge')
print Util.GetObjects(m, noun, WN_RDF_BASE+'wordForm')
print "Classification chain for 'knowledge':"
HypernymChain(noun, 'knowledge', m)
db.rollback()
return
def HypernymChain(noun, wform, m):
hyper = Util.GetObject(m, noun, WN_RDF_BASE+'hyponymOf')
if hyper:
hwform = Util.GetObject(m, hyper, WN_RDF_BASE+'wordForm')
print "%s is a kind of %s"%(wform, hwform)
HypernymChain(hyper, hwform, m)
return
if __name__ == "__main__":
Test()
在清单 2 中,Postgres.GetDb('sit') 建立到所创建的 RDF 数据库后端的连接。在建立该连接之后,在后端开始了一个事务,并使用它来建立可供查询的模型对象。首先,只要查看一下模型中的语句的数目。然后,使用在上一篇文章中所介绍的一些 RDF 查询的基本类型来查找单词“knowledge”的同义词,并跟踪概念间分类链。
WordNet/RDF 以如下形式使用 URI
http://www.cogsci.princeton.edu/~wn/concept#100001740
来表示名词同义集,其中 100001740 是同义集的标识符。然后,每个词(同义集中的每一个词)都有一条 wordForm 语句。如果适当,还有一条 hyponymOf 语句以将每个同义集同其超类相联系。因此,测试程序按照这一模式使用几个简单查询就可以获取同义词。 HypernymChain 是递归函数,该函数先取得同义集资源以及同义词中的某一词的单词形式,然后查找上义关系。将该清单保存到称为 wn-test.py 的文件中,并按如下所示运行它:
$ python wn-test.py
Size of the model (number of statements): 351632
Synonyms of the word 'knowledge':
['cognition', 'knowledge']
Classification chain for 'knowledge':
knowledge is a kind of psychological feature
问题跟踪器词汇层
上一个专题论述了为了抽取序列化 RDF 如何转换多个 XML
文件,然后如何通过 RDF 处理器传递结果。现在该是将那些语句添加到含有 WordNet 语句的同一个模型中的时候了:
$ 4rdf --driver=Postgres --dbName=sit issues.rdf
该代码再一次指定 Postgres 驱动程序以及与前面相同的数据库名称,但是,这一次它从 issues.rdf 文件读取数据,如果还记得的话,该文件包含从样本问题跟踪器文件中抽取的元数据。
现在,可以重新运行我们已经见过的查询,但这次具有语义能力。例如,在上一个专题中,演示了使用正则表达式查找赋予 uogbuji 所有操作(这些操作的主体里含有字符串 vote)的查询示例。现在,比如说,想查找赋予 uogbuji 有关一般意义上“选择”的所有操作。这时,不用再查找一些字符串模式,取而代之的是,需要语言认知层上的真正词汇模式。正在查找的单词都带有“selection”的含义:不仅仅是“vote”,而且还有“choice”和“ballot”。
清单 3 是执行该搜索的程序。
清单 3:使用 WordNet,通过英语语义概念执行搜索的程序(seman-search.py)
from Ft.Rdf.Drivers import Postgres
from Ft.Rdf import Model, Util
from Ft.Rdf.Model import REGEX
USER_ID_BASE = 'http://users.rdfinference.org/ril/issue-tracker#'
IT_SCHEMA_BASE = 'http://xmlns.rdfinference.org/ril/issue-tracker#'
WN_RDF_BASE = "http://www.cogsci.princeton.edu/~wn/schema/"
g_relatedWords = []
def SemanSearch(word):
db = Postgres.GetDb('wordnet')
db.begin()
model = Model.Model(db)
#Find the synset resource of which we have the word form
noun = Util.GetSubject(model, WN_RDF_BASE+'wordForm', word)
print 'Actions assigned to uogbuji related to "%s":'%(word)
#Get all word forms of this synset and its hyponyms
HyponymWords(noun, model)
#Combine all the words into one large regular expression
pattern = ".*" + "|".join(g_relatedWords) + ".*"
#Use this regex to search for the appopriate concepts
actions = Util.GetSubjects(model, IT_SCHEMA_BASE+'body', pattern,
objectFlags=REGEX)
#Iterate over the bodies of the matching actions
for action in actions:
#See if this action is assigned to uogbuji
assignee = Util.GetObject(model, action, IT_SCHEMA_BASE+'assign-to')
body = Util.GetObject(model, action, IT_SCHEMA_BASE+'body')
if assignee == USER_ID_BASE+'uogbuji':
print "*", body
db.rollback()
return
def HyponymWords(noun, model):
words = Util.GetObjects(model, noun, WN_RDF_BASE+'wordForm')
print "words", words
g_relatedWords.extend(words)
hypos = Util.GetSubjects(model, WN_RDF_BASE+'hyponymOf', noun)
print "hypos", hypos
for h in hypos:
HyponymWords(h, model)
return
if __name__ == "__main__":
import sys
SemanSearch(sys.argv[1])
在清单 3 中,SemanSearch 是主函数。它从访问带有 WordNet 和问题跟踪器数据的 RDF 模型开始执行。该函数带有一个 word 参数:作为概念性搜索基础的单词。第一步是将该单词转换到 WordNet 同义集资源。然后,该程序将该同义集所有其它单词形式(同义词),以及下义关系同义集中所有单词形式添加到搜索列表。例如,在给定最初的概念:“selection”的情况下开始搜索,清单 4 显示了这次搜索到的所有 89 个与“selection”的单词。
清单 4. 搜索“selection”的同义词和下义关系的结果
['choice', 'pick', 'selection', 'casting', 'sampling', 'random
sampling', 'proportional sampling', 'representative sampling',
'stratified sampling', 'conclusion', 'decision', 'determination',
'appointment', 'assignment', 'designation', 'naming', 'nominating',
'nomination', 'co-optation', 'co-option', 'delegacy', 'ordaining',
'ordination', 'laying on of hands', 'call', 'move', 'demarche',
'maneuver', 'maneuvering', 'manoeuvering', 'manoeuvre',
'tactical maneuver', 'tactical manoeuver', 'parking', 'device',
'gimmick', 'twist', 'fast one', 'trick', 'feint', 'gambit', 'ploy',
'stratagem', 'artifice', 'ruse', 'measure', 'step', 'countermeasure',
'countermine', 'porcupine provision', 'shark repellent', 'golden
parachute', 'greenmail', 'pac-man strategy', 'poison pill', 'suicide
pill', 'safe harbor', 'scorched-earth policy', 'casting lots', 'drawing
lots', 'sortition', 'finding', 'finding of fact', 'verdict', 'compromise
verdict', 'quotient verdict', 'directed verdict', 'false verdict',
'general verdict', 'partial verdict', 'special verdict', 'conclusion
of law', 'finding of law', 'volition', 'willing', 'election', 'co-optation',
'co-option', 'ballot', 'balloting', 'vote', 'voting', 'secret ballot',
'split ticket', 'straight ticket', 'multiple voting', 'casting vote',
'veto', 'pocket veto']
为了对该搜索列表中的单词(问题操作)执行一次性搜索,该程序将这些单词形式放进了一个大的正则表达式。然后,如同以前专栏文章所说明的那样,操作结果列表进一步缩小到赋给“uogbuji”的操作。以下是运行清单 3 中程序(seman-search.py)的结果:
$ python seman-search.py selection
Actions assigned to uogbuji related to "selection":
* Organize a vote on this topic
在命令行中传入基本概念(这里是“selection”),并且打印匹配的操作。
并非一切都十全十美
当然,这种语义搜索方法还有些问题。最明显的是性能问题。WordNet/RDF
图表的大小使得遍历的代价非常高昂。以上面的样本会话为例,使用“selection”作为搜索的基本概念,在 PIII 1GHz
膝上电脑上运行,花了两分多钟,严重影响了磁盘上的 DBMS。几乎所有时间都花在递归向下遍历下义关系链上。如果搜索诸如“thing”
这样抽象的概念,我几乎不敢推测这要花多长时间,它可能会将机器挂起(也可能使机器崩溃)。
和以前专题中一样,存在该问题的部分原因是这个示例仍然使用一些真正的蛮力的方法来查询 RDF 模型。它没有真正地利用任何优化。当在本系列中随后的文章中,讨论 RDF Inference Language (RIL)时,将提出一些优化措施。然而,即便经过优化,象这样功能强大的搜索可能还是有一些难以解决的性能问题。
可以通过策略来处理一些性能问题。譬如,可以禁止搜索超过某一抽象级别。一个比较原始的用以衡量抽象级别的标准,可能是从同义集到它的最远下义关系的最长距离。由于大多数的处理时间花费在遍历 WordNet 图表上,因此另外一个可能的解决方案是,通过使用搜寻器(crawler)以准备相关概念的列表,来优化常见搜索。
另外一个问题是,在 WordNet 上所做的努力还不够。WordNet 中几乎映射了所有的常用的名词或名词词组,但却没有映射动词、修饰语以及语言的其它部分。这一点限制了搜索。而且,还有一个事实,WordNet 是英语项目,因此其它语言可能还无法用这种具有强大功能的语义搜索。现在 EuroWordNet 在开发针对欧洲语言的映射,但它仍处于开发之中。当然,还有许多重要的语系,诸如东亚和中东,可能还没有这样的设施。
结束语
我一直很高兴地看到人们对我通过使用 RDF 语义查询使用 RDF
所引起的种种可能性进行演示所产生的兴奋反应。它能帮助人们了解半结构化关系和元数据管理的价值,因此这简直是恩赐,因为向生意人甚至许多开发人员解释这一概念都不是一件容易的事。我将通过讨论
RDF
驱动的问题跟踪器的详细信息,来继续探索使用知识管理以改进应用程序。然而,在下一专题中,将暂时放下这一点,先讨论我们在本专栏早些时候讨论的一些事物的更新。
参加有关本文的论坛。
“XML 编程思想”专栏系列的以前专题(关于使用 RDF 开始 KM):
普林斯顿小组的 WordNet 主页:英语词汇数据库。
本文中使用到的 WordNet RDF 转换。在这里也可以找到 RDF 模式。
WordNet:电子词汇数据库 ,ISBN 026206197X(MIT 出版社,1998)
WordNet for the Web,该服务以单独的 Web 页面表示每个 WordNet 概念。
将 WordNet 以资源目录描述语言(Resource Directory Description Language(RDDL))文档形式提供给 Web 页面的工具
EuroWordNet:“用 wordnet 为几种欧洲语言建立多语言数据库。”
带有来自 WordNet 样本的 IBM 探索“知识社会化”页面
Interlingual BRICO:IBM Systems Journal 论文,论述了建立在英语概念之上然后扩展到其它语言上的存在的理论。
FramerD:
Representing knowledge in the large:IBM Systems Journal 论文,讨论
FrameD,FrameD 是一种具有上下文感知能力的媒体应用程序系统。
|