最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

從零開始構(gòu)建一個(gè)電影知識(shí)圖譜,實(shí)現(xiàn)KBQA智能問答[下篇]

2023-07-11 17:47 作者:汀丶人工智能  | 我要投稿

從零開始構(gòu)建一個(gè)電影知識(shí)圖譜,實(shí)現(xiàn)KBQA智能問答[下篇]:Apache jena SPARQL endpoint及推理、KBQA問答Demo超詳細(xì)教學(xué)

效果展示:

1.Apache jena SPARQL endpoint及推理

在上一篇我們學(xué)習(xí)了如何利用 D2RQ 來開啟 endpoint 服務(wù),但它有兩個(gè)缺點(diǎn):

  1. 不支持直接將 RDF 數(shù)據(jù)通過 endpoint 發(fā)布到網(wǎng)絡(luò)上。

  2. 不支持推理。

這次我們介紹的?Apache Jena?能夠解決上面兩個(gè)問題。

## 1.1.Apache Jena 簡(jiǎn)介

Apache Jena(后文簡(jiǎn)稱 Jena),是一個(gè)開源的 Java 語義網(wǎng)框架(open source Semantic Web Framework for Java),用于構(gòu)建語義網(wǎng)和鏈接數(shù)據(jù)應(yīng)用。下面是 Jena 的架構(gòu)圖:

本次實(shí)踐我們會(huì)用到的組件有:TDB、rule reasoner 和 Fuseki。

  1. TDB 是 Jena 用于存儲(chǔ) RDF 的組件,是屬于存儲(chǔ)層面的技術(shù)。在單機(jī)情況下,它能夠提供非常高的 RDF 存儲(chǔ)性能。目前 TDB 的最新版本是 TDB2,且與 TDB1 不兼容。

  2. Jena 提供了 RDFS、OWL 和通用規(guī)則推理機(jī)。其實(shí) Jena 的 RDFS 和 OWL 推理機(jī)也是通過 Jena 自身的通用規(guī)則推理機(jī)實(shí)現(xiàn)的。

  3. Fuseki 是 Jena 提供的 SPARQL 服務(wù)器,也就是 SPARQL endpoint。其提供了四種運(yùn)行模式:?jiǎn)螜C(jī)運(yùn)行、作為系統(tǒng)的一個(gè)服務(wù)運(yùn)行、作為 web 應(yīng)用運(yùn)行或者作為一個(gè)嵌入式服務(wù)器運(yùn)行。

Jena 目前是使用最廣泛、文檔最全、社區(qū)最活躍的一個(gè)開源語義網(wǎng)框架。更多的細(xì)節(jié),讀者可以參考官方文檔。

## 1.2.Fuseki 與 OWL 推理實(shí)戰(zhàn)

我們先下載 Jena 的最新版本(fuseki 和其他的功能模塊不在同一個(gè)文件中,需要分別下載 apache-jena 和 apache-jena-fuseki)。后續(xù)操作以 Windows 為例,Linux 類似,只是腳本位置不同。

創(chuàng)建一個(gè)目錄(我這里命名為 “tdb”)用于存放 tdb 數(shù)據(jù)。進(jìn)入“apache-jena-X.X.X” 文件夾的 bat 目錄,可以看到很多批處理文件,我們使用 “tdbloader.bat” 將之前我們的 RDF 數(shù)據(jù)以 TDB 的方式存儲(chǔ)。命令如下:

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

“--loc” 指定 tdb 存儲(chǔ)的位置,即剛才我們創(chuàng)建的文件夾;第二個(gè)參數(shù)是由 Mysql 數(shù)據(jù)轉(zhuǎn)換得到的 RDF 數(shù)據(jù)。

進(jìn)入入 “apache-jena-fuseki-X.X.X” 文件夾,運(yùn)行 “fuseki-server.bat”,然后退出。程序會(huì)為我們?cè)诋?dāng)前目錄自動(dòng)創(chuàng)建“run” 文件夾。將我們的本體文件 “ontology.owl” 移動(dòng)到 “run” 文件夾下的 “databases” 文件夾中,并將 “owl” 后綴名改為 “ttl”。在“run” 文件夾下的 “configuration” 中,我們創(chuàng)建名為 “fuseki_conf.ttl” 的文本文件(取名沒有要求),加入如下內(nèi)容:

@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推理機(jī) ? ? 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" ; ? ? .

再次運(yùn)行 “fuseki-server.bat”,如果出現(xiàn)如下界面表示運(yùn)行成功:

Fuseki 默認(rèn)的端口是 3030,瀏覽器訪問 “http://localhost:3030/”,?和之前介紹的 D2RQ web 界面類似,我們可以進(jìn)行 SPARQL 查詢等操作。在 Python 中用 SPARQLWrapper 向 Fuseki server 發(fā)送查詢請(qǐng)求:

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. }

即查詢電影《功夫》的所有屬性。返回的結(jié)果:

? ? ? ? ? ? ? ? ? ? ? ? ? ?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年代的上海,自小受盡欺辱的街頭混混阿星(周星馳)為了能出人頭地,可謂窺見機(jī)會(huì)的縫隙就往里鉆,今次他盯上行動(dòng)日益猖獗的黑道勢(shì)力“斧頭幫”,想借之大名成就大業(yè)?! “⑿羌倜啊案^幫”成員試圖在一個(gè)叫“豬籠城寨”的地方對(duì)居民敲詐,不想引來真的“斧頭幫”與“豬籠城寨”居民的恩怨?!柏i籠城寨”原是藏龍臥虎之處,居民中有許多身懷絕技者(元華、梁小龍等),他們隱藏于此本是為遠(yuǎn)離江湖恩怨,不想麻煩自動(dòng)上身,躲都躲不及。而在觀戰(zhàn)正邪兩派的斗爭(zhēng)中,阿星逐漸領(lǐng)悟功夫的真諦。 ? 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 推理機(jī)得到的,即我們?cè)镜?RDF 數(shù)據(jù)里面是沒有的??梢栽?D2RQ 的 endpoint 中進(jìn)行同樣的查詢,得到如下結(jié)果:

? ? ? ? ? ? ? ? ? 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年代的上海,自小受盡欺辱的街頭混混阿星(周星馳)為了能出人頭地,可謂窺見機(jī)會(huì)的縫隙就往里鉆,今次他盯上行動(dòng)日益猖獗的黑道勢(shì)力“斧頭幫”,想借之大名成就大業(yè)?! “⑿羌倜啊案^幫”成員試圖在一個(gè)叫“豬籠城寨”的地方對(duì)居民敲詐,不想引來真的“斧頭幫”與“豬籠城寨”居民的恩怨。“豬籠城寨”原是藏龍臥虎之處,居民中有許多身懷絕技者(元華、梁小龍等),他們隱藏于此本是為遠(yuǎn)離江湖恩怨,不想麻煩自動(dòng)上身,躲都躲不及。而在觀戰(zhàn)正邪兩派的斗爭(zhēng)中,阿星逐漸領(lǐng)悟功夫的真諦。 ? 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 ?

這些是真實(shí)存在于 “kgdemomovie.nt” 的數(shù)據(jù)。

## 1.3.規(guī)則推理實(shí)戰(zhàn)

在 “databases” 文件夾下新建一個(gè)文本文件“rules.ttl”,填入如下內(nèi)容:

@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)]

我們定義了一個(gè)名為 “ruleComedian” 的規(guī)則,它的意思是:如果有一個(gè)演員,出演了一部喜劇電影,那么他就是一位喜劇演員。修改配置文件“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> ] ; ? ? #關(guān)閉OWL推理機(jī) ? ? #ja:reasoner [ja:reasonerURL <http://jena.hpl.hp.com/2003/OWLFBRuleReasoner>] . ? ? #開啟規(guī)則推理機(jī),并指定規(guī)則文件路徑 ? ? 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" ; ? ? .

我們只能啟用一種推理機(jī)。前面也提到,OWL 的推理功能也可以在規(guī)則推理機(jī)里面實(shí)現(xiàn),因此我們定義了 “ruleInverse” 來表示 “hasActedIn” 和“hasActor”的相反關(guān)系。更多細(xì)節(jié)讀者可以參考文檔。

我們執(zhí)行如下 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

查詢結(jié)果:

? ? ? ? ? ? ? ? ? ? ? ? ? ?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.小結(jié)

本次實(shí)踐介紹了如何使用 Jena 來開啟 endpoint 服務(wù),提供高效的查詢;并介紹了如何加入推理引擎。我們是用 Jena 提供的命令行工具來完成上述操作。實(shí)際上,jena 提供了所有工具的 API 接口,讀者可以用 Java 編寫程序,進(jìn)行開發(fā)。

2.KBQA Demo

下面將介紹如何用 Python 完成一個(gè)簡(jiǎn)易的問答程序。下圖是 demo 的展示效果:

查詢結(jié)果為空,回答 “I don't know.”;不能理解問句,回答 “I can't understand.”。本實(shí)現(xiàn)參考了王昊奮老師發(fā)布在 OpenKG 上的 demo“基于 REfO 的 KBQA 實(shí)現(xiàn)及示例”,讀者也可以參考此示例,來完成本 demo。下面談?wù)劚?demo 的流程。

## 2.1 基本流程

此 demo 是利用正則表達(dá)式來做語義解析。我們需要第三方庫來完成初步的自然語言處理(分詞、實(shí)體識(shí)別),然后利用支持詞級(jí)別正則匹配的庫來完成后續(xù)的語義匹配。

分詞和實(shí)體識(shí)別(人名和電影名)我們用 jieba 來完成。jieba 是一個(gè)輕量級(jí)的中文分詞工具,有多種語言的實(shí)現(xiàn)版本。對(duì)于分詞,在實(shí)驗(yàn)環(huán)境中,jieba 還是勉強(qiáng)能用。在我們這個(gè) demo 當(dāng)中,有些經(jīng)常會(huì)被使用的詞語并不能被正確切分。比如:“喜劇電影”、“恐怖電影”、“科幻電影”、“喜劇演員”、“出生日期”等,在分詞的時(shí)候,jieba 把它們當(dāng)作一個(gè)詞來處理,我們需要手動(dòng)調(diào)整詞語的頻率使得 “喜劇電影” 能被切分為 “喜劇” 和“電影”。至于實(shí)體識(shí)別,jieba 對(duì)于人名的識(shí)別精度尚可接受,但是電影名稱的識(shí)別精度太低以至于完全不可用。因此,我們直接把數(shù)據(jù)庫中的人名和電影名導(dǎo)出,作為外部詞典;使用 jieba 的時(shí)候加載外部詞典,這樣就能解決實(shí)體識(shí)別的問題。

將自然語言轉(zhuǎn)為以詞為基礎(chǔ)的基本單位后,我們使用 REfO(Regular Expressions for Objects) 來完成語義匹配。具體實(shí)現(xiàn)請(qǐng)參考 OpenKG 的 demo 或者本 demo 的代碼。

匹配成功后,得到其對(duì)應(yīng)的我們預(yù)先編寫的 SPARQL 模板,再向 Fuseki 服務(wù)器發(fā)送查詢,最后將結(jié)果打印出來。

## 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" 獲取數(shù)據(jù)的腳本。

  • "KB_query" 文件夾包含的是完成整個(gè)問答 demo 流程所需要的腳本。

  • "external_dict" 包含的是人名和電影名兩個(gè)外部詞典。csv 文件是從 mysql-workbench 導(dǎo)出的,按照 jieba 外部詞典的格式,我們將 csv 轉(zhuǎn)為對(duì)應(yīng)的 txt。

  • "word_tagging",定義 Word 類的結(jié)構(gòu)(即我們?cè)?REfO 中使用的對(duì)象);定義 "Tagger" 類來初始化詞典,并實(shí)現(xiàn)自然語言到 Word 對(duì)象的方法。

  • "jenasparqlendpoint",用于完成與 Fuseki 的交互。

  • "question2sparql",將自然語言轉(zhuǎn)為對(duì)應(yīng)的 SPARQL 查詢。

  • "question_temp",定義 SPARQL 模板和匹配規(guī)則。

  • "query_main",main 函數(shù)。

在運(yùn)行 "query_main" 之前,讀者需要啟動(dòng) Fuseki 服務(wù),具體方法請(qǐng)參考上一篇文章。

## 2.3 小結(jié)

我們通過使用正則表達(dá)式的方式來解析自然語言,并將解析的結(jié)果和我們預(yù)定義的模板進(jìn)行匹配,最后實(shí)現(xiàn)一個(gè)簡(jiǎn)易的 KBQA。方法沒有大家想象的那么 “高大上”,沒有統(tǒng)計(jì)方法、沒有機(jī)器學(xué)習(xí)也沒有深度學(xué)習(xí)。正則的好處是,易學(xué),從事相關(guān)行業(yè)的人基本都了解這個(gè)東西;其次,可控性強(qiáng)或者說可解釋性強(qiáng),如果某個(gè)問題解析錯(cuò)誤,我們只要找到對(duì)應(yīng)的匹配規(guī)則進(jìn)行調(diào)試即可;最后,正則冷啟動(dòng)比較容易,在沒有數(shù)據(jù)或者數(shù)據(jù)極少的情況下,我們可以利用正則規(guī)則馬上上線一個(gè)類似上述 demo 的初級(jí)的問答系統(tǒng)。在現(xiàn)實(shí)情況中,由于上述優(yōu)點(diǎn),工業(yè)界也比較青睞用正則來做語義解析。正則方法的缺陷也是顯而易見的,它并不能理解語義信息,而是基于符號(hào)的匹配。換個(gè)角度說,用正則的方法,就需要規(guī)則的設(shè)計(jì)者能夠盡可能考慮到所有情況,然而這是不可能的。暫且不考慮同義詞、句子結(jié)構(gòu)等問題,光是羅列所有可能的問題就需要花費(fèi)很大的功夫。盡管如此,在某些垂直領(lǐng)域,比如 “音樂”,“電影”,由于問題集合的規(guī)模在一定程度上是可控的(我們基本能將用戶的問題劃定在某個(gè)范圍內(nèi)),正則表達(dá)式還是有很大的用武之地的。在冷啟動(dòng)一段時(shí)間,獲得了一定用戶使用數(shù)據(jù)之后,我們可以考慮引入其他的方法來改善系統(tǒng)的性能,然后逐漸減少正則規(guī)則在整個(gè)系統(tǒng)中的比重。如果讀者想深入研究 KBQA,可以參考專欄 “揭開知識(shí)庫問答 KB-QA 的面紗”,該專欄的作者詳細(xì)介紹了做 KBQA 的方法和相關(guān)研究。

3.項(xiàng)目實(shí)操

3.1環(huán)境配置

  1. Python版本為3.6

  2. 安裝依賴pip install -r requirements.txt。

  3. jena版本為3.5.0,已經(jīng)上傳在該repo中(如果不用Docker運(yùn)行demo,需要自己修改配置文件中的路徑)。

  4. d2rq使用的0.8.1

3.2 運(yùn)行方式

這里提供兩種運(yùn)行demo的方式:

  1. 直接構(gòu)建docker鏡像,部署容器服務(wù)。推薦這種方式,已經(jīng)把各種環(huán)境配置好了。只需要安裝docker,構(gòu)建鏡像。

  2. 直接在本地運(yùn)行。需要自行修改配置文件(jena/apache-jena-fuseki-3.5.0/run/configuration/fuseki_conf.ttl配置文件中的路徑)

3.3 構(gòu)建docker鏡像

進(jìn)入項(xiàng)目根目錄

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

打開瀏覽器,輸入localhost,即能看到demo界面。 ## 3.4 本地運(yùn)行 其實(shí)就是把Dockerfile里面的命令直接在本地環(huán)境運(yùn)行(記得修改configuration/fuseki_conf.ttl中的文件路徑)。 第一步:安裝依賴庫

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

第二步:將nt格式的三元組數(shù)據(jù)以tdb進(jìn)行存儲(chǔ)(怎么得到kg_demo_movie.nt文件請(qǐng)參考`上篇`內(nèi)容)。

shell script /kbqa/jena/apache-jena-3.5.0/bin/tdbloader --loc="pathoftdb" "pathofkgdemomovie.nt" # 自行指定tdb的路徑,記得和configuration/fuseki_conf.ttl中一致

window環(huán)境是使用/kbqa/jena/apache-jena-3.5.0/bat/tdbloader.bat 第三步:設(shè)置環(huán)境變量(windows如何設(shè)置請(qǐng)自行查詢;也可以不設(shè)置streamlit端口,使用默認(rèn)端口,第五步啟動(dòng)后會(huì)提示服務(wù)的端口)

shell script export.UTF-8 LCALL=C.UTF-8 STREAMLITSERVERPORT=80 FUSEKIHOME=/kbqa/jena/apache-jena-fuseki-3.5.0

第四步:運(yùn)行fuseki(進(jìn)入apache-jena-fuseki-3.5.0子目錄,windows運(yùn)行fuseki-server.bat)

shell script ./fuseki-server

第五步:運(yùn)行web服務(wù)。

shell script streamlit run streamlit_app.py --server.enableCORS=true ```

打開瀏覽器,輸入指定的地址即可。

3.5 問題集錦

  1. fuseki-server服務(wù)啟動(dòng)后,關(guān)閉重啟會(huì)報(bào)錯(cuò)。這是jena的一個(gè)bug,把tdb中的文件刪了,重新用tdbloader命令生成一次即可。

  • 目錄結(jié)構(gòu)

    包含ER圖模型文件和創(chuàng)建數(shù)據(jù)庫、表,插入所有數(shù)據(jù)的sql文件。用戶可以直接使用sql文件導(dǎo)入數(shù)據(jù)到mysql中。

    • "external_dict"包含的是人名和電影名兩個(gè)外部詞典。csv文件是從mysql-workbench導(dǎo)出的,按照jieba外部詞典的格式,我們將csv轉(zhuǎn)為對(duì)應(yīng)的txt。

    • "word_tagging",定義Word類的結(jié)構(gòu)(即我們?cè)赗EfO中使用的對(duì)象);定義"Tagger"類來初始化詞典,并實(shí)現(xiàn)自然語言到Word對(duì)象的方法。

    • "jena_sparql_endpoint",用于完成與Fuseki的交互。

    • "question2sparql",將自然語言轉(zhuǎn)為對(duì)應(yīng)的SPARQL查詢。

    • "question_temp",定義SPARQL模板和匹配規(guī)則。

    • "query_main",main函數(shù)。在運(yùn)行"query_main"之前,讀者需要啟動(dòng)Fuseki服務(wù)。

    • kg_demo_movie文件夾

    • crawler中的movie_crawler用于從The Movie DB下載數(shù)據(jù),用戶需要自己去網(wǎng)站注冊(cè)賬號(hào),申請(qǐng)API KEY。在腳本中填入自己的API KEY,填寫mysql相關(guān)參數(shù)即可運(yùn)行。用戶需要額外下載的包:requests和pymysql。tradition2simple用于將繁體字轉(zhuǎn)為簡(jiǎn)體字(聲明一下,我找不到該文件的出處了,我是從網(wǎng)上找到的解決方案,如果有用戶知道該作者,麻煩告知,我會(huì)備注)。

    • KB_query文件夾包含的是完成整個(gè)問答demo流程所需要的腳本。

    • ontology.owl 通過protege構(gòu)建的本體,用戶可以直接用protege打開,查看或修改。

    • kg_demo_movie_mapping.ttl 根據(jù)d2rq mapping language編輯的映射文件,將數(shù)據(jù)庫中的數(shù)據(jù)映射到我們構(gòu)建的本體上。

    • kg_demo_movie.nt 利用d2rq,根據(jù)mapping文件,由Mysql數(shù)據(jù)庫轉(zhuǎn)換得到的RDF數(shù)據(jù)。

    • fuseki_conf.ttl fuseki server配置文件,指定推理引擎,本體文件路徑,規(guī)則文件路徑,TDB路徑等

    • rules.ttl 規(guī)則文件,用于基于規(guī)則的推理。

    • streamlit_app.py web demo文件,基于streamlit庫。

    • Data文件夾

項(xiàng)目碼源見文末跳轉(zhuǎn)

[跳轉(zhuǎn)鏈接]:https://blog.csdn.net/sinat_39620217/article/details/131662662

歡迎關(guān)注公眾號(hào):汀丶人工智能,公眾號(hào)也會(huì)提供一些相關(guān)的資源和優(yōu)質(zhì)文章。


從零開始構(gòu)建一個(gè)電影知識(shí)圖譜,實(shí)現(xiàn)KBQA智能問答[下篇]的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
邢台市| 元江| 高要市| 花垣县| 凤城市| 嫩江县| 娄烦县| 肃北| 青神县| 二连浩特市| 峨山| 蛟河市| 陵水| 高唐县| 克什克腾旗| 温宿县| 宜宾县| 蕉岭县| 平陆县| 金华市| 崇信县| 南召县| 精河县| 平度市| 饶平县| 五河县| 象州县| 仙游县| 闵行区| 阳高县| 资阳市| 通江县| 北辰区| 容城县| 沾化县| 滨州市| 册亨县| 镇平县| 方城县| 锦屏县| 安陆市|