4.定义类和类层次结构

4.1确保类层次结构正确

“is-a”关系

我们可以通过“is-a”关系来定义类层次结构。如果B类的每个实例也是A类的一个实例,则A类是B的子类。例如, 霞多丽(Chardonnay)是白葡萄酒的一个子类。分类层次结构亦可以用“是一种”(kind-of)关系描述,例如 霞多丽是一种白葡萄酒;喷气式飞机是一种飞机;肉类是一种食物。

一个类的一个子类代表一个概念,它是父类代表的“一种”概念。

一种葡萄酒不是所有葡萄酒的一个子类。

常见的建模错误是将同一概念的单数和复数版本定义到层次结构中,并使得前者是后者的一个子类。例如,将“葡萄酒”(Wine)类定义为“葡萄酒们”(Wines)的子类是错误的。通过代入“是一种”关系,建模误差就会变得清晰,例如单一的葡萄酒不是一种葡萄酒。避免这种错误的最佳方法是在命名类时统一使用单数或复数(参见第6节关于命名概念的讨论)。

层次关系的传递性

子类关系是传递性的:如果B是A的子类,且C是B的子类,那么C是A的一个子类。 例如,我们可以定义一个“葡萄酒”类,然后定义“白葡萄酒”类作为“葡萄酒”的子类。然后我们将霞多丽定义为白葡萄酒的一个子类。子类关系的传递性意味着霞多丽类也是“葡萄酒”的子类。有时我们区分直接子类和间接子类。直接子类是与父类的“最接近”子类,也就是说层次结构中类与其直接子类之间没有其他类。在我们的例子中,霞多丽是白葡萄酒的直接子类,但不是“葡萄酒”的直接子类。

类层次结构的演进

维护一致的类层次结构可能会随着域的发展而变得具有挑战性。例如,多年来所有的仙粉黛(Zinfandel)葡萄酒都是红色的。因此,我们将一类仙粉黛(Zinfandel)葡萄酒定义为红酒类的一个子类。然而,有时候葡萄酒酿造商会在酿酒的过程中去掉生色的因素,从而改变葡萄酒的颜色。因此,我们得到玫瑰色的的“白色仙粉黛”。现在我们需要将仙粉黛类分成种,分别是白仙粉黛和红仙粉黛两个类,它们又分别是玫瑰葡萄酒和红葡萄酒的子类。

类和它的名称

辨别类和它的名称很重要:类表达了领域中的概念,而不是表示这些概念的单词。当我们选择不同的术语命名体系,类的名称可能会有所差异,但每个术语本身应对应客观存在的概念共识。例如,我们可以创建一个名为Shrimps(虾)的类,然后将其改名为Prawns,该类仍然表示相同的客观概念“虾”。可以与名为Shrimps的类实例相配的葡萄酒,也可以与名为Prawns的类的实例相配。从更实际的角度来说,应该始终遵循以下规则:

同一概念的同义词并不代表不同的类别

同义词只是概念的不同名称。因此,我们不应该同时有一个类称为Shrimps(虾) 和一个类称为Prawns(虾的另一种英文名称)。甚至一个类称为Crevette (虾,英文从法语中借来的词汇)。我们应该定义一个类,称为Shrimps(虾)。 许多系统允许将在定义类同时关联该类名称的同义词、不同语种的别名,以及界面中展示给用户的名称。如果表示系统不支持这样的类定义,我们仍然可以在相应的本体说明文档中描述之。

避免类循环定义

我们应该避免类层次结构中的循环。当某个类A的一个子类是B并且B也是A的父类时,这样的层次结构中存在一个循环。理论上讲,在层次结构中创建这样一个循环只能说明A类和B类是相等的,换言之,所有A的实例是B的实例,B的所有实例也都是A的实例。

4.2分析层次结构中的同级别概念(siblines)

基本定义

层次结构中的同级别概念是指某一个类的所有直接子类(参见第4.1节)。“除了根节点概念外,层次结构中的所有同级别概念应该在同一个粒度层次”。例如,“白葡萄酒”类和“霞多丽”类并非是同一个类的直接子类(比如说葡萄酒类)。白葡萄酒是比霞多丽更为通用的概念。同级别概念的粒度选择类似于书本中的章节组织粒度体系。在这个意义上,类层次结构的与书本纲要的结构类似。

然而,在层次结构的根节点概念(通常表示为一些非常普通的类的直接子类,如Thing)代表了主要的领域知识体系划分,这些概念之间通常不可比,也不需要是类似的概念,属于例外。

判定尺度

一个类直接子类的数量有多少,并没有硬性限制。当然,许多结构良好的本体中,一个类通常有二到十几个直接子类。

我们提供两个指导原则:

原则:如果类只有一个直接子类,可能存在建模问题或本体不完整。

原则:如果类有十几个子类,则可能需要构建一些中间类。

这两个规则类似于列表的排版规则,一个列表中应该不只一个成员,也不应该有太多成员。例如,大多数红勃艮葡萄酒是科尔多(Côte-d'Or)葡萄酒。假设我们只想代表这种大多数“红勃艮第葡萄酒”。我们可以创建一个“红色勃艮第(Red Burgundy)”类,然后创建一个单一的亚类科尔多葡萄酒(Côte-d'Or)(图6a)。然而,如果在我们的表示中,“红色勃艮第(Red Burgundy)”和科尔多葡萄酒(Côte-d'Or)本质上是等价的(所有红色勃艮第葡萄酒都科尔多是葡萄酒,所有科尔多葡萄酒都是红色勃艮第葡萄酒),那创造科尔多葡萄酒(Côte-d'Or)类就不是必需的,并且不会在本体中添加任何新信息。如果我们要包括“夏隆內丘(Côte Chalonnaise)葡萄酒,产自科尔多以南的更便宜的勃艮第葡萄酒,那么我们可以创建”红色勃艮第“类的两个直接子类:科尔多葡萄酒(Côte-d'Or)和夏隆內丘(Côte Chalonnaise)葡萄酒。

假设将所有类型的葡萄酒列为Wine类的直接子类。然后,这份清单将包括诸如博若莱和波尔多等本体遍的葡萄酒,以及更具体的类型,如波亚克(Paulliac)和玛歌(Margaux)(图7a)。那”葡萄酒类“就会因存在过多的直接子类 而变得不好使用。实际上,为了本体以更有组织的方式反映不同类型的葡萄酒的分类体系,梅多克(Medoc)应该是波尔多(Bordeaux)的一个子类,而科尔多葡萄酒(Côte-d'Or)应该是勃艮第的一个子类。同样具有红葡萄酒和白葡萄酒等中等本体将反映许多人所拥有的葡萄酒领域的概念模型(图7本体对于一大群同级别概念,如果没有众所周知的分类体系,我们也不需要人为地创造新的分类体系。毕竟,本体是现实世界的反映,如果现实世界中没有分类,那么本体应该反映出来。

4.3多重继承

大多数知识表示系统允许类层次结构中的多重继承:类可以是几个类的子类。假设我们要创建一个单独的甜点葡萄酒类,“甜点葡萄酒”类。波尔图(Port Wine)既是红酒,也是甜点酒。[4]因此,我们定义波尔图(Port Wine)这个类有两个父类:红葡萄酒和甜点酒。 波尔图(Port Wine)类的所有实例都将是红葡萄酒类和甜点酒类的实例。 波尔图(Port Wine)类将从其父类继承槽位以及对应的刻面。因此,它会继承如下设定:糖分槽位的值为SWEET(来自甜点葡萄酒类),以及”单宁级别“和“颜色”槽位的取值(来自红葡萄酒类).

[4]我们选择在我们的本体中只代表红色波尔图,白色波尔图确实存在,但它们是非常罕见。

4.4何时引入一个新类

建模过程中的一个难题就是:什么时候引进一个新类,或何时通过不同的属性值表示差异。不论是充斥无关类的过度细分的复杂层次结构,还是一个把大量分类信息编码在槽位取值中的平坦层次结构都不是很好的知识组织体系。寻找适当的平衡并不容易,所以我们推荐如下几个经验法。

“ 类的子类通常(1)具有父类不具有的附加属性,或(2)槽位的限制与父类不同,或(3)参与到与父类不同的关系中。

例如,红葡萄酒可以具有不同的单宁水平,而该属性不用于描述一般葡萄酒。甜点葡萄酒的”糖“槽的取值是SWEET,但这一取值并不适用于它的所有父类。黑比诺葡萄酒可能会很好地与海鲜搭配,而其他红葡萄酒并非如此。换句话说,我们在层次结构中引入一个新类,应该有充分的理由说明,存在一定的场景只能使用这个类,而不能用它的父类来替换。

在实践中,增加一个新的子类通常应该添加新的槽位、定义新的槽位取值、或覆盖继承的槽位的某些刻面。当然,即使不引入任何新属性,有时创建新类也是有用的。例如术语层次结构中的类应该对应已有的分类常识,不一定要引入新属性。例如,电子医疗记录系统的本体可以包括各种疾病的分类。这种分类可能只是一种不具有任何属性(或具有相同属性集)的术语层次结构。在这种情况下,使用多层的层次结构而不是单层列表来保存常识中的层次结构仍然是有用的,因为它(1)允许更容易的知识探索和导航,以及(2)便于医生判定术语的一般性粒度。引入不含新属性的新类,也可能有其他原因,例如领域专家可以按常识划分模型概念,即使这些概念本身并无显著区别。本体的人性化设计可以促进领域专家之间以及领域专家和基于知识的系统之间的沟通,通过定义层次体系,我们希望反映专家对本体所表示的领域的认知。

最后,我们不应该为每个额外的限制创建一个类的子类。例如,我们介绍了红葡萄酒,白葡萄酒和玫瑰葡萄酒,因为这种区别是葡萄酒世界中的一个天然的。我们不需要为精致的葡萄酒,温和的葡萄酒等增加分类。当定义类层次结构时,我们的目标是提供有效的知识组织体系,并在创建必要的类和创建太多类之间取得平衡.

4.5 新类或属性值

在领域知识建模时,我们经常需要决定是否把具体的区别(如白色,红色或玫瑰葡萄酒)作为属性值或一组类,而这又取决于领域的范围和手头的任务。例如,我们是创建一个白葡萄酒类,还是简单地创建一个Wine类,并为“颜色”槽位填入不同的值?此问题的答案要因地制宜。具体说,需要按照本体的设计需求,提出下列问题:“白葡萄酒的概念在我们的领域有多重要?”(1) 如果葡萄酒在这个领域只有边缘的重要性,而且葡萄酒是否为白色,对该类与领域中其他类的关系没有任何特别的影响,那么我们不应该为白葡萄酒引入一个单独的类。例如,对于在生产葡萄酒商标的工厂使用的领域模型,任何颜色的葡萄酒商标都是相同的,没有必要为白葡萄酒单独建立一个类。(2)如果为了表示葡萄酒,食物及它们的合理搭配,红葡萄酒与白葡萄酒就会非常不同:二者与不同的食物配对,且具有不同的性质等等。同样,葡萄酒的颜色对于我们可以用来确定葡萄酒品尝体系的葡萄酒知识库也很重要。因此,我们应该为白葡萄酒创建了一个单独的类。

原则:如果具有不同槽位值的概念成为其他类中不同槽位的限制(值域),我们会建立一个类。否则,我们可以使用同一个类的槽位值来区分这些概念。

其次,我们的葡萄酒本​​体具有红梅洛和白梅洛等类,而不本体梅洛葡萄酒形成一个单一类。当我们正在开发一个详细的葡萄酒本​​体,我们可以认为红梅洛和白梅洛的确是不同的葡萄酒类型(即使它们是由相同的葡萄酿造的)如果我们在开发一个详尽的葡萄酒本体,这个区别是重要的。

原则:如果一个区别在领域中很重要,我们将不同取值的对象视为不同种类的对象,那么我们应该创建一个新的类来体现去这样的区别。

考虑一个类的潜在的单个实例也有助于决定是否创建一个新的类。

原则:个别实例所属的类不应该经常更改。

当我们使用外在属性而不是内在属性来区分类的概念,这些类的实例将不得不经常从一个类迁移到另一个类。例如,“冷藏葡萄酒”不应该是在餐厅酒单本体中的一个类。“冷藏”应该只是一瓶酒的属性,因为是否冷藏的状态会经常变化,“冷藏葡萄酒”的一个实例可以很容易地停止成为这个类的一个实例,然后过一段时间再次成为这个类的一个实例。

通常数字,颜色,位置会被定义为是槽位,不需要创建新类。当然葡萄酒是一个显著的例外,因为葡萄酒的颜色对葡萄酒的描述是至关重要的。

再举一个例子,比如人体解剖本体。当我们定义肋骨时,我们是否需要为“第一左肋”,“第二左肋”等为分别创建一个类?或者我们是否有一个类“肋骨”包含骨头排列和排列的位置的槽位?[5] 如果在本体中,每个肋骨的描述信息都显著不同,那么我们应该为每个肋骨创建一个类。比如说,如果要表示详细的邻接和位置信息(对于每个肋骨是不同的)以及每个肋骨和它保护的器官的具体功能关系,这些分类就是有必要的。但是,如果我们以稍小的一般性来模拟解剖结构,并且就我们的潜在应用而言,所有的肋骨都非常相似(我们只是谈论在X射线上哪个肋骨断了,但不考虑身体的其他部位)我们可以简化我们的层次结构,这个类型为肋骨,并有两个槽位:横向位置,顺序。

[5] 这里我们假设每个解剖器官都是一个类,因为我们也想谈论“约翰的第一左肋骨”。一个人的某个器官将在我们的本体中被表示为实例。

4.6一个实例或一个类?

判定一个特定的概念是本体的一个类还是一个实例,取决于本体的潜在应用场景。本体知识表示的粒度选择决定了类和实例区分的界限,而本体的粒度又由本体的潜在应用决定。换句话说,知识库中最具体的对象是什么?回顾我们在第3节第1步中确定的能力问题,构成答案的最具体的概念是知识库中实例的非常好的候选者。。

原则:个体实例是知识库中最具体的概念。

例如,如果我们只是谈论葡萄酒与食物的合理搭配,我们不会对具体的实际的一瓶酒感兴趣,那么像 斯特林葡萄园梅洛 (Sterling Vineyards Merlot)这样的术语可能是我们使用的最具体的术语。因此,斯特林葡萄园梅洛 (Sterling Vineyards Merlot)将成为知识库中的一个概念。

另一方面,如果我们想要在餐厅中管理葡萄酒的库存,除了具有良好的葡萄酒食品搭配配对的知识库外,还可以将每一瓶酒变成为我们知识库中的一个实例。

同样,如果我们想记录不同年份斯特林葡萄园梅洛 (Sterling Vineyards Merlot)葡萄酒的属性,那么每一个特定年份的斯特林葡萄园梅洛 (Sterling Vineyards Merlot)葡萄酒都是知识库中的一个实例,这些实例所属的类是斯特林葡萄园梅洛 (Sterling Vineyards Merlot类。

有些规则可以将一些实例“移动”到一组类中

原则:如果概念形成一个自然层次结构,那么我们应该将它们表示为一组类。

以葡萄酒产区为例,最初我们可以定义主要葡萄酒产区,如法国,美国,德国等,然后从这些大区域的组成细化定义特定葡萄酒产区。举例说,“勃艮第地区”可以是“法国地区”类的一个实例。但是我们也想说科尔多地区(Côte-d'Or)是勃艮第地区( Bourgogne region )的一部分。这样,“勃艮第地区“就应该是一个类,这样才能有有子类或实例。不过,指定”勃艮第地区( Bourgogne region )为一个类别,然后指定科尔多地区(Côte-d'Or)是”勃艮第地区( Bourgogne region )的一个实例,这些做法随意性很强。开发者很难明确区分哪些地区应该是类,而哪些是实例。因此我们不妨将所有葡萄酒产区都定义为类。 Protege -2本体允许用户将一些类指定为抽象类,表示该类没有任何直接的实例。在我们的例子中,所有地区类都是抽象的。

如果我们从类名中省略了“地区”这个词,则相同的类层次结构将是不正确的。我们不能说阿尔萨斯是法国的一个子类,因为“阿尔萨斯”不是一种“法国”。然而,阿尔萨斯地区“是一种”法国地区。只有类可才可以被安排在一个层次结构上 - 知识体系中没有一个“子实例”的概念。因此,如果术语之间存在自然的层次结构,例如在第4.2节的术语层级中,我们应该将这些术语定义为类,即使它们可能没有任何自己的实例.

4.7限制范围

作为定义层次结构的最后一段讨论,以下一组规则用于本体体定义的完整性:

原则:本体不需要包含有关领域的所有可能信息:您不需要专门化(或泛化)超出应用程序的需求(本体专门化或泛化的方向最多一层)。

对于我们的葡萄酒和食品的例子,我们不需要知道葡萄酒的商标用什么纸制成或海鲜菜的制作方法。类似地,

原则:“本体不不需要包含所有可能的属性和类之间区别”。

在我们的本体中,我们当然不必囊括葡萄酒或食物可能具有的所有属性,而只需要包括我们关注类中最关键的属性。即使葡萄酒书籍告诉我们葡萄的大小,本体中不必非要包括这些知识。同样,我们也不必添加所有在系统中的所有术语之间任意关系。例如,我们在本体中不包括“最受欢迎葡萄酒”和“最受欢迎的食物”等关系。

这条最后的规则也适用于限制本体中已有概念之间的关系。以生物学实验的本体为例,本体可能包含生物有机体的概念,还包含执行实验的实验者的概念(包括他的名字,隶属关系等)。尽管实验者作为一个人的也恰好是一个生物有机体(也就是说,一个实验者类是生物有机体类的一个子类),但我们没有必要将这个区别关系纳入本体。换言之,实验者不是“一种”生物体,因为我们可能永远不会对实验者本身进行实验。在实践中,我们不需要在可预见的应用程序中包含上述子类关系。事实上,引入这个子类关系甚至会带来负面影响:实验者的一个实例将具有与生物有机体有关的重量,年龄,物种和其他数据的槽位,但这些多余的槽位与在描述实验的背景的目标毫不相关。当然我们应该在文档中记录这样设计的决策原因,以便将要查看本体的用户了解设计初衷。(他们可能不了解本体设计时所考虑的应用场景)

4.8 不相交的子类

许多系统允许我们明确指定几个类是不相交的。如果没有任何共同的实例,两个类是不相交的。例如,我们本体中的甜点葡萄酒和白葡萄酒课程并非不相交:有许多葡萄酒都是两者的实例。例如,“罗瑟梅尔枯萄精选雷司令(Rothermel Trochenbierenauslese Riesling)”是甜点雷司令类的一个实例,也是白葡萄酒的一个实例。另一方面,红葡萄酒和白葡萄酒不相交的:没有酒可以同时是红色和白色。指定类是不相交的,可以使系统更好地校验本体。如果我们声明红葡萄酒和白葡萄酒类是不相交的,之后创建一个类,它同时是雷司令(白葡萄酒的一个子类)和波尔图(Port Wine)(红葡萄酒的一个子类)的子类时,系统通过推理可以发现此建模错误。

Last updated

Was this helpful?