我的本体是图书分类库。我在这方面有问题。我想通过 protégé 4.1 构建一个书籍分类本体,这个分类有 14 个类别,除了兄弟类 Author、book、Isbn。book 类的个人是 book 的主题(约 600 个主题),author 类的个人是 name 的作者,也是 isbn 类。然后我对对象属性和数据类型属性感到困惑。如果 hasEdition 在我的本体中的属性中,那么我说类书中的每一本书都与版本类有关系。所以我使用对象属性,但这个类(版本类)中的个体是整数<9。那怎么能说出来呢?它是数据类型还是对象?并且可以使用对象属性与数据类型属性吗?(同名)
1 回答
关于对象和数据类型属性
在 Protégé 中有不同的选项卡用于创建对象属性和数据类型属性。如果一个属性应该将个人与个人联系起来,那么它需要是一个对象属性,如果它将个人与文字联系起来,那么它需要是一个数据类型属性。
如果你有一个属性hasEdition
域是Book
,那么问题就变成了范围应该是什么。如果您期望三倍,例如:
Book72 hasEdition "1"^^xsd:int
Book16 hasEdition "3"^^xsd:int
其中值是文字,则hasEdition
应该是数据类型属性。另一方面,如果您的班级Edition
有一些特定的人,例如,
Edition a owl:Class .
first a Edition .
second a Edition .
third a Edition .
…
这样你就可以拥有
Book72 hasEdition first .
Book16 hasEdition third .
thenhasEdition
应该是一个对象属性。
如果您需要查看 RDF 序列化并确定属性是哪些类型,您应该查询类owl:ObjectProperty
和owl:DatatypeProperty
(并且,为了完整起见,owl:AnnotationProperty
)。也就是说,取决于hasEdition
您将看到的是对象属性还是数据类型属性:
hasEdition a owl:ObjectProperty .
或者
hasEdition a owl:DatatypeProperty .
决定使用哪个
您希望hasEdition
属性是数据类型属性还是对象属性实际上取决于您要存储的数据类型,这取决于您的应用程序。如果您只是表示简单的信息,例如"first"
、"second"
等,那么您可能希望使用将一本书与其版本相关联的数据类型属性。如果您抽象地表示书籍,即不是书籍的单个实例(与书商的库存系统相反,它会关注书籍的单个实例),这可能是一条好路线。
另一方面,如果您实际代表的是书籍实例。例如,如果您是书商,并且有 25 份Semantic Web for the Working Ontologist和 27 份Programming the Semantic Web库存),那么您实际上可能有兴趣代表书籍的各个版本,其标题为 ISBN , 等可能会存储在版本上,而不是书本上。
这只是一种意见,您在选择数据模型时确实有很大的灵活性。获得好的数据模型通常需要一些经验,而经验需要时间。即便如此,您也有很好的工具来处理和转换数据,因此您可以尝试不同的表示,并从一个映射到另一个。
选择其中之一的后果示例
我建议您看一下RDF Primer。资源和文字是不同类型的事物。资源是匿名的或由 IRI 标识的,并且可以是语句的主题(因此是类的成员,由于语句
@prefix lib: <http://example.org/library/> .
lib:HermanMelville rdf:type lib:Author .
文字,例如字符串"Herman Melville
“不能成为句子的主语,因此不能成为类的成员。将作者作为资源(个人),您可以这样做
lib:MobyDick lib:hasAuthor lib:HermanMelville .
lib:HermanMelville lib:hasName "HermanMelville"@en .
在这种情况下,hasAuthor
是一个对象属性并且hasName
是一个数据类型属性。
另一方面,您可以创建hasAuthor
一个数据类型属性,而不是
lib:MobyDick lib:hasAuthor "Herman Melville"@en .
但是,如果您这样做,那么您就没有方便的方法来添加有关作者的任何其他信息,因为文字"Herman Melville"@en
不能成为三元组的主题,因此您不能例如说
"Herman Melville"@en places:livedAt places:Arrowhead .
而在第一种情况下,你可以说
lib:HermanMelville places:livedAt places:Arrowhead .
这实际上只是您希望如何查询数据的问题。如果hasAuthor
是对象属性,我可以编写这样的查询来查找居住在 Arrowhead 的作者所写的书籍:
PREFIX lib: <http://...>
PREFIX places: <http//...>
SELECT ?book WHERE {
?book lib:hasAuthor ?author .
?author places:livedAt places:Arrowhead .
}
甚至更简洁(但等效):
PREFIX lib: <http://...>
PREFIX places: <http//...>
SELECT ?book WHERE {
?book lib:hasAuthor [ places:livedAt places:Arrowhead ] .
}
另一方面,如果hasAuthor
是一个将书与其作者姓名相关联的数据类型属性,我们仍然可以有一个Author
类,其实例通过该hasName
属性与其姓名相关联,但这使得查询数据有点复杂,因为hasAuthor
属性是强制一层间接(获取书的作者的名字,然后找到有这个名字的作者),所以我们有这样的查询:
PREFIX lib: <http://...>
PREFIX places: <http//...>
SELECT ?book WHERE {
?book lib:hasAuthor ?authorName .
?author lib:hasName ?authorName .
?author places:livedAt places:Arrowhead .
}
这个查询不能被简化得这么好。这真的归结为您希望如何查询您的数据,以及什么对您来说很方便。请注意,您可以在 SPARQL 中编写的一些查询很难编写为 OWL DL 表达式。WhenhasAuthor
是一个对象属性,其作者住在 Arrowhead 的书籍类别由以下表达式给出:
lib:hasAuthor (places:livedAt value places:Arrowhead)
这只是一类有一位住在箭头的作者的东西。如果hasAuthor
是一个数据类型属性,写这样一个表达式要困难得多,如果不是不可能的话,因为你需要找到两个具有相同文字值的东西(一本书和一个作者)(作者姓名的字符串) .