我有一些数据三元组,我想用某种基本的 OWL 本体编写。我有三胞胎,例如:
Delhi is part of India
或者
India is an Asian country
请注意,我有“is-a”、“part-of”或“related-to”等关系。构建本体的最简单方法是什么?任何工作示例或对示例网站的引用都会有很大帮助!
您的问题中混杂了很多不同的东西,我强烈建议您花点时间(远离键盘!)来思考您要在这里实现的目标。
首先,地理本体会变得相当复杂,并且在这方面已经做了很多工作。可能明显的起点是GeoNames 本体,它为地理特征命名,包括像德里这样的城市和像印度这样的国家。至少,您应该在应用程序中重新使用这些名称,因为这将最大限度地提高您的数据与其他可用链接数据源成功连接的机会。
但是,您可能不希望应用程序中包含整个 GeoNames(我猜),因此您还需要清楚为什么需要本体。解决此问题的一个好方法是从您的应用程序外部:与其担心使用哪种 Jena 模型,不如先考虑如何完成这句话“使用本体,我的应用程序的用户将能够. ……”。这应该会引导您建立一些能力问题(例如,参见本指南的第 3 节) 为您的本体。一旦你知道你想要表示什么样的信息,以及你需要对其应用什么样的查询,你的技术选择就会更加清晰。我意识到这些应用程序通常是迭代开发的,你会想尽早尝试一些代码,但我仍然主张在开始编码之旅之前更清楚地记住你的目标。
您暗示您想使用 Jena 来驱动一个网站。这里有很多选择。不要被语义网这个术语误导——这实际上意味着将类似网络的特性引入到内联的数据集中,而不是将语义放入人类可读的网页本身。虽然您可以这样做,而且很多人都这样做,但您的架构中需要一些额外的层。我们通常使用以下两种方法之一:在 servlets 容器中使用 Jena 和模板引擎,例如Velocity,或者使用 Ruby Web 框架并通过JRuby驱动 Jena 。还有许多其他方法可以解决这个特定问题: Jena 不直接解决 Web 发布问题,但它可以在任何基于 Java 的 Web 框架中使用。
最后,关于命名空间,你应该尽可能地重用现有的词汇表,从而重用命名空间。不要为已经在某处数据网络上具有表示的事物编造新名称。使用 GeoNames 或DbPedia或任何其他适合的已发布词汇表。如果它们不适合,那么您应该创建一个新名称,而不是以不兼容的方式使用现有名称。在这种情况下,您应该使用应用程序(例如您的公司或大学)的 Web 域作为命名空间的基础。理想情况下,您应该在命名空间的基本 URL 上发布您的本体,但这有时可能很难根据本地 Web 策略进行安排。
我建议曼彻斯特大学的OWL API。通过这种方式,您可以开始在 Java 中“即时”创建您的本体,如果需要,您可以通过单个方法调用将其序列化为您喜欢的格式(RDF、曼彻斯特语法等),或者直接处理 in-内存表示。通过这种方式,您可以在程序的上下文中快速原型化和试验您的本体。
对于库及其主要组件的概述,我建议使用库创建者提供的教程(代码教程),它涵盖了 90% 的基本需求。
PS:Protégé 是基于 OWL Api 的,你也可以按照建议尝试一下,但特别是一开始我更喜欢快速玩本体,当我头脑足够清晰时切换到像 Protege 这样的工程环境。此外,使用外部本体,您需要学习如何导航它,恕我直言,一开始它真的不值得。
看看斯坦福的Protege。它是一个本体编辑器。
您只需声明一个由主语、宾语和谓词组成的三元组类。“has-a”是一个谓词,所以你的本体元素看起来像:
"Dehli", "is-in", "India"
"India", "is-in", "Asia"
"India", "is-a", "country"
当然,这并不能解决查询问题,但是如果有一个不错的数据存储(即使是数据库也可以),您就可以开始使用一个不错的查询机制构建一个灵活的本体。
当然,JENA 的能力远远超过它所创造的能力。它确实提供了语义查询的东西,以及更好的资源定义和解析。但是,它比简单的三元组结构要复杂得多。这一切都取决于你需要什么。
/**
- This is maven dependencies for owl-api
<dependency>
<groupId>net.sourceforge.owlapi</groupId>
<artifactId>owlapi-api</artifactId>
</dependency>
<dependency>
<groupId>net.sourceforge.owlapi</groupId>
<artifactId>owlapi-apibinding</artifactId>
</dependency>
* First of all you need to initialize ontology:
**/
private OWLDataFactory factory;
private PrefixManager pm;
private OWLOntology ontology;
private String pmString = "#";
private OWLOntologyManager manager;
private OWLReasoner reasoner;
private ShortFormEntityChecker entityChecker;
private BidirectionalShortFormProviderAdapter bidirectionalShortFormProviderAdapter;
private void initializeOntology(String fileContent)
throws OWLOntologyCreationException {
InputStream bstream = new ByteArrayInputStream(fileContent.getBytes());
this.manager = OWLManager.createOWLOntologyManager();
this.ontology = this.manager.loadOntologyFromOntologyDocument(bstream);
IRI ontologyIRI = this.ontology.getOntologyID().getOntologyIRI();
this.pm = new DefaultPrefixManager(ontologyIRI.toString()
+ this.pmString);
this.factory = this.manager.getOWLDataFactory();
ReasonerFactory factory = new ReasonerFactory();
this.reasoner = factory.createReasoner(this.ontology);
Set<OWLOntology> onts = new HashSet<>();
onts.add(this.ontology);
DefaultPrefixManager defaultPrefixManager = new DefaultPrefixManager(
this.pm);
ShortFormProvider shortFormProvider = new ManchesterOWLSyntaxPrefixNameShortFormProvider(
defaultPrefixManager);
this.bidirectionalShortFormProviderAdapter = new BidirectionalShortFormProviderAdapter(
this.manager, onts, shortFormProvider);
this.entityChecker = new ShortFormEntityChecker(
this.bidirectionalShortFormProviderAdapter);
}
/*
After that you need to define your classes and the relations of the classes. These relations calls as object properties in ontology. Instance of each ontology class calls as individual and the attributies of the classes (for person name, age , adress) calls as data-property.
*/
// To create a new individual of an ontology class :
public OWLClass getClass(String className) {
return this.factory.getOWLClass(":" + className, this.pm);
}
public OWLNamedIndividual createInvidual(String cls, String invname) {
OWLNamedIndividual res = this.factory.getOWLNamedIndividual(":"
+ invname, this.pm);
this.manager.addAxiom(this.ontology,
this.factory.getOWLDeclarationAxiom(res));
OWLClassAssertionAxiom axiom = this.factory.getOWLClassAssertionAxiom(
getClass(cls), res);
this.manager.addAxiom(this.ontology, axiom);
return res;
}
// To create an object property :
// This method will create an object property named prop if it is not exist.
public OWLObjectProperty getObjectProperty(String prop) {
return this.factory.getOWLObjectProperty(":" + prop, this.pm);
}
public void addObjectProperty(String propname, OWLNamedIndividual prop,
OWLNamedIndividual obj) {
OWLObjectPropertyAssertionAxiom axiom = this.factory
.getOWLObjectPropertyAssertionAxiom(
getObjectProperty(propname), obj, prop);
this.manager.addAxiom(this.ontology, axiom);
}
// And finally , to add a data-property to individuals :
public OWLDataProperty getDataProperty(String prop) {
return this.factory.getOWLDataProperty(":" + prop, this.pm);
}
public void addDataProperty(String propname, boolean propvalue,
OWLNamedIndividual inv) {
OWLAxiom axiom = this.factory.getOWLDataPropertyAssertionAxiom(
getDataProperty(propname), inv, propvalue);
this.manager.addAxiom(this.ontology, axiom);
}