上篇文章电影知识图谱问答(二)|生成298万条RDF三元组数据中讲到如何将爬取得到的豆瓣电影和书籍数据转换成知识图谱所需的RDF类型数据,本篇文章将介绍如何将得到的298万条RDF类型数据存储到知识图谱数据库之中,并介绍如何利用SPARQL进行知识检索。实践之前,请自主学习Apache Jena, Apache Fuseki, SPARQL相关知识。


1. 知识图谱数据库

既然是要存储三元组数据,那选择什么样的数据库呢?你可能见过很多类型的数据库软件,比如MySql、MongoDB等,那么能不能采用这些传统数据库呢?答案是不能,因此传统关系型数据库不能够体现知识间的层次关系,更不能进行知识推理和知识检索。因此,需要选择特定的图数据库,目前常用的图数据库包括Neo4j和Apache Jena。

Neo4j是高性能、NoSQL类型的图数据库,存储过程中将数据表示为节点,数据之间的关系表示为边,节点和边的类型可以是字符串、数字等。Neo4j能够存储百亿节点,形成巨大的图网络结构,即大规模知识图谱。Neo4j能够非常方便的将数据可视化,看出数据之间的关联关系,可视化效果如下所示。
Neo4j.png

Apache Jena是开源的Java语义网框架,用于链接数据和构建语义网,可存储RDF、RDFS类型数据。Apache Jena提供TDB、Rule Reasoner、Fuseki组件,其中TDB是Jena用于存储RDF类型数据的组件,属于存储层面的技术;Rule Reasoner可进行简单规则推理,支持用户进行自定义推理规则;Fuseki是Jena提供的SPARQL服务器,支持SPARQL语言进行检索,可在单机和服务器端高效运行。
Jena.png

因为知识图谱问答需定义很多推理规则,对可视化没有太多要求,所以我们选择Apache Jena来存储RDF数据。有兴趣的朋友可尝试Neo4j图数据库,另外北大自研的gStore也可以尝试一下,有成果后欢迎分享。

2. Apache Jena知识存储

选择好存储方法(Apache Jena)之后,便需要了解如何进行知识存储和知识检索,具体流程包括将RDF类型数据转换成TDB类型数据、配置及启动Apache Fuseki、利用SPARQL从Apache Jena中进行知识检索。

2.1 RDF2TDB

Apache Jena需要tdb类型的数据,所以需要将已得到的RDF类型数据转换成tdb类型数据,转换方法可通过Apache Jena提供的工具进行实现。

首先创建tdb文件夹,后续用于存储生成的tdb类型数据。接下来下载Apache Jena,下载完成之后进入到apache-jena-3.12.0/bin目录,利用下列命令将RDF类型数据转换成TDB类型数据,其中/GitHub/DouBan-KGQA/data/tdb是tdb文件夹路径,/GitHub/DouBan-KGQA/data/rdf/douban_kgqa.nt是生成的RDF数据地址。

./tdbloader --loc="/GitHub/DouBan-KGQA/data/tdb" "/GitHub/DouBan-KGQA/data/rdf/douban_kgqa.nt"

2.2 Fuseki配置

转换成TDB类型数据完成之后,如果想要在网页端进行查看和检索,还需要配置Apache Fuseki。首先进行下载Apache Fuseki,下载完成之后,进入到apache-jena-fuseki-3.12.0/文件夹内,运行下列命令。

./fuseki-server

运行完之后,退出上述命令,Apache Fuseki会自动在apache-jena-fuseki-3.12.0/文件夹内创建run/文件。进入到/apache-jena-fuseki-3.12.0/run/database/文件夹,创建douban_kgqa_inference.ttl文件,配置自定义推理规则,示例如下所示,比如自反规则(p导演了电影m也可以表示为m电影的导演是p)。

@prefix : <http://www.douban_kgqa.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#> .


[ruleInverse: (?p :has_acted_in ?m) -> (?m :has_actor ?p)]
[ruleInverse: (?p :has_writed_in ?m) -> (?m :has_writer ?p)]
[ruleInverse: (?p :has_directed_in ?m) -> (?m :has_director ?p)]
[ruleInverse: (?p :has_authored_in ?m) -> (?m :has_author ?p)]
[ruleInverse: (?p :has_translated_in ?m) -> (?m :has_translator ?p)]

自定义规则配置完成之后,需要将生成的tdb类型数据和Apache Fuseki进行关联,配置文件路径为/apache-jena-fuseki-3.12.0/run/configuration/fuseki_conf.ttl。配置文件如下所示,其中需要修改的是fuseki:nameja:rulesFromtdb:location。fuseki:name替换成前面定义的数据库名称,ja:rulesFrom为自定义推理机路径,tdb:location为生成的tdb文件夹路径。详细配置文件可参考官方教程https://jena.apache.org/documentation/fuseki2/fuseki-configuration.html

@prefix fuseki:  <http://jena.apache.org/fuseki#> .
@prefix rdf:     <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs:    <http://www.w3.org/2000/01/rdf-schema#> .
@prefix tdb:     <http://jena.hpl.hp.com/2008/tdb#> .
@prefix ja:      <http://jena.hpl.hp.com/2005/11/Assembler#> .
@prefix :        <#> .

<#service1>  rdf:type fuseki:Service ;
    fuseki:name                       "douban_kgqa" ;       # http://host:port/tdb
    fuseki:serviceQuery               "sparql" ;    # SPARQL query service
    fuseki:serviceQuery               "query" ;    # SPARQL query service (alt name)
    fuseki:serviceUpdate              "update" ;   # SPARQL update service
    fuseki:serviceUpload              "upload" ;   # Non-SPARQL upload service
    fuseki:serviceReadWriteGraphStore "data" ;     # SPARQL Graph store protocol (read and write)
    # A separate read-only graph store endpoint:
    fuseki:serviceReadGraphStore      "get" ;      # SPARQL Graph store protocol (read only)
    fuseki:dataset           <#dataset> ;
    .

<#dataset> rdf:type ja:RDFDataset ;
    ja:defaultGraph <#modelInf> ;
    .

<#modelInf> rdf:type ja:InfModel ;
    ja:reasoner [
        ja:reasonerURL <http://jena.hpl.hp.com/2003/GenericRuleReasoner>;
        # ubuntu
        # ja:rulesFrom <file:///home/ubuntu/DouBan-KGQA/json2jena/rdf2jena/apache-jena-fuseki-3.10.0.2/run/databases/douban_kgqa_inference.ttl>;
    ];
    ja:baseModel <#g> ;
    .

<#g> rdf:type tdb:GraphTDB ;
    # ubuntu
    # tdb:location "/home/ubuntu/DouBan-KGQA/data/tdb/" ;
    tdb:unionDefaultGraph true ;

fuseki_conf.ttl配置完成之后,再次运行下列命令,便能够启动Apache Jena和Apache Fuseki服务。

./fuseki-server

Neo4j.png

启动成功之后,打开http://localhost:3030/网页便能够进行查看和知识检索。

Fuseki-Demo.png

3. SPARQL知识检索

数据存储成功之后,便能够通过SPARQL检索语言从Apache Jena数据库之中进行检索答案。比如查询流浪地球的主演有哪些?,翻译成SPARQL检索语言如下所示。

PREFIX : <http://www.douban_kgqa.com#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>

SELECT ?x WHERE {
  ?s :movie_info_name '流浪地球'.
  ?s :has_actor ?a.
  ?a :movie_person_name ?x.
}
LIMIT 25

利用上述SPARQL查询语言,在Apache Fuseki网页中便能够检索得到答案,如下图所示,能够得到如下吴京、赵今麦等等答案。
SPARQL.png

当然,通过SPARQL查询语言也能够查询得到流浪地球的上映时间是什么时候?流浪地球的导演是谁?吴京的出生地是在哪儿?围城的作者是谁?等等问题答案。但难点问题是如何将自然语言问句转换得到SPARQL查询语句?

4.总结

本篇文章介绍了常用两种图数据库的特点,并选用Apache Jena数据库作为知识存储。同时,介绍了如何将RDF类型数据转换成Apache Jena所需的tdb类型数据,如何配置Apache Fuseki引擎,如何利用SPARQL查询语句进行知识检索。但同时我们发现,利用SPARQL能够进行知识检索,但如何将自然语言问句转换成SPARQL查询语句成为难点问题,下篇文章我们进行详细分析。


欢迎关注公众号谓之小一阅读更多内容。
公众号

文章目录
文章目录