本章,介绍 基于jena的规则引擎实现推理,并通过两个例子介绍如何coding实现。

规则引擎概述

jena包含了一个通用的规则推理机,可以在RDFS和OWL推理机使用,也可以单独使用。

推理机支持在RDF图上推理,提供前向链、后向链和二者混合执行模式。包含RETE engine 和 one tabled datalog engine。可以通过GenericRuleReasoner来进行配置参数,使用各种推理引擎。要使用 GenericRuleReasoner,需要一个规则集来定义其行为.

Rule的语法与结构

规则通过 Rule对象来进行定义,包含 body terms列表 (premises),head terms列表 (conclusions) 和可选的 name 和可选的direction。

An informal description of the simplified text rule syntax is:

_Rule_ := _bare-rule_ .

or [ _bare-rule_ ]

or [ ruleName : _bare-rule_ ]

_bare-rule_ := _term_, ... _term_ -> _hterm_, ... _hterm_ // forward rule

or _bhterm_

_hterm := term

_ or [ _bare-rule_ ]

_term_ := (_node_, _node_, _node_) // triple pattern

or (_node_, _node_, _functor_) // extended triple pattern

or builtin(_node_, ... _node_) // invoke procedural primitive

_bhterm_ := (_node_, _node_, _node_) // triple pattern

_functor_ := functorName(_node_, ... _node_) // structured literal

_node_ := _uri-ref_ // e.g. http://foo.com/eg

or prefix:localname // e.g. rdf:type

or <_uri-ref_> // e.g.

or ?_varname_ // variable

or 'a literal' // a plain string literal

or 'lex'^^typeURI // a typed literal, xsd:* type names supported

or number // e.g. 42 or 25.5

逗号 "," 分隔符是可选的.

前向和后向规则语法之间的区别仅与混合执行策略相关,请参见下文。

_functor_ 是一个扩展的三元组,用于创建和访问文本值。functorName可以是任何简单的标识符。

为保障rules的可读性URI引用支持qname语法。可以使用在 PrintUtil对象中注册的前缀。

下面是一些规则示例:

[allID: (?C rdf:type owl:Restriction), (?C owl:onProperty ?P),

(?C owl:allValuesFrom ?D) -> (?C owl:equivalentClass all(?P, ?D)) ]

[all2: (?C rdfs:subClassOf all(?P, ?D)) -> print('Rule for ', ?C)

[all1b: (?Y rdf:type ?D)

[max1: (?A rdf:type max(?P, 1)), (?A ?P ?B), (?A ?P ?C)

-> (?B owl:sameAs ?C) ]

Rule allID说明了functor用于将OWL限制的组件收集到单个数据结构中,然后可以触发进一步的规则

Rule all2 表示一个前向规则,它创建了一个新的后向规则,并且还调用了print.

Rule max1 说明了如何使用数字

可以使用以下方法加载和解析规则文件:

List rules = Rule.rulesFromURL("file:myfile.rules");

或者

BufferedReader br = / _open reader_ / ;

List rules = Rule.parseRules( Rule.rulesParserFromReader(br) );

或者

String ruleSrc = / _list of rules in line_ /

List rules = Rule.parseRules( rulesSrc );

在前两种情况下(从URL或BufferedReader读取),规则文件由一个简单的处理器预处理,该处理器剥离注释并支持一些额外的宏命令:

# ...

注释.

// ...

注释

@prefix pre: .

定义了一个前缀pre ,可以用在规则文件中.

@include .

包含指定规则,允许规则文件包含RDFS和OWL的预定义规则

完整实例:

@prefix pre: .

@include .

[rule1: (?f pre:father ?a) (?u pre:brother ?f) -> (?u pre:uncle ?a)]

规则推理demo1--喜剧演员

例如,在一个电影知识图谱里,如果一个演员参演的电影的类型是喜剧片,我们可以认为这个演员是喜剧电影

推理规则:

[ruleComedian: (?p :hasActedIn ?m) (?m :hasGenre ?g) (?g :genreName '喜剧') -> (?p rdf:type :Comedian)]

我们用代码来实现:

String prefix = "http://www.test.com/kg/#";

Graph data = Factory.createGraphMem();

// 定义节点

Node movie = NodeFactory.createURI(prefix + "movie");

Node hasActedIn = NodeFactory.createURI(prefix + "hasActedIn");

Node hasGenre = NodeFactory.createURI(prefix + "hasGenre");

Node genreName = NodeFactory.createURI(prefix + "genreName");

Node genre = NodeFactory.createURI(prefix + "genre");

Node person = NodeFactory.createURI(prefix + "person");

Node Comedian = NodeFactory.createURI(prefix + "Comedian");

// 添加三元组

data.add(new Triple(genre, genreName, NodeFactory.createLiteral("喜剧")));

data.add(new Triple(movie, hasGenre, genre));

data.add(new Triple(person, hasActedIn, movie));

// 创建推理机

GenericRuleReasoner reasoner = (GenericRuleReasoner) GenericRuleReasonerFactory.theInstance().create(null);

PrintUtil.registerPrefix("", prefix);

// 设置规则

reasoner.setRules(Rule.parseRules(

"[ruleComedian: (?p :hasActedIn ?m) (?m :hasGenre ?g) (?g :genreName '喜剧') -> (?p rdf:type :Comedian)] \n"

+ "-> tableAll()."));

reasoner.setMode(GenericRuleReasoner.HYBRID); // HYBRID混合推理

InfGraph infgraph = reasoner.bind(data);

infgraph.setDerivationLogging(true);

// 执行推理

Iterator tripleIterator = infgraph.find(person, null, null);

while (tripleIterator.hasNext()) {

System.out.println(PrintUtil.print(tripleIterator.next()));

}

输出结果:

(:person rdf:type :Comedian)

(:person :hasActedIn :movie)

可以看到,已经给person加上了Comedian。

规则推理demo2 -- 关联交易

我们再来看上一篇文章中提到的那个金融图谱:

陈华钧老师PPT里,有一个推理任务:

执掌一家公司就一定是这家公司的股东;

某人同时是两家公司的股东,那么这两家公司一定有关联交易;

PPT里是使用Drools来实现的,具体可以参见PPT。我们这里使用jena来实现,可以达到同样的效果。

首先,构造好图谱,为了方便理解,我们用中文变量:

Model myMod = ModelFactory.createDefaultModel();

String finance = "http://www.example.org/kse/finance#";

Resource 孙宏斌 = myMod.createResource(finance + "孙宏斌");

Resource 融创中国 = myMod.createResource(finance + "融创中国");

Resource 乐视网 = myMod.createResource(finance + "乐视网");

Property 执掌 = myMod.createProperty(finance + "执掌");

Resource 贾跃亭 = myMod.createResource(finance + "贾跃亭");

Resource 地产公司 = myMod.createResource(finance + "地产公司");

Resource 公司 = myMod.createResource(finance + "公司");

Resource 法人实体 = myMod.createResource(finance + "法人实体");

Resource 人 = myMod.createResource(finance + "人");

Property 主要收入 = myMod.createProperty(finance + "主要收入");

Resource 地产事业 = myMod.createResource(finance + "地产事业");

Resource 王健林 = myMod.createResource(finance + "王健林");

Resource 万达集团 = myMod.createResource(finance + "万达集团");

Property 主要资产 = myMod.createProperty(finance + "主要资产");

Property 股东 = myMod.createProperty(finance + "股东");

Property 关联交易 = myMod.createProperty(finance + "关联交易");

Property 收购 = myMod.createProperty(finance + "收购");

// 加入三元组

myMod.add(孙宏斌, 执掌, 融创中国);

myMod.add(贾跃亭, 执掌, 乐视网);

myMod.add(王健林, 执掌, 万达集团);

myMod.add(乐视网, RDF.type, 公司);

myMod.add(万达集团, RDF.type, 公司);

myMod.add(融创中国, RDF.type, 地产公司);

myMod.add(地产公司, RDFS.subClassOf, 公司);

myMod.add(公司, RDFS.subClassOf, 法人实体);

myMod.add(孙宏斌, RDF.type, 人);

myMod.add(贾跃亭, RDF.type, 人);

myMod.add(王健林, RDF.type, 人);

myMod.add(万达集团,主要资产,地产事业);

myMod.add(融创中国,主要收入,地产事业);

myMod.add(孙宏斌, 股东, 乐视网);

myMod.add(孙宏斌, 收购, 万达集团);

PrintUtil.registerPrefix("", finance);

// 输出当前模型

StmtIterator i = myMod.listStatements(null,null,(RDFNode)null);

while (i.hasNext()) {

System.out.println(" - " + PrintUtil.print(i.nextStatement()));

}

上图所示的图谱,包含如下的三元组:

- (:公司 rdfs:subClassOf :法人实体)

- (:万达集团 :主要资产 :地产事业)

- (:万达集团 rdf:type :公司)

- (:地产公司 rdfs:subClassOf :公司)

- (:融创中国 :主要收入 :地产事业)

- (:融创中国 rdf:type :地产公司)

- (:孙宏斌 :股东 :乐视网)

- (:孙宏斌 rdf:type :人)

- (:孙宏斌 :执掌 :融创中国)

- (:乐视网 rdf:type :公司)

- (:贾跃亭 rdf:type :人)

- (:贾跃亭 :执掌 :乐视网)

- (:王健林 rdf:type :人)

- (:王健林 :执掌 :万达集团)

我们来定义推理规则:

执掌一家公司就一定是这家公司的股东;

收购一家公司,就是这家公司的股东

某人同时是两家公司的股东,那么这两家公司一定有关联交易;

用jena规则来表示:

[ruleHoldShare: (?p :执掌 ?c) -> (?p :股东 ?c)]

[[ruleHoldShare2: (?p :收购 ?c) -> (?p :股东 ?c)]

[ruleConnTrans: (?p :股东 ?c) (?p :股东 ?c2) -> (?c :关联交易 ?c2)]

执行推理:

GenericRuleReasoner reasoner = (GenericRuleReasoner) GenericRuleReasonerFactory.theInstance().create(null);

reasoner.setRules(Rule.parseRules(

"[ruleHoldShare: (?p :执掌 ?c) -> (?p :股东 ?c)] \n"

+ "[ruleConnTrans: (?p :收购 ?c) -> (?p :股东 ?c)] \n"

+ "[ruleConnTrans: (?p :股东 ?c) (?p :股东 ?c2) -> (?c :关联交易 ?c2)] \n"

+ "-> tableAll()."));

reasoner.setMode(GenericRuleReasoner.HYBRID);

InfGraph infgraph = reasoner.bind(myMod.getGraph());

infgraph.setDerivationLogging(true);

System.out.println("推理后...\n");

Iterator tripleIterator = infgraph.find(null, null, null);

while (tripleIterator.hasNext()) {

System.out.println(" - " + PrintUtil.print(tripleIterator.next()));

}

输出结果:

推理后...

- (:万达集团 :关联交易 :乐视网)

- (:万达集团 :关联交易 :融创中国)

- (:万达集团 :关联交易 :万达集团)

- (:孙宏斌 :股东 :万达集团)

- (:孙宏斌 :股东 :融创中国)

- (:融创中国 :关联交易 :万达集团)

- (:融创中国 :关联交易 :乐视网)

- (:融创中国 :关联交易 :融创中国)

- (:乐视网 :关联交易 :万达集团)

- (:乐视网 :关联交易 :融创中国)

- (:乐视网 :关联交易 :乐视网)

- (:贾跃亭 :股东 :乐视网)

- (:王健林 :股东 :万达集团)

- (:公司 rdfs:subClassOf :法人实体)

- (:万达集团 :主要资产 :地产事业)

- (:万达集团 rdf:type :公司)

- (:地产公司 rdfs:subClassOf :公司)

- (:融创中国 :主要收入 :地产事业)

- (:融创中国 rdf:type :地产公司)

- (:孙宏斌 :收购 :万达集团)

- (:孙宏斌 :股东 :乐视网)

- (:孙宏斌 rdf:type :人)

- (:孙宏斌 :执掌 :融创中国)

- (:乐视网 rdf:type :公司)

- (:贾跃亭 rdf:type :人)

- (:贾跃亭 :执掌 :乐视网)

- (:王健林 rdf:type :人)

- (:王健林 :执掌 :万达集团)

我们看到,推理后孙宏斌是三家公司的股东,三家公司都有关联交易。

作者:Jadepeng

出处:jqpeng的技术记事本--http://www.cnblogs.com/xiaoqi

您的支持是对博主最大的鼓励,感谢您的认真阅读。

本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

python 知识图谱 推理_知识图谱推理与实践 (2) -- 基于jena实现规则推理相关推荐

  1. 消解原理推理_什么是推理统计中的Z检验及其工作原理?

    消解原理推理 I Feel: 我觉得: The more you analyze the data the more enlightened, data engineer you will becom ...

  2. python知识图谱实战_知识图谱实战

    原标题:知识图谱实战 知识图谱是近来非常红火的技术,融合网络爬虫,自然语言处理,机器学习,深度学习,图数据库,复杂网络分析等多种热门技术于一身,技术含量密集,在构造语义搜索,问答平台,高智能的人机界面 ...

  3. python 知识图谱数据库_知识图谱和 Neo4j 浅析-数据库

    编辑推荐: 本文来自于51cto,介绍了什么是知识图谱,知识图谱的应用场景,知识图谱的构建,知识图谱的存储以及 neo4j 的性能测试,neo4j图数据库优化等知识. 在当前大数据行业中, 随着算法的 ...

  4. python知识图谱可视化_知识图谱可视化

    ## 人物关系知识图谱 #### 一.背景 将结构化数据通过关系预处理程序处理为图数据库可以查询的数据,示例是将其中一部分(人物关系数据)可视化表示. #### 二.用到的技术 技术点:图数据库Neo ...

  5. python文献知识图谱可视化_知识图谱可视化工具(知识图谱可视化python)

    知识图谱可视化工具免费杭州市西湖区教育装备保障服务中心 除了知识图,图还能做什么?编者注:作者的高级解决方案顾问包汉林.本文将集中在三个方面,侧重于图数据库和图分析的价值,并列举图分析应用程序的一些方 ...

  6. python知识点智能问答_基于知识图谱的智能问答机器人

    研究背景及意义 智能问答是计算机与人类以自然语言的形式进行交流的一种方式,是人工智能研究的一个分支. 知识图谱本质上是一种语义网络,其结点代表实体(entity)或者概念(concept),边代表实体 ...

  7. 神经网络推理_分析神经网络推理性能的新工具

    神经网络推理 Measuring the inference time of a trained deep neural model on different hardware devices is ...

  8. 特征图谱字典_空间数据图谱为特征

    特征图谱字典 For my first Medium post I will show a nice, easy way to enrich your spatial data with featur ...

  9. 计算机基础知识整理大全_知识大全 | 物理选修35quot;波粒二象性quot;

    图图说: 作为高中课程学习的常备工具书,本丛书以新考试大纲和课程标准为依据,参照新课标各版本教材编写而成,包括新课标各版本教材必修和选修的知识点,并对知识点进行了详细讲解与说明,同时以高考真题诠释对知 ...

最新文章

  1. 怎么知道一名研究生有没有科研潜力?
  2. Qt入门之基础篇 ( 一 ) :Qt4及Qt5的下载与安装
  3. php查询算法,PHP算法之二分查找
  4. Android热更新方案Robust
  5. 类属性-类属性的定义及使用
  6. 后端Coder如何做好代码设计?
  7. 学习响应式BootStrap来写融职教育网站,Bootsrtap第十天你的收获
  8. 关于CPU的12个硬核干货!
  9. 验证只能以英文字母开头的字符串
  10. 《中国人工智能学会通讯》——4.40 什么是类人概念学习?
  11. Linux三剑客之grep
  12. 小菜学前端day02(学习笔记)
  13. 写了四十篇办公自动化文章后,我整理了这十个常用操作,代码拿走就用!
  14. 通信室计算机室采购配置co2灭火器,2019一级消防案例分析考点:民用类建筑消防设施的配置...
  15. Dubbo-接口数据序列化Serialization
  16. 南安普顿大学人工智能硕士课程
  17. 纯css实现手风琴效果_创建纯CSS手风琴的4种方法
  18. Mozilla的架构(收集)
  19. 前端项目如何向一个后端项目传递数组?(批量删除如何传参)
  20. ModelSim 实用知识:优化,SDF,覆盖率

热门文章

  1. 【AIoT库】专业权威、高含金量的2021“物联之星”年度评选正式启动,500+物联网企业竞相追逐
  2. 计算机专业的个人简历英语,计算机专业优秀个人英文简历范文【三篇】
  3. 【操作系统】操作系统的主要任务
  4. 简述计算机地图制图的主要阶段,计算机地图制图原理、特点及发展趋势
  5. Windows Server 2012/2016 在桌面上显示“我的电脑”图标
  6. 基于SSM实现高校教材预定管理系统-毕业设计【附源码】
  7. 默孚龙导电滑环运用的多吗
  8. 体育馆管理系统源代码
  9. oracle exp导出表where,oracle EXP导出一张表时使用query参数指定where条件
  10. Webshell免杀-JSP