3. 简明知识工程方法
正如我们前面所说,开发本体没有一种“完全正确的”方法。本章针对常见问题,介绍开发本体的一种迭代过程。此过程中,先粗略地构建最初的本体,然后不断改进本体并填写细节。在介绍这个过程的同时,我们会讨论设计者如何做出建模决策,以及不同解决方案的优缺点和含义。
首先,我们要强调本体设计中的一些基本规则。这些规则可能看起来很教条,然而它们可以帮助在许多情况下进行设计决策。
原则:领域建模没有唯一正确的方式,总有可行的替代方案。最好的解决方案几乎总是取决于所考虑的应用和所期望的扩展。
原则:本体开发是一个迭代过程。
原则:本体中的概念应该接近目标领域中对象(不论是物理对象或逻辑对象)和关系。 这些概念很有可能就是来自描述领域的文字中的名词(对象)或动词(关系)。
本体的用途和本体的详细程度规划直接影响建模决策的全过程。本体的直观程度、可扩展性、可维护性都是需要权衡的因素。同时,我们也要注意维护本体模型与实际世界的紧密联系。在我们定义本体的初始版本之后,我们可以通过实际应用、解决问题、与领域专家讨论来对其进行评估和调试。一般情况下,我们都需要修改初始本体。迭代设计的这个过程也可能会在本体的整个生命周期中继续下去。
步骤1. 确定本体的领域和范围
我们建议通过定义本体的领域和范围来启动本体的开发。这需要回答几个基本问题: (1)本体将涉及的领域是什么? (2)我们将要如何使用本体?(3)本体表达的信息应解答什么样的问题? (4)谁将使用和维护本体?上述问题的答案可能在本体设计过程中发生变化,但在任何时间点都有助于限制模型的范围。
以我们之前介绍的葡萄酒和食品的本体为例,(1)食品和葡萄酒就是这个本体的领域;(2)我们计划将该本体用于表达葡萄酒和食物的合理搭配,并由此开发相应的软件系统;(3)显然本体中应该描述不同类型的葡萄酒,主要食物类型,葡萄酒和食物的合理搭配以及不良组合等概念。同时,本体不会包括管理酒厂库存或者餐厅员工的概念,即使这些概念在某种成都上与葡萄酒和食物的概念相关。(4)如果我们设计的本体将被用在对葡萄酒相关文献的自然语言处理,将概念的同义词和词性信息包含在本体中可能很重要。如果本体将用于帮助餐厅客户决定要订购哪种葡萄酒,我们需要增加零售价格信息。如果用于酒吧饭店等葡萄酒买家,可能需要增加批发定价和批量采购的可能性。如果本体维护者与本体使用者使用不同的语言描述该领域的概念,我们需要提供多种语言之间的翻译映射。
可用性评价问题 (Competency questions)
可用性评价问题(Gruninger and Fox 1995),是通过拟定一个基于本体的知识库可以回答的问题列表,来确定本体范围的一种方法。这些问题可用于对本体设计的可用性评测,例如本体是否包含足够的信息来回答这些类型的问题?答案所需要的细节或表示方式?这些问题只是一个草稿,不需要详尽无遗。
在葡萄酒和食品领域,可能有以下问题:
当选择葡萄酒时应考虑葡萄酒的哪种特性?
波尔多是红葡萄酒还是白葡萄酒?
赤霞珠是否可以与海鲜合理搭配?
与烤肉最佳搭配的葡萄酒是什么?
哪种葡萄酒的特征影响葡萄酒与菜品的搭配?
不同年份的葡萄酒的芳香与酒体特性会变化吗?
纳帕馨芳葡萄酒的哪些年份品质比较好?
从这个问题列表中可以看出,本体将包括各种葡萄酒的特征,葡萄酒类型,葡萄酒年份,葡萄酒的品质评价,以及推荐葡萄酒和食物的合理搭配时,对选择合适的葡萄酒有价值的食品分类,
步骤2.考虑重新使用现有的本体
复用别人的工作总是有益的,不必重新发明轮子。看看我们是否可以改进和扩展现有的资源来支持我们的目标领域和任务。如果我们的系统需要与使用特定本体或受控词表的其他应用程序交互,则必须重用现有本体。值得注意的是,许多本体已经以电子数字化形式提供,可以直接导入到您正在使用的本体开发环境中。本体的表达方式往往并不重要,因为许多知识表示软件可以导入导出本体。即使一个知识表示软件不能直接用特定的格式工作,将一个本体从一个格式翻译成另一个格式的任务通常不是一个困难的事情。网络和文献中有可重用本体的本体库。例如,我们可以使用Ontolingua本体库(http://www.ksl.stanford.edu/software/ontolingua/)或DAML本体库(http://www.daml.org/ontologies/ )。还有一些公开的商业本体(例如,UNSPSC(www.unspsc.org),RosettaNet(www.rosettanet.org),DMOZ(www.dmoz.org))。
例如,法国葡萄酒的知识库可能已经存在,如果我们可以导入这个知识库和它所基于的本体,那么我们得到的将不仅是法国葡萄酒的分类,还有用于区分葡萄酒类型的初步特征体系。葡萄酒的槽位列表可以很容易地从一些用于购买葡萄酒(www.wines.com 等)商业网站上获得, 这也是购买葡萄酒的客户关注的属性。
注意,本指南针对初学者,假设没有已知的相关本体存在,并从头开始开发本体。
步骤3. 列举本体中的重要术语
列举所有术语有利于本体开发者向用户陈述或解释本体,说明我们要谈什么术语,这些术语有什么属性,这些术语进一步应该有什么描述。 例如,葡萄酒的重要术语,如葡萄酒,葡萄,酒庄,位置,葡萄酒的颜色,酒体,风味和糖含量等;不同类型的食物,如鱼和红肉;葡萄酒的亚型如白葡萄酒等等。在项目启动时,最重要的是获得一个相对完整的术语列表,不必担心它们所代表的概念之间的重叠,术语之间的关系,或概念可能具有的任何属性,或者概念是类还是槽位。
接下来的两个步骤包括:(1)开发类的层次结构和(2)定义概念的槽位。这两个步骤相互依赖,首先很难做一个再做另一个。通常,我们在层次结构中创建一些概念的定义,然后通过描述这些概念的属性等来继续。这两个步骤也是本体设计过程中最重要的步骤。我们将在这里简要介绍一下,然后在接下来的两节中讨论需要考虑的更复杂的问题,常见的陷阱,决策等。
步骤4.定义类和类的层次结构
类的层次结构可以通过如下方法构建(Uschold和Gruninger 1996):
(1)自上而下的方法,从定义领域中最普遍的概念出发,然后逐步细化概念。例如,可以先为葡萄酒和食品的一般概念创建类。然后再创建“葡萄酒”的子类,例如白葡萄酒,红葡萄酒,玫瑰葡萄酒。我们还可以将“红葡萄酒”进一步分类为西拉(Syrah),红色勃艮第(Red Burgundy),赤霞珠(Cabernet Sauvignon)等。
(2)自下而上的方法,从最具体的类出发定义层次结构的叶节点,随后的将这些类别通过分组和抽象组合成更一般的概念。例如,我们从两种葡萄酒波亚克(Pauillac)和玛歌(Margaux)的定义开始,为这两个类创建一个共同的父类梅多克(Medoc),而梅多克(Medoc)又是波尔多葡萄酒的一个子类。
(3)混合方法综合了自上而下和自下而上的方法,首先定义最突出的概念,然后适当地将其概括和细分。我们开始可能选择几个顶级的概念(如Wine),以及几个具体的概念(如Margaux)。然后,我们将它们与中级概念(如Medoc)相关联。然后可以举一反三,为来自法国的每一个区域的葡萄酒建立相应的类,从而产生一些中间层的概念。
图2显示了不同级别的分类抽象关联层次。
上述三种方法各有千秋,读者可以按照自己对领域的认知选择。如果开发者有一个系统的自上而下的领域全局观,那么使用自上而下的方法可能会更容易。组合方法对于许多本体开发人员来说通常是最简单的,因为“中间”概念往往是领域中更具描述性的概念(Rosch 1978)。如果您首先通过区分最一般的分类来认知葡萄酒,那么自上而下的方法可能会更适合你。如果你宁愿从具体的例子开始,自下而上的方法可能更合适。
无论我们选择哪种方法,我们通常从定义类开始。从在步骤3中创建的列表中,我们选择描述具有独立存在的对象的术语,而不是描述这些对象的术语。这些术语将是本体中的类,并将成为类层次结构中的锚点[2]。 通过询问“是否某个类的一个实例必然是另一个类的实例”,我们可以决定类的层级关系。改写为规则就是: “如果A类是B类的父类,那么每个B的实例也是A的一个实例”。
[2]我们也可以将类视为一元谓词(有一个参数的逻辑表达式),例如,“这个对象是一个葡萄酒吗?”,槽位可以看作二元谓词(有两个参数的逻辑表达式),例如,“这个对象的风味是否强大?”“这个对象的味道是什么?”
例如,每瓶黑比诺葡萄酒(Pinot Noir)都是红葡萄酒,所以,黑比诺(Piont Noir)这个类是红葡萄酒(Red Wine)类的子类。
图2显示了葡萄酒(Wine)本体的类层次结构的一部分。第4节包含了定义类层次结构时的进一步详细讨论。
步骤5.定义类的属性-- 槽位
单靠类是不能提供足够的信息来回答步骤1中的能力问题。一旦我们定义了一些类,我们必须描述概念的内部结构。我们已经从步骤3中创建的术语列表中选择了类。大部分剩余术语可能是这些类的属性。这些术语包括例如葡萄酒的颜色,酒体,风味,糖含量以及酒庄的位置。对于列表中的每个属性,我们必须确定所描述的类。这些属性成为附加到类的槽位。因此,Wine类具有以下槽位:颜色,酒体,味道和糖含量。而酒庄将有一个“位置”槽位。
一般来说,有几种类型的对象型属性可以成为本体的槽位:
(1)“内在的”属性。如葡萄酒的味道。
(2)“外在的“属性。如葡萄酒的名称和产地。
(3)组成部分。可以是对象的物理和抽象的“部分”,例如,宴席的一道菜。
(4) 与其他个体的关系。这些关系是类的成员之间或者和其他物品之间的。 例如,“葡萄酒的酿造者”代表葡萄酒和葡萄酒厂之间的关系,或者“葡萄酒所使用的葡萄”。
因此,除了早先发现属性之外,我们需要在葡萄酒类中添加以下槽位:名称,区域,酿造者,葡萄。图3显示了葡萄酒类的槽位。该类的所有子类都会继承该类的槽位。例如,Wine类的所有槽位将被继承到酒(Wine)的所有子类,包括红酒(Red Wine)和白酒(White Wine)。我们将添加一个额外的槽位,单宁级别(低,中等或高)到红葡萄酒类。“单宁级别”槽位将由红葡萄酒的所有子类(如波尔多和博若莱)继承。一个槽位应该附加在可以具有该属性的最通用的类中。例如,葡萄酒的酒体和颜色应该附在葡萄酒类,因为它是最通用的类,其实例将都具有酒体和颜色的属性。
步骤6. 定义槽位的刻面(facet)
槽位可以进一步定义不同的刻面(也就是槽位取值的特征), 例如取值类型,允许的取值,不同取值的数量(基数cadinality)。 例如,葡萄酒的名称是一个字符串,可以定义如下,“葡萄酒”类的“名称”槽位的取值类型是字符串(String)类型。一个槽位“生产”可以同时取多个值(例如“酒庄生产多种葡萄酒”),并且取值是葡萄酒类的实例(例如 “酒庄”的“生产”槽位对应的取值必须来自“葡萄酒”类)。
下面描述几个常见的刻面:
槽位基数(Slot cardinality)
槽位基数定义了一个槽可以有多少个不同的值。一些系统仅区分单个基数(允许至多一个值)和多个基数(允许任意数量的值)。葡萄酒的酒体为单一基数的槽位(就是说,葡萄酒只能有一个酒体)。由某个酒庄生产的葡萄酒允许多个基数槽位(就是说,一个酒庄可以生产多种葡萄酒)。
一些系统允许指定最小和最大基数,以更精确地描述槽位值的数量。 最小基数为N意味着槽位必须至少具有N个不同的值。例如,葡萄酒的“葡萄”槽位的最小基数为1,就是说每种葡萄酒由至少一种葡萄制成。 最大基数为M表示一个槽位最多可以有M个不同的值。“单一葡萄酒”类的“葡萄”槽位的最大基数为1,就是说此类葡萄酒仅由一种葡萄制成。有时将最大基数设置为0可能很有用,这样的设置将指示该分类的槽位不应该有任何值,例如“企鹅”类虽然是“鸟”类的子类,但是其“最大飞行时间”槽位不应该有取值。
槽位取值类型(Slot-value type)
槽位取值类型描述槽位中可填充哪些类型的值。以下是更常见的值类型的列表:
(1)字符串(String)是用于槽位(如“名称”)的最简单的值类型,值是一个简单的字符串。
(2)数字(Number, 有时使用更多特定的浮点数和整数值类型)描述槽位带数值。例如,葡萄酒的“价格”可以有一个值类型Float.
(3)布尔(Boolean) 指简单的“是”、“否”。例如,如果我们选择不将起泡葡萄酒作为单独的类来表示,葡萄酒是否起泡都可以表示为布尔值:如果值为“true”(“是”)则是起泡酒,,并且如果值为“false”(“否”)则该酒不是起泡酒。
(4)枚举指定该槽位的特定允许值的列表。例如,我们可以指定风味槽可以承受三个可能的值之一:强,中等和微妙。在Protege-2000中,枚举的槽位是Symbol的类型。
(5) 实例类型,允许定义实例之间的关系,定义槽位取值允许哪些类的实例。例如,“酒庄”类的“生产”槽位的取值类型为葡萄酒类,也就是选择葡萄酒的实例作为“生产”的取值。[3] 图4显示了“酒庄”类中“生产”槽位的定义。
[3]一些系统只是使用一个类来指定值类型,而不需要一个特殊的实例类型槽。
槽位的定义域(Domain)和值域(Range)
槽位取值类型通常也被称为槽位的值域(Range)。在图4的例子中,葡萄酒类是“生产”槽位的值域。有些些系统允许为在槽位与特定的类连接时,进一步限制该槽位的值域。槽位所连接的类(或者槽位所描述的类)称为槽位的定义域,例如酒庄类是“生产”槽位的定义域。换言之,在我们将槽位连接到一个类时,槽位所依附的这个类被称为该槽位的定义域。
我们通常采用如下规则确定槽位的定义域或值域:一个槽位的定义域或值域应该适当选择。一方面,不要定义一个过于普遍的定义域或值域:槽位定义域中的所有类的实例都是用该槽位描述,而槽位的任意取值都应该是槽位的值域的某个实例。不建议选取一个范围过大的通用类(例如THING)作为槽位的值域。例如,在描述“酒庄”类的“生产”槽位时,我们不必枚举所有的葡萄酒,更不必选择THING--本体中最通用的类, 而是使用“葡萄酒”类作为该槽位的值域。确切地说共有三条原则:
(1)如果一个槽位的值域(或定义域)对应的类列表中同时包含一个类和它的子类,则可以删除该子类。例如,一个槽位的值域同时包含“葡萄酒”类和“红葡萄酒”类,我们可以从值域中删除“红葡萄酒”类。因为此槽位的值域已经隐含地包含了“葡萄酒”类的所有其他子类,红葡萄酒类是葡萄酒类的一个子类,
(2)如果一个槽位的值域(或定义域)对应的类列表中包含了一个A类的所有子类,但是没有没有包括A类,则可以使用A类替换掉它的所有子类。例如,一个槽位的值域若是包括了“红葡萄酒”类,“白葡萄酒”类,“玫瑰葡萄酒”类等“葡萄酒”类的所有子类,我们可以直接指定该槽位的值域为“葡萄酒”类。
(3)如果一个槽位的值域(或定义域)对应的类列表中包含了一个A类的大多数子类(并非全部),则可以根据实际情况考虑直接只使用A类并去掉这些子类。
再如,设计“单宁水平”的槽位的定义域时,我们可以将该槽位的定义域指定为红葡萄酒的每个子类(例如波尔多,梅洛,博若莱等)。但是因为所有的红葡萄酒都具有“单宁水平”的槽位,所以我们更应该把这个槽位放在这个更通用的“红葡萄酒”类上。进一步指定该槽位的定义域为”葡萄酒“类是不正确得,因为人们不使用“单宁水平”来描述白葡萄酒。
步骤7. 创建实例
最后一步是在类的层次结构,为类创建个体实例。定义类的个体实例需要:
(1)选择一个类,(2)创建该类的个体实例,和(3)填充该实例槽位的值。例如,我们可以创建一个单独的实例夏多-莫贡-博若莱 (Chateau-Morgon-Beaujolais)来代表一种特定类型的博若莱葡萄酒,或者说夏多-莫贡-博若莱 (Chateau-Morgon-Beaujolais)是“博若莱葡萄”类的一个实例。此实例具有以下槽位取值(图5):
酒体=轻;
颜色=红色;
风味=细腻;
单宁水平=低;
葡萄=Gamay(葡萄类的实例);
制造商=Chateau-Morgon(葡萄酒类的实例);
地区=博若莱(葡萄酒产区类的实例)
糖分:干;
该实例是来自博若莱地区的Chateua Morgon Beaujolais,由Morate酒庄酿造的Gamay葡萄制成。它具有酒体轻,口感细腻,红色,单宁含量低。它是干红葡萄酒。
本节讨论在定义类和类层次结构(第3节中的步骤4)时需要注意的要点和容易出现的错误。正如我们之前提到的,对于任何给定的领域,并没有唯一正确的类层次结构。类的层次结构取决于本体的可能用途,以及应用程序所需的详细程度、开发者的个人偏好、以及与其他模型兼容的要求。但是,在开发类层次结构时,我们将讨论几个准则。尤其在定义了相当数量的新类之后,回顾并检查新建的层次结构是否符合这些准则是有益的。
Last updated
Was this helpful?