关于人工智能:从零开始构建一个电影知识图谱实现KBQA智能问答下篇KBQA问答Demo超详细教学

70次阅读

共计 14916 个字符,预计需要花费 38 分钟才能阅读完成。

从零开始构建一个电影常识图谱,实现 KBQA 智能问答[下篇]:Apache jena SPARQL endpoint 及推理、KBQA 问答 Demo 超具体教学

成果展现:

1.Apache jena SPARQL endpoint 及推理

在上一篇咱们学习了如何利用 D2RQ 来开启 endpoint 服务,但它有两个毛病:

  1. 不反对间接将 RDF 数据通过 endpoint 公布到网络上。
  2. 不反对推理。

这次咱们介绍的 Apache Jena 可能解决下面两个问题。

1.1.Apache Jena 简介


Apache Jena(后文简称 Jena),是一个开源的 Java 语义网框架(open source Semantic Web Framework for Java),用于构建语义网和链接数据利用。上面是 Jena 的架构图:

本次实际咱们会用到的组件有:TDB、rule reasoner 和 Fuseki。

  1. TDB 是 Jena 用于存储 RDF 的组件,是属于存储层面的技术。在单机状况下,它可能提供十分高的 RDF 存储性能。目前 TDB 的最新版本是 TDB2,且与 TDB1 不兼容。
  2. Jena 提供了 RDFS、OWL 和通用规定推理机。其实 Jena 的 RDFS 和 OWL 推理机也是通过 Jena 本身的通用规定推理机实现的。
  3. Fuseki 是 Jena 提供的 SPARQL 服务器,也就是 SPARQL endpoint。其提供了四种运行模式:单机运行、作为零碎的一个服务运行、作为 web 利用运行或者作为一个嵌入式服务器运行。

Jena 目前是应用最宽泛、文档最全、社区最沉闷的一个开源语义网框架。更多的细节,读者能够参考官网文档。

1.2.Fuseki 与 OWL 推理实战


咱们先下载 Jena 的最新版本(fuseki 和其余的功能模块不在同一个文件中,须要别离下载 apache-jena 和 apache-jena-fuseki)。后续操作以 Windows 为例,Linux 相似,只是脚本地位不同。

创立一个目录(我这里命名为“tdb”)用于寄存 tdb 数据。进入“apache-jena-X.X.X”文件夹的 bat 目录,能够看到很多批处理文件,咱们应用“tdbloader.bat”将之前咱们的 RDF 数据以 TDB 的形式存储。命令如下:

.\tdbloader.bat --loc="D:\apache jena\tdb" "D:\d2rq\kg_demo_movie.nt"

“–loc”指定 tdb 存储的地位,即方才咱们创立的文件夹;第二个参数是由 Mysql 数据转换失去的 RDF 数据。

进入入“apache-jena-fuseki-X.X.X”文件夹,运行“fuseki-server.bat”,而后退出。程序会为咱们在当前目录主动创立“run”文件夹。将咱们的本体文件“ontology.owl”挪动到“run”文件夹下的“databases”文件夹中,并将“owl”后缀名改为“ttl”。在“run”文件夹下的“configuration”中,咱们创立名为“fuseki_conf.ttl”的文本文件(取名没有要求),退出如下内容:

@prefix : <http://base/#> .
@prefix tdb: <http://jena.hpl.hp.com/2008/tdb#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix ja: <http://jena.hpl.hp.com/2005/11/Assembler#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix fuseki: <http://jena.apache.org/fuseki#> .
:service1 a fuseki:Service ;
fuseki:dataset <#dataset> ;
fuseki:name "kg_demo_movie" ;
fuseki:serviceQuery "query" , "sparql" ;
fuseki:serviceReadGraphStore "get" ;
fuseki:serviceReadWriteGraphStore "data" ;
fuseki:serviceUpdate "update" ;
fuseki:serviceUpload "upload" .
<#dataset> rdf:type ja:RDFDataset ;
ja:defaultGraph <#model_inf> ;
.
<#model_inf> a ja:InfModel ;
ja:baseModel <#tdbGraph> ;
#本体文件的门路
ja:content [ja:externalContent <file:///D:/apache%20jena/apache-jena-fuseki-3.5.0/run/databases/ontology.ttl>] ;
#启用 OWL 推理机
ja:reasoner [ja:reasonerURL <http://jena.hpl.hp.com/2003/OWLFBRuleReasoner>] .
<#tdbGraph> rdf:type tdb:GraphTDB ;
tdb:dataset <#tdbDataset> ;
.
<#tdbDataset> rdf:type tdb:DatasetTDB ;
tdb:location "D:/apache jena/tdb" ;
.

再次运行“fuseki-server.bat”,如果呈现如下界面示意运行胜利:

Fuseki 默认的端口是 3030,浏览器拜访“http://localhost:3030/”,和之前介绍的 D2RQ web 界面相似,咱们能够进行 SPARQL 查问等操作。在 Python 中用 SPARQLWrapper 向 Fuseki server 发送查问申请:

PREFIX : <http://www.kgdemo.com#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT * WHERE {
?x :movieTitle '功夫'.
?x ?p ?o.
}

即查问电影《功夫》的所有属性。返回的后果:

x p o
file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#movie/9470 http://www.kgdemo.com#hasGenre file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#genre/14
file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#movie/9470 http://www.kgdemo.com#hasGenre file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#genre/28
file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#movie/9470 http://www.kgdemo.com#hasGenre file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#genre/35
file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#movie/9470 http://www.kgdemo.com#hasGenre file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#genre/80
file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#movie/9470 http://www.w3.org/1999/02/22-rdf-syntax-ns#type http://www.kgdemo.com#Movie
file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#movie/9470 http://www.kgdemo.com#movieRating 7.2E0
file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#movie/9470 http://www.kgdemo.com#movieIntroduction 1940 年代的上海,自小受尽欺辱的街头混混阿星(周星驰)为了能出人头地,堪称窥见机会的缝隙就往里钻,今次他盯上口头日益猖狂的黑道权势“斧头帮”,想借之小名成就大业。阿星混充“斧头帮”成员试图在一个叫“猪笼城寨”的中央对居民讹诈,不想引来真的“斧头帮”与“猪笼城寨”居民的恩怨。“猪笼城寨”原是藏龙卧虎之处,居民中有许多身怀绝技者(元华、梁小龙等),他们暗藏于此本是为远离江湖恩怨,不想麻烦主动上身,躲都躲不迭。而在观战正邪两派的奋斗中,阿星逐步领悟功夫的真谛。file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#movie/9470 http://www.kgdemo.com#movieTitle 功夫
file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#movie/9470 http://www.kgdemo.com#movieReleaseDate 2004-02-10
file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#movie/9470 http://www.w3.org/1999/02/22-rdf-syntax-ns#type http://www.w3.org/2002/07/owl#Thing
file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#movie/9470 http://www.kgdemo.com#hasActor file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#person/25251
file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#movie/9470 http://www.kgdemo.com#hasActor file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#person/57609
file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#movie/9470 http://www.kgdemo.com#hasActor file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#person/118745
file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#movie/9470 http://www.kgdemo.com#hasActor file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#person/57607
file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#movie/9470 http://www.kgdemo.com#hasActor file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#person/65975
file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#movie/9470 http://www.kgdemo.com#hasActor file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#person/78878
file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#movie/9470 http://www.kgdemo.com#hasActor file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#person/83635
file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#movie/9470 http://www.kgdemo.com#hasActor file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#person/119426
file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#movie/9470 http://www.kgdemo.com#hasActor file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#person/545277
file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#movie/9470 http://www.kgdemo.com#hasActor file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#person/576408
file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#movie/9470 http://www.kgdemo.com#hasActor file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#person/1136808
file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#movie/9470 http://www.kgdemo.com#hasActor file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#person/1173200
file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#movie/9470 http://www.kgdemo.com#hasActor file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#person/1173216
file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#movie/9470 http://www.kgdemo.com#hasActor file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#person/1173223
file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#movie/9470 http://www.kgdemo.com#hasActor file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#person/1173224
file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#movie/9470 http://www.kgdemo.com#hasActor file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#person/1287732
file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#movie/9470 http://www.kgdemo.com#hasActor file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#person/1676386
file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#movie/9470 http://www.w3.org/1999/02/22-rdf-syntax-ns#type http://www.w3.org/2000/01/rdf-schema#Resource
file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#movie/9470 http://www.w3.org/2002/07/owl#sameAs file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#movie/9470

电影的“hasActor”属性是通过 OWL 推理机失去的,即咱们本来的 RDF 数据外面是没有的。能够在 D2RQ 的 endpoint 中进行同样的查问,失去如下后果:

x p o
http://localhost:2020/resource/movie/9470 http://www.kgdemo.com#movieRating 7.2E0
http://localhost:2020/resource/movie/9470 http://www.kgdemo.com#movieIntroduction 1940 年代的上海,自小受尽欺辱的街头混混阿星(周星驰)为了能出人头地,堪称窥见机会的缝隙就往里钻,今次他盯上口头日益猖狂的黑道权势“斧头帮”,想借之小名成就大业。阿星混充“斧头帮”成员试图在一个叫“猪笼城寨”的中央对居民讹诈,不想引来真的“斧头帮”与“猪笼城寨”居民的恩怨。“猪笼城寨”原是藏龙卧虎之处,居民中有许多身怀绝技者(元华、梁小龙等),他们暗藏于此本是为远离江湖恩怨,不想麻烦主动上身,躲都躲不迭。而在观战正邪两派的奋斗中,阿星逐步领悟功夫的真谛。http://localhost:2020/resource/movie/9470 http://www.kgdemo.com#hasGenre http://localhost:2020/resource/genre/14
http://localhost:2020/resource/movie/9470 http://www.kgdemo.com#hasGenre http://localhost:2020/resource/genre/28
http://localhost:2020/resource/movie/9470 http://www.kgdemo.com#hasGenre http://localhost:2020/resource/genre/35
http://localhost:2020/resource/movie/9470 http://www.kgdemo.com#hasGenre http://localhost:2020/resource/genre/80
http://localhost:2020/resource/movie/9470 http://www.kgdemo.com#movieReleaseDate 2004-02-10
http://localhost:2020/resource/movie/9470 http://www.kgdemo.com#movieTitle 功夫
http://localhost:2020/resource/movie/9470 http://www.w3.org/1999/02/22-rdf-syntax-ns#type http://www.kgdemo.com#Movie

这些是实在存在于“kg_demo_movie.nt”的数据。

1.3. 规定推理实战


在“databases”文件夹下新建一个文本文件“rules.ttl”,填入如下内容:

@prefix : <http://www.kgdemo.com#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix xsd: <XML Schema> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
[ruleComedian: (?p :hasActedIn ?m) (?m :hasGenre ?g) (?g :genreName '悲剧') -> (?p rdf:type :Comedian)]
[ruleInverse: (?p :hasActedIn ?m) -> (?m :hasActor ?p)]

咱们定义了一个名为“ruleComedian”的规定,它的意思是:如果有一个演员,出演了一部喜剧电影,那么他就是一位喜剧演员。批改配置文件“fuseki_conf.ttl”:

@prefix : <http://base/#> .
@prefix tdb: <http://jena.hpl.hp.com/2008/tdb#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix ja: <http://jena.hpl.hp.com/2005/11/Assembler#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix fuseki: <http://jena.apache.org/fuseki#> .
:service1 a fuseki:Service ;
fuseki:dataset <#dataset> ;
fuseki:name "kg_demo_movie" ;
fuseki:serviceQuery "query" , "sparql" ;
fuseki:serviceReadGraphStore "get" ;
fuseki:serviceReadWriteGraphStore "data" ;
fuseki:serviceUpdate "update" ;
fuseki:serviceUpload "upload" .
<#dataset> rdf:type ja:RDFDataset ;
ja:defaultGraph <#model_inf> ;
.
<#model_inf> a ja:InfModel ;
ja:baseModel <#tdbGraph> ;
#本体文件的门路
ja:content [ja:externalContent <file:///D:/apache%20jena/apache-jena-fuseki-3.5.0/run/databases/ontology.ttl>] ;
#敞开 OWL 推理机
#ja:reasoner [ja:reasonerURL <http://jena.hpl.hp.com/2003/OWLFBRuleReasoner>] .
#开启规定推理机,并指定规定文件门路
ja:reasoner [
ja:reasonerURL <http://jena.hpl.hp.com/2003/GenericRuleReasoner> ;
ja:rulesFrom <file:///D:/apache%20jena/apache-jena-fuseki-3.5.0/run/databases/rules.ttl> ; ]
.
<#tdbGraph> rdf:type tdb:GraphTDB ;
tdb:dataset <#tdbDataset> ;
.
<#tdbDataset> rdf:type tdb:DatasetTDB ;
tdb:location "D:/apache jena/tdb_for_demo" ;
.

咱们只能启用一种推理机。后面也提到,OWL 的推理性能也能够在规定推理机外面实现,因而咱们定义了“ruleInverse”来示意“hasActedIn”和“hasActor”的相同关系。更多细节读者能够参考文档。

咱们执行如下 SPARQL 查问,喜剧演员有哪些:

PREFIX : <http://www.kgdemo.com#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT * WHERE {
?x rdf:type :Comedian.
?x :personName ?n.
}
limit 10

查问后果:

x n
file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#person/111298 郑丹瑞
file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#person/70591 陈欣健
file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#person/116351 沈殿霞
file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#person/116052 鲍汉琳
file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#person/1002925 张同祖
file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#person/62423 林正英
file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#person/1614091 林琪欣
file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#person/224929 陈法蓉
file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#person/1135398 叶世荣
file:///D:/d2rq/d2rq-0.8.1/kg_demo_movie.nt#person/119426 元秋

1.4. 小结


本次实际介绍了如何应用 Jena 来开启 endpoint 服务,提供高效的查问;并介绍了如何退出推理引擎。咱们是用 Jena 提供的命令行工具来实现上述操作。实际上,jena 提供了所有工具的 API 接口,读者能够用 Java 编写程序,进行开发。

2.KBQA Demo

上面将介绍如何用 Python 实现一个繁难的问答程序。下图是 demo 的展现成果:

查问后果为空,答复“I don’t know.”;不能了解问句,答复“I can’t understand.”。本实现参考了王昊奋老师公布在 OpenKG 上的 demo“基于 REfO 的 KBQA 实现及示例”,读者也能够参考此示例,来实现本 demo。上面谈谈本 demo 的流程。

2.1 根本流程


此 demo 是利用正则表达式来做语义解析。咱们须要第三方库来实现初步的自然语言解决(分词、实体辨认),而后利用反对词级别正则匹配的库来实现后续的语义匹配。

分词和实体辨认(人名和电影名)咱们用 jieba 来实现。jieba 是一个轻量级的中文分词工具,有多种语言的实现版本。对于分词,在试验环境中,jieba 还是勉强能用。在咱们这个 demo 当中,有些常常会被应用的词语并不能被正确切分。比方:“喜剧电影”、“恐怖电影”、“科幻电影”、“喜剧演员”、“出生日期”等,在分词的时候,jieba 把它们当作一个词来解决,咱们须要手动调整词语的频率使得“喜剧电影”能被切分为“悲剧”和“电影”。至于实体辨认,jieba 对于人名的辨认精度尚可承受,然而电影名称的辨认精度太低以至于齐全不可用。因而,咱们间接把数据库中的人名和电影名导出,作为内部词典;应用 jieba 的时候加载内部词典,这样就能解决实体辨认的问题。

将自然语言转为以词为根底的根本单位后,咱们应用 REfO(Regular Expressions for Objects) 来实现语义匹配。具体实现请参考 OpenKG 的 demo 或者本 demo 的代码。

匹配胜利后,失去其对应的咱们事后编写的 SPARQL 模板,再向 Fuseki 服务器发送查问,最初将后果打印进去。

2.2 代码文件阐明


kg_demo_movie/
crawler/
movie_crawler.py
__init__.py
tradition2simple/
langconv.py
traditional2simple.py
zh_wiki.py
__init__.py
KB_query/
jena_sparql_endpoint.py
query_main.py
question2sparql.py
question_temp.py
word_tagging.py
external_dict/
csv2txt.py
movie_title.csv
movie_title.txt
person_name.csv
person_name.txt
__init__.py
  • “crawler” 文件夹蕴含的是咱们从 “The Movie DB” 获取数据的脚本。
  • “KB_query” 文件夹蕴含的是实现整个问答 demo 流程所须要的脚本。
  • “external_dict” 蕴含的是人名和电影名两个内部词典。csv 文件是从 mysql-workbench 导出的,依照 jieba 内部词典的格局,咱们将 csv 转为对应的 txt。
  • “word_tagging”,定义 Word 类的构造(即咱们在 REfO 中应用的对象);定义 “Tagger” 类来初始化词典,并实现自然语言到 Word 对象的办法。
  • “jena_sparql_endpoint”,用于实现与 Fuseki 的交互。
  • “question2sparql”,将自然语言转为对应的 SPARQL 查问。
  • “question_temp”,定义 SPARQL 模板和匹配规定。
  • “query_main”,main 函数。

在运行 “query_main” 之前,读者须要启动 Fuseki 服务,具体方法请参考上一篇文章。

2.3 小结


咱们通过应用正则表达式的形式来解析自然语言,并将解析的后果和咱们预约义的模板进行匹配,最初实现一个繁难的 KBQA。办法没有大家设想的那么“高大上”,没有统计办法、没有机器学习也没有深度学习。正则的益处是,易学,从事相干行业的人根本都理解这个货色;其次,可控性强或者说可解释性强,如果某个问题解析谬误,咱们只有找到对应的匹配规定进行调试即可;最初,正则冷启动比拟容易,在没有数据或者数据极少的状况下,咱们能够利用正则规定马上上线一个相似上述 demo 的高级的问答零碎。在现实情况中,因为上述长处,工业界也比拟青眼用正则来做语义解析。正则办法的缺点也是不言而喻的,它并不能了解语义信息,而是基于符号的匹配。换个角度说,用正则的办法,就须要规定的设计者可能尽可能思考到所有状况,然而这是不可能的。暂且不思考同义词、句子构造等问题,光是列举所有可能的问题就须要破费很大的功夫。尽管如此,在某些垂直畛域,比方“音乐”,“电影”,因为问题汇合的规模在肯定水平上是可控的(咱们根本能将用户的问题划定在某个范畴内),正则表达式还是有很大的用武之地的。在冷启动一段时间,取得了肯定用户应用数据之后,咱们能够思考引入其余的办法来改善零碎的性能,而后逐步缩小正则规定在整个零碎中的比重。如果读者想深入研究 KBQA,能够参考专栏“揭开知识库问答 KB-QA 的面纱”,该专栏的作者具体介绍了做 KBQA 的办法和相干钻研。

3. 我的项目实操

3.1 环境配置

  1. Python 版本为 3.6
  2. 装置依赖pip install -r requirements.txt
  3. jena 版本为 3.5.0,曾经上传在该 repo 中(如果不必 Docker 运行 demo,须要本人批改配置文件中的门路)。
  4. d2rq 应用的 0.8.1

3.2 运行形式

这里提供两种运行 demo 的形式:

  1. 间接构建 docker 镜像,部署容器服务。举荐这种形式,曾经把各种环境配置好了。只须要装置 docker,构建镜像。
  2. 间接在本地运行。须要自行批改配置文件(jena/apache-jena-fuseki-3.5.0/run/configuration/fuseki_conf.ttl 配置文件中的门路)

3.3 构建 docker 镜像

进入我的项目根目录

docker build -t kbqa:V0.1 .
docker run -p 80:80

关上浏览器,输出 localhost,即能看到 demo 界面。

3.4 本地运行

其实就是把 Dockerfile 外面的命令间接在本地环境运行(记得批改 configuration/fuseki_conf.ttl 中的文件门路)。

第一步:装置依赖库

pip3.6 install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple/

第二步:将 nt 格局的三元组数据以 tdb 进行存储(怎么失去 kg_demo_movie.nt 文件请参考 上篇 内容)。

/kbqa/jena/apache-jena-3.5.0/bin/tdbloader --loc="path_of_tdb" "path_of_kg_demo_movie.nt" # 自行指定 tdb 的门路,记得和 configuration/fuseki_conf.ttl 中统一

window 环境是应用 /kbqa/jena/apache-jena-3.5.0/bat/tdbloader.bat

第三步:设置环境变量(windows 如何设置请自行查问;也能够不设置 streamlit 端口,应用默认端口,第五步启动后会提醒服务的端口)

export LANG=C.UTF-8 LC_ALL=C.UTF-8 STREAMLIT_SERVER_PORT=80 FUSEKI_HOME=/kbqa/jena/apache-jena-fuseki-3.5.0

第四步:运行 fuseki(进入 apache-jena-fuseki-3.5.0 子目录,windows 运行 fuseki-server.bat)

./fuseki-server

第五步:运行 web 服务。

streamlit run streamlit_app.py --server.enableCORS=true

关上浏览器,输出指定的地址即可。

3.5 问题集锦

  1. fuseki-server 服务启动后,敞开重启会报错。这是 jena 的一个 bug,把 tdb 中的文件删了,从新用 tdbloader 命令生成一次即可。
  • 目录构造

    • Data 文件夹

    蕴含 ER 图模型文件和创立数据库、表,插入所有数据的 sql 文件。用户能够间接应用 sql 文件导入数据到 mysql 中。

    • kg\_demo_movie 文件夹
    • crawler 中的 movie_crawler 用于从 The Movie DB 下载数据,用户须要本人去网站注册账号,申请 API KEY。在脚本中填入本人的 API KEY,填写 mysql 相干参数即可运行。用户须要额定下载的包:requests 和 pymysql。tradition2simple 用于将繁体字转为简体字(申明一下,我找不到该文件的出处了,我是从网上找到的解决方案,如果有用户晓得该作者,麻烦告知,我会备注)。
    • KB_query 文件夹蕴含的是实现整个问答 demo 流程所须要的脚本。

      • “external_dict” 蕴含的是人名和电影名两个内部词典。csv 文件是从 mysql-workbench 导出的,依照 jieba 内部词典的格局,咱们将 csv 转为对应的 txt。
      • “word_tagging”,定义 Word 类的构造(即咱们在 REfO 中应用的对象);定义 ”Tagger” 类来初始化词典,并实现自然语言到 Word 对象的办法。
      • “jena\_sparql_endpoint”,用于实现与 Fuseki 的交互。
      • “question2sparql”,将自然语言转为对应的 SPARQL 查问。
      • “question_temp”,定义 SPARQL 模板和匹配规定。
      • “query\_main”,main 函数。在运行 ”query_main” 之前,读者须要启动 Fuseki 服务。
    • ontology.owl
      通过 protege 构建的本体,用户能够间接用 protege 关上,查看或批改。
    • kg\_demo\_movie_mapping.ttl
      依据 d2rq mapping language 编辑的映射文件,将数据库中的数据映射到咱们构建的本体上。
    • kg\_demo_movie.nt
      利用 d2rq,依据 mapping 文件,由 Mysql 数据库转换失去的 RDF 数据。
    • fuseki_conf.ttl
      fuseki server 配置文件,指定推理引擎,本体文件门路,规定文件门路,TDB 门路等
    • rules.ttl
      规定文件,用于基于规定的推理。
    • streamlit_app.py
      web demo 文件,基于 streamlit 库。

我的项目码源见文末跳转

跳转链接

欢送关注公众号:汀丶人工智能,公众号也会提供一些相干的资源和优质文章。

本文参加了 SegmentFault 思否写作挑战「摸索编码世界之旅 – 记我的第一份编程工作」,欢送正在浏览的你也退出。

正文完
 0