05 - Protege & OWL API 的使用 - 本科毕设整理

  • 我的本科毕设题目是《基于家居环境的智能推理引擎设计》,跟我的专业通信工程似乎……第一次接触语义网(Sementicweb)和网络本体语言(OWL)。主要研究了智能家居关键技术,分析了多种场景的智能家居环境特点、推理机技术,设计实现了一种基于家居环境的智能推理引擎。

当然,上面都是废话…当初累死累活找不到什么资料,现在…拖了这么久,整理一下Protege和OWL API的使用,万一有师弟师妹拿到这种鬼一样的毕设题目,或者…甚至听闻我这毕设要被做成MOOC和下届本科生的程序设计实验课程题目,哎,标准的坑货学长了。

本文会涉及到的东西:OWL语言;Protege;Jena(划掉);本体Ontology;

不想看基础的废话的朋友可以直接拉到第三章看例子。

更新:
后来毕设拿去发了个很水的EI…

  • C. Zhang, X. Wen, W. Zheng, Z. Lu and L. Wang, “A Design of Decision Engine for 5G Auto-driving Based on Ontology Slice,” 2019 IEEE 5th International Conference on Computer and Communications (ICCC), Chengdu, China, 2019, pp. 1016-1022.
  • 毕设demo的源码:github.com/KujouOct/DecisionEngine-demo (毕业多年已经忘光了emmm)

第一章 Protege

1、是啥

  • 是斯坦福大学开发的OWL语言本体构建工具。官网了解一下:
    https://protege.stanford.edu

  • 基于Java,可视化界面,内置推理机和SWRL等插件,支持更多插件扩展

  • 功能完备,OWL API中的功能基本全都覆盖到了

  • 下载地址就在官网首页。
    或者我的百度云:
    Protege5.2 https://pan.baidu.com/s/1U5KaSwZLpHpULyERlfKw2w 密码:fydl

调研了Protege之后的我:“这东西这么6,我们还用啥JESS,Jena,OWL API啊?”
“别人能上天,我们就不上了么?”


2、Protege咋用啊(创建本体)

  • 界面
    界面
    界面花花绿绿,还算友好。比起枯燥的代码构建本体,人性化多了。
    当然刚一启动Protege肯定没这么多窗口,可以从WindowViews里调出各种窗口,建议先搞出来Class hierarchy、Class Description、Individuals、Individual Description、Individual Property Assertion、Object Property等这几个窗口。
  • 2.1 声明类(Class)

菜单点击file, new.每个本体有一个总的类owl:Thing。
我们在这个类的下面声明一个子类(subclass),比如输入设备iDevices:
点击图2-1(Add subclass),Name就叫iDevices。
图2-2
再声明输出设备oDevices类,可以点回到owl:Thing然后声明子类,也可以直接声明sibling class
图2-3

同理我们再声明一些类,就能实现一个类的架构出来。
图2-4

类的属性有:
图2-5
点击后面的加号就可以声明相应的属性,其中Equivalent To属性声明的是当满足这一条件时这个类等同于另一个指定的类;Subclass of,Disjoint with等顾名思义。

  • 2.2 声明个体(Individual)

点击图2-6声明个体,声明个体之后在这个个体的Description里可以声明它属于哪个类,在 Property Assertion里声明它具有的对象属性数据属性等。

  • 2.3 对象属性

在本体中如何表示“我是你师兄”这样一种关系呢?那就要用到对象属性。比如“人”这个类下的个体“我”具有“isFatherOf”,啊不是,具有“isBrotherOf”的对象属性,对象是“你”:
在 Object Property 里创建isBrotherOf这一对象属性,在 对象“我”的property assertion里声明
图2-7
这就行了。

  • 2.4 数据属性
    跟对象属性差不多,顾名思义数据属性,比如先声明Temperature这一数据属性,在代表温度传感器的个体XTemp里声明它具有Temperature这一数据属性,值是30 (℃):
    图2-8

type?整成integer还是整成float看你喜好。


再咋用啊(创建规则库)

  • 2.5 SWRLTab的使用
    由于用OWL语言直接写规则很麻烦,可读性也较差(看个例子?:),因此可以用SWRL这个很棒的插件。
    例:温度高过阈值了开空调并保持其他制热设备关闭 的规则OWL语言实现:
<DLSafeRule>
        <Annotation>
            <AnnotationProperty IRI="http://swrl.stanford.edu/ontologies/3.3/swrla.owl#isRuleEnabled"/>
            <Literal datatypeIRI="http://www.w3.org/2001/XMLSchema#boolean">true</Literal>
        </Annotation>
        <Annotation>
            <AnnotationProperty abbreviatedIRI="rdfs:comment"/>
            <Literal datatypeIRI="http://www.w3.org/2001/XMLSchema#string">温度高开启空调制冷</Literal>
        </Annotation>
        <Annotation>
            <AnnotationProperty abbreviatedIRI="rdfs:label"/>
            <Literal datatypeIRI="http://www.w3.org/2001/XMLSchema#string">S1</Literal>
        </Annotation>
        <Body>
            <ClassAtom>
                <Class IRI="#HTemp"/>
                <Variable IRI="#p"/>
            </ClassAtom>
            <ClassAtom>
                <Class IRI="#iDevices"/>
                <Variable IRI="#p"/>
            </ClassAtom>
            <ObjectPropertyAtom>
                <ObjectProperty IRI="#hasTemp"/>
                <Variable IRI="#p"/>
                <Variable IRI="#y"/>
            </ObjectPropertyAtom>
        </Body>
        <Head>
            <ObjectPropertyAtom>
                <ObjectProperty IRI="#TurnCold"/>
                <NamedIndividual IRI="#Air"/>
                <NamedIndividual IRI="#TestSucc"/>
            </ObjectPropertyAtom>
            <ObjectPropertyAtom>
                <ObjectProperty IRI="#TurnOff"/>
                <NamedIndividual IRI="#Control"/>
                <NamedIndividual IRI="#Fireplace"/>
            </ObjectPropertyAtom>
            <ObjectPropertyAtom>
                <ObjectProperty IRI="#TurnOff"/>
                <NamedIndividual IRI="#Fireplace"/>
                <NamedIndividual IRI="#TestSucc"/>
            </ObjectPropertyAtom>
            <ObjectPropertyAtom>
                <ObjectProperty IRI="#TurnOn"/>
                <NamedIndividual IRI="#Control"/>
                <NamedIndividual IRI="#Air"/>
            </ObjectPropertyAtom>
        </Head>
    </DLSafeRule>

而SWRL的实现呢?

iDevices(?p) ^ hasTemp(?p, ?y) ^ HTemp(?p) -> TurnOn(Control, Air) ^ TurnCold(Air, TestSucc) ^ TurnOff(Fireplace, TestSucc) ^ TurnOff(Control, Fireplace)

SWRL的官网:http://www.w3.org/Submission/SWRL/
当然,如果你直接按照官网给的例子写规则是会报错的,大概是他们太久没更新了语法不太对……至于SWRL的语法,看上面那个例子也就很清楚了吧。简单解释一下就是:
iDevices里的某个个体(?p),它具有对于另一个体(?y)的对象属性(hasTemp)并且( ^ )它也是高温(Htemp)类的个体,那么(->)就让个体Control具有对于Air的对象属性TurnOn以及 吧啦吧啦吧啦后面一串规则。
当你搞了一坨规则以后:
图2-9

更新:补充一下吧,关于在swrl规则里用swrlb:lessThan等Built-In来推理的时候,HermiT并不支持,测试发现Pellet支持较好,附一条测试Pellet用的swrl规则例子:
距离小于十米则减速:

Environment(?p) ^ Distance(?p, ?x) ^ swrlb:lessThan(?x, 10) -> OPSpeedDown(Controltest, Controltest)

SWRL所有的Build-In都在官网列出了,需要的可以自己查阅。

  • 2.6 本体内的参数决策
    利用Class 的Equivalent To属性,比如温度Temp类下有高温HTemp低温LTemp和常温NTemp等等不想disjoint的子类,可以通过让Temp类的个体,若其Temperature数据属性大于某个值就等同于高温类HTemp,就可以完成本体内的决策。
    以LTemp为例
    图2-喵喵喵?
    它的Equivalent To属性声明是这样的
Temperature some xsd:integer[<= 10]

需要注意的是……

大于等于的写法[>=10],=号和后面的数字之间不需要空格
小于等于的写法[<= 10],=号和后面的数字必须要由空格,不然报错
喵喵喵?这是什么鬼bug……

最后,
保存你创建的本体,会生成相应的.owl文件

用Protege构建本体就到这吧。


第二章 OWL API

基于OWL API可以做些简单的开发,对本科生来说目的肯定是入门一下Java和HTML。主要包括:

  • 读取本体,创建本体Model

  • 修改本体中某些数值、属性等

  • 调用推理机,根据本体中的规则库进行推理

1.读取本体

  • 1.1 读本体文件
JFileChooser FileChooser = new JFileChooser();
FileChooser.setCurrentDirectory(new File("C://Users/Doraoct/eclipse-workspace/InferenceEngine/ontology/"));
FileChooser.setDialogTitle("请选择本体文件");
int returnVal = FileChooser.showOpenDialog(null);
	if(JFileChooser.APPROVE_OPTION == returnVal)
	{
		InFilePosition = FileChooser.getSelectedFile();
……
……
……
	}
  • 1.2 创建本体Model
OWLOntologyManager 	OOM 		= OWLManager.createOWLOntologyManager();
OWLOntology 		myOntology 	= OOM.loadOntologyFromOntologyDocument(InFilePosition);
OWLDataFactory 		DF		 	= OOM.getOWLDataFactory();
  • 1.3 例:把前端输入的温度写进本体

(为啥要前端输入?还不是因为没有真的传感器)

OWLDataProperty 	Temperature = DF.getOWLDataProperty		(IRI.create(base+"#Temperature"));
OWLNamedIndividual 	IndiXT 		= DF.getOWLNamedIndividual	(IRI.create(base + "#XTemp"));
OWLDataPropertyAssertionAxiom ODPAA = DF.getOWLDataPropertyAssertionAxiom(Temperature, IndiXT,InsideTemp);
IRI 				documentIRI = OOM.getOntologyDocumentIRI(myOntology);
AddAxiom 			addAxiom 	= new AddAxiom(myOntology, ODPAA);
OOM.applyChange(addAxiom);
  • 1.4 例:从本体读温度传感器数值
Map<OWLDataPropertyExpression, Set<OWLLiteral>> ODPV=IndiXT.getDataPropertyValues(myOntology);
String StringODPV = ODPV.toString();
StringODPV=StringODPV.trim();//去空格
//输出是标签形式的一长串,往前端显示数字的话可以百度个代码吧string里的数字拿出来就是了。我的代码实在没脸放。
  • 1.5 调用HermiT或Jena推理机
//ReasonerFactory RF = new ReasonerFactory();  //调用jena默认推理机
OWLReasonerFactory RF = new Reasoner.ReasonerFactory();//调用HermiT 推理机
OWLReasoner reasoner = RF.createNonBufferingReasoner(myOntology);
System.out.println(reasoner.getReasonerName()+"版本信息:"+reasoner.getReasonerVersion());
reasoner.precomputeInferences();//Infer All	
ArrayList<InferredAxiomGenerator<? extends OWLAxiom>> IAG = new ArrayList<InferredAxiomGenerator<? extends OWLAxiom>>();			     	

下面的输出选项可供选择你想要输出的推理结果:

IAG.add(new InferredSubClassAxiomGenerator());
IAG.add(new InferredClassAssertionAxiomGenerator());
IAG.add(new InferredDataPropertyCharacteristicAxiomGenerator());
IAG.add(new InferredDisjointClassesAxiomGenerator());
IAG.add(new InferredEquivalentClassAxiomGenerator());
IAG.add(new InferredEquivalentDataPropertiesAxiomGenerator());
IAG.add(new InferredEquivalentObjectPropertyAxiomGenerator());
IAG.add(new InferredInverseObjectPropertiesAxiomGenerator());
IAG.add(new InferredSubDataPropertyAxiomGenerator());
IAG.add(new InferredObjectPropertyCharacteristicAxiomGenerator());
IAG.add(new InferredPropertyAssertionGenerator());
IAG.add(new InferredSubObjectPropertyAxiomGenerator());
  • 1.6 读取个体的对象属性(可用于读取推理结果呀)
OWLNamedIndividual IndiAir = DF.getOWLNamedIndividual(IRI.create(base + "#Air"));
Map<OWLObjectPropertyExpression, Set<OWLIndividual>> OOPA=IndiAir.getObjectPropertyValues(Inquire);
tempStr=OOPA.toString();
//你自己的判断规则,我只是举个例子
if (tempStr.indexOf("#TurnCold>=[<http://www.semanticweb.org/doraoct/ontologies/2018/2/untitled-ontology-7#TestSucc>]")!=-1){textField_25.setText("制冷中");}
if (tempStr.indexOf("#TurnHot>=[<http://www.semanticweb.org/doraoct/ontologies/2018/2/untitled-ontology-7#TestSucc>]")!=-1){textField_25.setText("制热中");}
if (tempStr.indexOf("#TurnOff>=[<http://www.semanticweb.org/doraoct/ontologies/2018/2/untitled-ontology-7#TestSucc>]")!=-1){textField_25.setText("已关闭");}
				        
  • 1.7 如果你真的像我一样头铁要尝试用OWL写规则进本体……
//哎,比如大于等于0不能直接声明成>=0,必须得声明称一个OWLFacetRestriction
OWLFacetRestriction dayudengyu0 = DF.getOWLFacetRestriction(MIN_INCLUSIVE, DF.getOWLLiteral(0));
OWLFacetRestriction xiaoyudengyu15 = DF.getOWLFacetRestriction(MAX_INCLUSIVE, DF.getOWLLiteral(15));
//气哭了
OWLDataRange LTempDR = DF.getOWLDatatypeRestriction(integerDatatype,dayudengyu0,xiaoyudengyuXXXTemp);//设定数值限制
OWLDataSomeValuesFrom LTR = DF.getOWLDataSomeValuesFrom(Temperature, LTempDR);//将数值显示应用到Teperature属性
OWLClassExpression LTE = DF.getOWLObjectIntersectionOf(Temp, LTR);//将属性添加到Temp属性下
OWLEquivalentClassesAxiom LTEq = DF.getOWLEquivalentClassesAxiom(LTemp, LTE);//将这一属性定义为HTemp的EquivalentTo属性
OOM.addAxiom(myOntology, LTEq);

何必呢哈哈哈。

第三章 例子

  • 例1:简单关系推理
    已知:个体 Jackson 是 个体Jack的儿子,uncleSamJack的兄弟;
    要推理出:uncleSamJackson的叔叔;
    那么构建本体的过程:(注意区分大小写)
根据第一章2.1节~2.4节等,声明:
类person
个体Jackson, Jack, 以及uncleSam
对象属性isUncleOf, isBrotherOf和isSonOf
将上述个体声明为属于person类
给个体Jack赋予对象属性isSonOf,对象是father,即isSonOf(Jackson,father)
给个体uncleSam赋予对象属性isBrotherOf,对象是father,即isBrotherOf(uncleSam,Jack)
根据第一章2.5节,创建SWRL规则:
person(?a)^isSonOf(?a,?b)^isBrotherOf(?c,?b)->isUncleOf(?c,?a)
  • 例2:简单数值推理
    已知:期末考试的分数score90分以上我们叫他“大佬”,60~90分叫“过了”,60分一下叫“挂科”;当然,如果被发现作弊了那么直接挂科。
    要推理出:JacksonKujou期末考得如何(可以随意输入分数);
    那么构建本体的过程:
声明:
类student
个体Jackson, Kujou, professor
数据属性score
对象属性cheatedInExam, yoooManYouAreGreat,goHomeAndPlay,seeYouNextTerm
将Jackson Kujou声明为属于student类
给个体Jackson赋予对象属性cheatedInExam,对象是professor,即cheatedInExam(Jackson,professor)
给个体uncleSam赋予对象属性isBrotherOf,对象是father,即isBrotherOf(uncleSam,Jack)   当然,这里的professor就是个中间变量,是个工具人,改成啥都无所谓,好处就是最后可以通过读取它的所有对象属性来看到所有推理结果。
根据第一章2.5节,创建SWRL规则:
(在学生等个体看各自是否通过:)
规则1:student(?a)^cheatedInExma(?a,?b)->seeYouNextTerm(?a,professor)
规则2:student(?a)^score(?a,?data)^swrlb:lessThan(?data,60)->seeYouNextTerm(?a,professor)
规则3:student(?a)^score(?a,?data)^swrlb:lessThan(?data,90)^swrlb:greaterThanOrEqual(?data,60)->goHomeAndPlay(?a,professor)
规则4:student(?a)^score(?a,?data)^swrlb:greaterThanOrEqual(?data,90)->yoooManYouAreSoGreat(?a,professor)
(在工具人那里看所有学生通过情况:)
student(?a)^cheatedInExma(?a,?b)->seeYouNextTerm(professor,?a)
student(?a)^score(?a,?data)^swrlb:lessThan(?d,60)->seeYouNextTerm(professor,?a)
......其他同理

然后就可以输入每个学生相应的分数,比如Kujou 85分:
声明Kujou的数据属性score为85;
比如Jackson 95分,但是他作弊了:
声明Jacjson的数据属性score为95,声明Jackson具有对professor的对象属性cheatedInExam;

那么推理结果为:
Kujou过了,goHomeAndPlay。Jackson挂了,yoooManYouAreGreat,seeYouNextTerm都有,可以用Java处理,觉得进一步处理麻烦?例3:
  • 例3:Equivalent To属性
    可以通过将作弊了的学生归类为badStudent这一student类的子类中,来化简规则库,即不需要对象属性cheatedInExam了。
声明student类
声明goodStudent和badStudent两个student类的子类
声明数据属性cheated
参见2.6节,可以规定比如cheated =1 代表作弊了,是badStudent

SWRL规则可以相应改为
student(?a)^badStudent(?a)->seeYouNextTerm(?a,professor)

双盲答辩,
答辩组长 :你这引擎可真菜啊
我:啊?嗯……确实……
答辩老师A:你指导教师是XX吧(她说对了)
我 :?????


我,广告,点开:
考研复试中,有哪些令人窒息的问题?https://www.zhihu.com/question/270364088/answer/358743546

  • 45
    点赞
  • 164
    收藏
    觉得还不错? 一键收藏
  • 74
    评论
### 回答1: 在Protégé中,"pellet"是一个重要的推理引擎推理引擎是用于推理和计算知识图谱中的逻辑推断的工具。 在Protégé中,当我们构建和编辑本体时,我们可以使用"pellet"推理引擎来执行一些特定的逻辑推断。这些推断可以帮助我们发现本体中的潜在逻辑错误、补充缺失的知识和生成新的推理结果。 使用"pellet"引擎,我们可以进行多种类型的推断,如类的子类关系、实例的实例关系、属性的完整性约束等。例如,如果我们在本体中定义了一个父类-子类的层级结构,"pellet"可以自动根据该层级结构进行类的一些推断,如一个实例属于某个类的子类。类似地,如果我们在本体中定义了属性之间的一些约束,"pellet"也可以帮助我们推断出这些约束是否满足。 "pellet"推理引擎使用非常方便,在Protégé的菜单中可以直接选择它作为默认的推理引擎。此外,通过插件机制,我们还可以使用其他推理引擎,如HermiT和Fact++.不同的推理引擎可能会根据其特定的算法和推理策略产生不同的推理结果,因此在使用推理引擎时需要注意相应的推理规则和推理的正确性。 综上所述,"pellet"是Protégé中一个重要的推理引擎,它可以帮助我们进行各种类型的逻辑推断,从而增强本体的表达能力和推理能力。 ### 回答2: 在Protege中,"pellet"指的是OWL推理器。Protege是一个用于本体建模和推理的开源软件,而Pellet则是其中一个用于执行OWL推理的插件。 OWL(Web本体语言)是一种用于表示知识的语言,它基于描述逻辑,可以描述实体之间的关系、属性和类别等。然而,只有使用OWL推理器才能对OWL本体进行推理并获得更多的隐含信息。 Pellet是Protege提供的一个强大的OWL推理器,它可以帮助用户在本体中发现更多的知识。它基于描述逻辑DL-Lite,使用了分类算法和SAT求解器等技术。它具有高效的推理性能和良好的可扩展性,可以处理大规模的本体。 在Protege使用Pellet,用户可以通过选择Pellet推理引擎来启用推理功能。一旦启用,用户可以使用Protege的多种功能来定义本体,包括类、属性、实例等。当用户建立了本体之后,Pellet可以自动进行推理,发现新的关联、类别和实例等。 通过使用Pellet进行推理,用户可以更充分地利用已有的本体知识,发现隐藏的关系和知识,从而更准确地描述现实世界中的实体和关系。它还可以帮助用户发现本体中的不一致和潜在的错误,提升本体的质量和可靠性。 总之,Pellet是Protege中的一个重要组件,它为用户提供了强大的OWL推理功能,帮助用户更好地理解和利用本体知识。它是一个在本体建模和推理领域非常受欢迎的工具,被广泛应用于学术研究和实际应用中。 ### 回答3: 在Protege中,Pellet是一个重要的推理引擎。它是一个基于描述逻辑的OWL-DL(Description Logic)Reasoner,主要用于语义网上的本体建模和推理。 Pellet的主要功能是基于已定义的本体进行逻辑推理。它可以通过检查本体的一致性、解释Tbox和Abox的关联以及推理概念和实例之间的关系来增强本体的语义表达能力。 使用Pellet,可以更好地理解和分析本体之间的关系,从而使知识表示更加准确和丰富。Pellet还提供了许多有用的推理服务,如计算概念的等价类、计算推理结果的可满足性等。 在Protege使用Pellet通常需要进行以下步骤:首先,将Pellet插件添加到Protege中。然后,加载本体文件并配置推理设置。最后,运行推理引擎以进行推理。 通过使用Pellet,可以更方便地进行本体的推理和验证。它可以帮助用户发现本体中的潜在问题,并提供有关推理结果的解释。同时,Pellet还能够提供高效的推理性能,适用于处理大规模本体和复杂推理任务。 总之,Pellet在Protege中是一个非常重要的推理引擎,它可以提供强大的推理功能,帮助用户构建和分析更复杂和准确的本体模型。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 74
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值