关于Apache Jena Ontology API
利用Apache Jena进行本体论的使用
据说,Apache Jena是一个与RDF4J并列广泛使用的RDF库。虽然Jena的功能更多,但学习起来相对困难。
实际上,若只是创建普通的RDF,相当容易。但是,一旦涉及到处理OWL等本体论,突然感觉难度增加了很多。
在Apache Jena中,提供了处理RDFS、OWL等的一致API。考虑到日语资源相对较少,因此在此留下备忘录。
Ontology API的基本知识
OWL可以被视为RDFS(RDF Schema)的超集,可以表示大部分可以使用RDFS表示的内容。例如,RDF属性可以被层次化表示,但是在OWL属性中可以扩展为可传递、语义、功能等。此外,还可以描述相互(逆)关系。
顺便提一下,OWL有两个版本:基于描述逻辑进行严格类型区分的OWL DL,以及专注于实用本体构建的OWL Full。此外,还提供了更易于实现的OWL DL子集,即OWL Lite。
使用本体论的好处是可以使用推理器对数据进行推断。Jena提供了推理API,可以使用各种推理引擎。
基本类是OntClass,在这个类中可以表示各种模式(配置文件)。这个类扩展了Jena的Model类,并定义了在本体中规定的约束(构建)。具体来说,可以通过以下方式使用工厂方法生成。
OntModel m = ModelFactory.createOntologyModel();
在这种情况下,将使用默认设置(OWL-Full、In-Memory、RDFS推理)进行生成。由于通常会有很大负载,所以应使用合适的设置。在这种情况下,请输入OntModelSpec作为参数。如下所示。关于要使用的语言配置文件(OWL Full、OWL DL、OWL Lite、RDFS),也可以在此参数中进行设置。有16个配置文件可供选择。请具体参考API文档。
OntModel m = ModelFactory.createOntologyModel( OntModelSpec.OWL_MEM);
在Jena的本体模型中,如果要处理多个本体,则需要具有导入模型集合的功能。与一般的Jena使用方式相同,导入本体时也使用read方法。
read( String url )
read( Reader reader, String base )
read( InputStream reader, String base )
read( String url, String lang )
read( Reader reader, String base, String Lang )
read( InputStream reader, String base, String Lang )
当加载本体时,默认情况下会包含其自身的引用URI。 具体而言,用rdf:about指定的URI。 在官方网站的示例中介绍如下。 使用owl:import引用和加载的本体被指示出来。 “dc”是指Dublin Core吗?
<owl:Ontology rdf:about="">
<dc:creator rdf:value="Ian Dickinson" />
<owl:imports rdf:resource="http://jena.apache.org/examples/example-ont" />
</owl:Ontology>
被如此加载的本体被保留为不同的图结构。如果有多个被加载,它们将作为联合图被整合并由推理器引用。
有许多选项可以用于使用这些本体论进行RDF持久化等方面。官方网站提供了以下示例。OntDocumentManager是一个辅助处理本体论的模块,在其中调用addAltEntry方法。它描述了将从互联网上获取的ESWC本体论复制到本地RDF并进行处理的过程。要记住所有这些内容确实很困难啊。。。
OntModel m = ModelFactory.createOntologyModel();
OntDocumentManager dm = m.getDocumentManager();
dm.addAltEntry( "http://www.eswc2006.org/technologies/ontology",
"file:" + JENA + "src/examples/resources/eswc-2006-09-21.rdf" );
m.read( "http://www.eswc2006.org/technologies/ontology" );
在Scala上的练习
似乎在世界上有一种名为 banana-rdf 的 Scala 原生实现,但由于缺乏详细文档,我想尝试使用 Scala 封装 Jena。
这次我将用Ammonite在REPL中写下步骤。
// Jenaのダウンロード
import $ivy.`org.apache.jena:jena-core:3.8.0`
import scala.collection.JavaConverters._
import org.apache.jena.rdf.model._
import org.apache.jena.ontology.OntModelSpec._
// ベースモデルを生成
val SOURCE = " http://rdfs.org/sioc/ns"
val NS = SOURCE + "#"
val base = ModelFactory.createOntologyModel(OWL_MEM)
base.read(SOURCE, "RDF/XML")
// ベースモデルによる推論モデルを生成
val inf = ModelFactory.createOntologyModel(OWL_MEM_MICRO_RULE_INF, base)
val user = base.getOntClass(NS + "UserAccont")
val u1 = base.createIndividual(NS + "user1", user)
u1.listRDFTypes(true).toList.asScala.foreach{`type` => println( c1.getURI() + " is asserted in class " + `type`}
// http://rdfs.org/sioc/ns#account1 is asserted in class http://rdfs.org/sioc/ns#UserAccount
val inf_user = inf.getIndividual(NS + "user1")
inf_user.listRDFTypes(true).toList.asScala.foreach{`type` => println( inf_user.getURI() + " is asserted in class " + `type`}
// http://rdfs.org/sioc/ns#account1 is asserted in class http://rdfs.org/sioc/ns#UserAccount
// http://rdfs.org/sioc/ns#account1 is asserted in class http://rdfs.org/sioc/ns#User
首先,我们会从网络上获取本体,并进行加载。
接下来,我们会参考本体的类来创建Individual(通过getOntClass的部分),然后通过createIndividual进行创建。
最后一部分是通过使用生成的Individual的URI进行推理。listRDFTypes的布尔参数用于表示它是否直接(Direct)引用了类。在上面的注释中的输出中,显示了两个类,但如果参数为false,则可以获得以下输出。你应该大致理解了意思吧。
http://rdfs.org/sioc/ns#account1 is asserted in class http://rdfs.org/sioc/ns#UserAccount
http://rdfs.org/sioc/ns#account1 is asserted in class http://rdfs.org/sioc/ns#User
http://rdfs.org/sioc/ns#account1 is asserted in class http://www.w3.org/2002/07/owl#Thing
http://rdfs.org/sioc/ns#account1 is asserted in class http://www.w3.org/2000/01/rdf-schema#Resource
http://rdfs.org/sioc/ns#account1 is asserted in class http://xmlns.com/foaf/0.1/OnlineAccount
此外,还有很多其他需要记住的东西,例如属性描述和约束条件的描述等等。无论如何,通过使用Ontorogy API,我们可以发现可以利用既有的本体进行各种推理。
今天到此为止。