基於語義網的自動問答系統實現

文章同步個人獨立博客

1.本體的創建

本體的作用是描述概念與概念之間的關係。它給出了構成相關領域詞彙的基本術語和關係,以及利用這些術語和關係構成的規定這些詞彙外延的規則的定義。
利用本體,我們可以統一管理所有的數據,使得數據規範化、並能利用本體進行一定程度的推理,提高自動問答技術的性能。
爲了對圖書館的文獻資源進行語義化描述,需要構建本體。我們基於DC和DCTERMS元數據標準, 構建了一個元數據本體。
此外,文獻資源的描述還涉及到其他信息, 譬如作者名、出版機構名、主題詞,分類號等,因爲上述資源目前已有成熟的本體用於描述,我們直接對其進行復用或者進行必要的擴展。 採用的本體: FOAF: 描述個人/作者機構;SKOS: 描述受控詞表;GeoNames: 描述地名;Event: 描述會議事件。
下面給出自定義本體的結構圖:
基於語義網的自動問答系統實現

2.RDF數據的構建

本項目所涉及的數據主要包括圖書館的書目數據,受控詞表數據,個人/組織機構數據和地名數據。 其中,圖書的書目數據來自南京大學圖書館的MARC書目數據,期刊論文,會議論文和學位論文的書目數據來自CNKI網站,作者信息來自南京大學信息管理學院官方網站中教師的個人網頁。
原始數據爲HTML文檔,基於構建的元數據本體及相關本體(FOAF本體,EVENT本體,SKOS模型),將上述數據轉換爲RDF/XML格式。
下面給出一個RDF數據的例子。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
圖書元數據(Book.RDF)
<metaonto:BookRDF:about="http://example/nju.edu.cn/book/9787030220073#i">
<dcterms:titlexml:lang="zh">政務信息資源管理與政府決策</dcterms:title>
<dcterms:creatorRDF:resource="http://example/nju.edu.cn/person/Suxinning#i"/>
<metaonto:abstractxml:lang="zh">本書共八章,內容包括:政務信息資源概論、政務信息資源採集與政府決策、政務信息資源組織與政府決策、政務信息處理與政府決策等。
</metaonto:abstract>
<dcterms:publisherRDF:resource="http://example/nju.edu.cn/organization/SciencePress#i"/>
<metaonto:placePublishedRDF:resource="http://example/nju.edu.cn/place/Beijing#i"/>
<dcterms:dateRDF:datatype="http://www.w3.org/2001/XMLSchema#gYear">2008</dcterms:date>
<dcterms:formatxml:lang="zh">242頁</dcterms:format>
<metaonto:identifierISBN>9787030220073</metaonto:identifierISBN>
<dcterms:subjectRDF:resource="http://example/nju.edu.cn/classification/CLC#D035.1-39"/>
<dcterms:subjectxml:lang="zh">電子政務</dcterms:subject>
<dcterms:subjectxml:lang="zh">信息管理</dcterms:subject>
<RDFs:isDefinedByRDF:resource="http://example/nju.edu.cn/book/9787030220073.RDF"/>
</metaonto:Book>

3.關聯數據的發佈與訪問

3.1關聯數據的定義

關聯數據(即linked data),是一種使得數據之間可以相互鏈接並變得更加有用的發佈結構化數據的方式。它建立在如HTTP、RDF、URIs等標準的WEB技術之上。但是它的目的並不是爲人類閱讀提供web網頁,而是使計算機可以自動的讀取它們進而達到信息的共享。使不同來源的數據可以相互鏈接並被查詢。
之所以要進行關聯數據的發佈,是因爲我們項目目標是開發一個針對關聯的圖書館資源的自動問答系統,也就是說這些圖書館數據是相互關聯的。關聯數據就是利用web在數據和不同的數據源間建立特定的鏈接。要實現輕鬆共享結構化數據的目標,首要步驟就是將現有資源或新生資源發佈爲關聯數據。

3.2關聯數據的構建

圖書館的文獻資源之間,文獻資源與其他資源之間(譬如知識組織資源,人名,地名)存在着相互聯繫,我們採用RDF鏈接顯示地表達它們之間存在的各種關聯關係,形成圖書館的關聯數據。
本系統中用到的數據,相互之間存在着許多聯繫。這些聯繫靠RDF:resource標籤呈現,一個RDF數據實例裏面包含另外一個RDF數據實例的URI。例如,下面三條語句在book和person、organization以及place之間建立了聯繫:

1
2
3
<dcterms:creator RDF:resource="http://example/nju.edu.cn/person/Xuyan#i"/>
<dcterms:publisher RDF:resource="http://example/nju.edu.cn/organization/YuluPress#i"/>
<metaonto:placePublished RDF:resource="http://example/nju.edu.cn/place/Changsha#i"/>

下面給出整個系統中所有數據之間的聯繫,其關聯形式如下圖所示:
linkeddata

3.3 關聯數據的發佈

JenaTDB + Fuseki + Pubby。
關聯數據的發佈主要用到的工具爲Fuseki和Pubby。其中Fuseki集成了RDF數據的存儲工具TDB和Sparql查詢終端。
Pubby的主要作用是在Fuseki提供的Sparql終端上面加一個關聯數據接口。使得所有存儲在TDB中的RDF數據,可以以關聯數據的形式在瀏覽器中訪問。
下面是Fuseki的查詢界面及查詢結果。

fuseki
fesukei_result

Pubby的使用方法:首先下載最新版本的Pubby,然後安裝tomcat或者jetty,這兩者爲Pubby提供了servlet容器,將Pubby下的webapp文件夾拷貝到tomcat或者Jetty的webapps文件夾下,然後更改/WEB-INF/下的配置文件config.ttl,使其適合自身系統。下面的是Pubby和Fuseki結合工作的結構圖。
pubby
Pubby的配置文件分爲三個部分:前綴聲明、server配置、dataset配置。其中server只能有一個,而dataset可以有多個,配置文件的格式如下:

1
2
3
4
5
6
7
8
<> a conf:Configuration;
    conf:option1 value1;
    conf:option2 value2;
    (...)
    conf:dataset [
        conf:option1 value1;
        conf:option2 value2;
    ];.

配置文件當中提供了許多配置選項,配置選項有的是必須的,有的可以缺省。爲了和Sparql終端相連接,需要將conf:SparqlEndpoint設置爲如下形式:
conf:SparqlEndpoint ;

3.4 關聯數據的訪問

採用Sparql查詢, Fuseki是一個Sparql查詢終端。由於關聯數據在發佈的時候會對URI進行重寫,因此用戶在訪問關聯數據的時候,不能通過實際的URI進行,而必須將URI轉換爲與Pubby發佈結果一致的URL。通過觀察可以發現,Pubby在重寫URI的時候存在一定的規律,因此我們可以通過這個規律來訪問關聯數據。
如果Pubby的config.n3配置文件中 conf:webBase的填寫如下:
conf:webBase ;
而原始URI爲http://example/nju.edu.cn/person/ChenYa#i”,那麼發佈出來的URI會變成:

http://127.0.0.1:8080/webapp/page/person/Suxinning%23i

我們注意到這個URL和原始的URI有兩點區別:
a.example/nju.edu.cn/被替換爲127.0.0.1:8080/webapp/page/。
b.“#”被換成了“%23”。

因此,我們可以利用PHP腳本對其進行修改

1
2
3
4
5
$rep_str1="127.0.0.1:8080/webapp/";
$rep_str2="%23";
$result=str_replace("example/nju.edu.cn/",$rep_str1,$var);
echostr_replace("#",$rep_str2,$result);

這樣就實現的URI的替換.

4. 問句的預處理

(1)識別用戶提問中的命名實體,如書名,人名,組織機構名, 目前採用一種簡單而直接的方法,構建一個命名實體列表及其索引,直接在問句中進行字符串匹配查找,然後進行標註, 標註可以採用XML標籤;
(2)中文分詞軟件對中文問句進行分詞處理;
(3)採用解析器Standford Parser 對問句進行句法解析。
分詞:利用ICTCLAS中文分詞

1
2
3
4
5
6
7
8
9
packagecom.xjt.nlp.word;
 
publicclass ICTCLAStest {
  publicstatic void main(String[] args) {
  ICTCLAS instance=ICTCLAS.getInstance();
  String sentence="信息檢索這本書的作者是誰?";
  System.out.println(instance.paragraphProcess(sentence));
  }
}

分詞結果爲:

1
信息/n  檢索/v  這/r  本書/r  的/u  作者/n  是/v  ?/w

下面對一個示例問句進行分析:

1
e.g. who wrote books about information retrieval ?

Parse

1
2
3
4
5
6
7
8
9
(ROOT
     (SBARQ
       (WHNP (WP who))
        (SQ
         (VP (VBD wrote)
           (NP (NNS books))
           (PP (IN about)
             (NP (NN information) (NN retrieval))))) //這裏NP爲名詞短語,也就是說information retrieval應該可以被識別出來
(. ?)))

Typed dependencies

1
2
3
4
5
6
nsubj(wrote-2, who-1)// nsubj 代表nominal subject,可以提取出主語who,知道查詢的結果應該爲WHO,然後通過wrote得到who應該表示creator,於是得到select後面應該爲 ?creator 於是得到三元組<?s :creator ?creator>
root(ROOT-0, wrote-2)
dobj(wrote-2, books-3)// dobj代表 direct object,可以提取出type爲book ,<?s RDF:type metaonto:book>
prep(wrote-2, about-4)
nn(retrieval-6, information-5)//nn代表noun compound modifier,名詞組合,可以得到通過information retrieval通過對詞表的匹配得到其爲subject,然後得到三元組<?s :subject “information retrieval”>
pobj(about-4, retrieval-6)

下面得到Sparql查詢語句

1
2
3
4
5
6
7
8
9
prefix dcterms:<http://purl.org/dc/terms/>
prefix metaonto:<http://example/nju.edu.cn/Ontology/metaonto.owl#>
prefix RDF: <http://www.w3.org/1999/02/22-RDF-syntax-ns#>
select  ?creator
Where
{ ?s  metaonto:type Book
     ?s  dcterms:creator ?creator.
     ?s dcterms:subject “information retrieval”.
}

5. 問題模板的構建和DEMO系統的開發

目前採用手工的方法自行構建某種類型問題的SPARQL查詢模板,將問句手工到映射到對應的模型,在模板的空槽中探入問句中抽取出的命名實體。
本DEMO系統支持自然語言(中文)的查詢,用戶在瀏覽器中輸入查詢問句,系統經過分詞,從問句當中提取出用於構造Sparql查詢的三元組,然後從系統RDF數據中查詢。如果查詢到結果,則在瀏覽器中將結果呈現給用戶,否則告訴用戶資源不存在。
在中文分詞過程中使用了兩個詞典,一個系統詞典和一個用戶自定義詞典,用戶自定義詞典主要用途爲實例提取。本體的功能主要是爲Sparql查詢的構造提供查詢謂語,如foaf:name。所有的RDF數據都存儲在TDB當中。Pubby用於關聯數據的發佈,讓用戶可以用URI查詢到相同資源的更多信息。
DEMO系統的結構如下:
demo
下面對DEMO系統的實現做一個詳細的介紹。

5.1 DEMO系統的分詞

這裏用到的分詞軟件爲簡易中文分詞系統(Simple Chinese Word Segmentation,簡稱SCWS),這是一套基於詞頻詞典的機械式中文分詞引擎,它能將一整段的中文文本基本正確地切分成詞。該系統的分詞算法上並無太多創新成分,採用的是自己採集的詞頻詞典,並輔以一定的專有名稱,人名,地名, 數字年代等規則識別來達到基本分詞,經小範圍測試準確率在 90% ~ 95% 之間, 基本上能滿足一些小型搜索引擎、關鍵字提取等場合運用。
該系統支持用戶自定義詞典,詞典格式爲”xxx.xdb”或者”xxx.txt”,兩者可以相互轉換,詞典必須遵循一定的格式,系統提供的詞典是通用的互聯網信息詞彙集,收錄了大約 28 萬個詞。

5.2 DEMO系統的命名實體抽取

在構造Sparql查詢時,非常關鍵的一點就是命名實體的抽取。例如用戶查詢問句:

1
Question:請告訴我數據倉庫和數據挖掘這本書的作者和出版社?

那麼我們第一步則需要把“數據倉庫和數據挖掘”這個命名實體抽取出來。提取命名實體的辦法有很多種。例如,限定用戶輸入問句時,必須給命名實體一個特殊標識,然後在分詞時利用這個標識把命名實體提取出來。但這樣對用戶而言並不友好,我們不能假定所有的用戶都按照我們的要求來提問。爲了使系統更加的友好,簡單而實用的辦法就是自定義一個用戶詞典,這個詞典記錄了系統所有RDF數據的命名實體名稱。
如果我們不利用用戶詞典直接對問句進行分詞,本例的分詞結果爲:

1
請/告訴/我/數據/倉庫/和/數據/挖掘/這/本/書/的/作者/和/出版社/

可見系統將“數據倉庫和數據挖掘”這個命名實體分割成了“數據/倉庫/和/數據/挖掘”,這樣在構造Sparql查詢時,必定無法查出任何結果,因此這並不是我們所需要的分詞結果。
由於scws分詞時可以使用多個詞典,且用戶自定義詞典優先級大於系統詞典,因此分詞過程中會先利用用戶詞典,然後再使用系統詞典。
在小的測試系統當中,我們可以手工將這些詞抽取出來,並構建用戶詞典,但當數據集到達一定數量時,我們可以利用Jena或者php腳本對RDF數據進行讀取,抽取出命名實體,並利用程序構造詞典。
下面是用戶自定義詞典的樣例:
cidian
【注】自定義詞典中的TF和IDF利用分詞系統提供的一個“新詞生詞的TF/IDF計算器”獲得,此計算器的依據是參照百度搜索結果數量加以計算,計算公式僅適用於 scws 分詞,其它用途則只能用於參考。
利用該方法得到的分詞結果爲:

1
2
3
4
5
6
7
8
9
10
請/告訴/我/數據倉庫和數據挖掘/這/本/書/的/作者/和/出版社/1
這樣就成功的將命名實體提取出來了。
<h4>5.3 DEMO系統的謂語抽取 </h4>
Sparql查詢的構造需要首先構建主語-謂語-賓語三元組,前面我們已經將命名實體(即實例)提取出來了,實例既可以是主語也可以是賓語,但在該DEMO系統當中,我們假定所有的實例在三元組當中都是作爲賓語存在的。
下面一步則需要將謂語從問句中提取出來。如果本體比較龐大,可以利用Jena來解析本體,謂語的提取可以使用Jena解析本體,利用本體當中的RDFs:label標籤的描述和分詞結果進行匹配,然後得到相對應的查詢謂語:
1
dcterms:creator
    RDFs:label  “作者”@zh;
dcterms:publisher
RDFs:label  “出版社”@zh;

對於分詞結果當中的“作者”可以得到查詢謂語”dcterms:creator”。而對於“出版社”則可以得到謂語”dcterms:publisher”。
另外一個替代方法則是使用數據庫,構建一張表格,表格當中存放着Sparql查詢所需要的謂語以及本體RDF:label所對於的描述,表格如下:
predicate
這樣一來,同樣可以得到相對應得謂語。而且不需要每次查詢時都解析本體,只需要簡單的SQL查詢和匹配即可。

5.4 DEMO系統的查詢構造

獲取到賓語和謂語之後,就可以自動生成Sparql查詢語句了,在構建查詢語句時,可以將查詢語句分爲三個部分。
第一部分:前綴,即prefix。對於一個封閉的系統,這一部分是固定的,不需要動態生成,只需要在構建查詢時填充到Sparql查詢中即可。Sparql前綴標識的格式爲:

1
prefix dcterms:<http://purl.org/dc/terms/>

第二部分:查詢目標,查詢目標可以根據查詢謂語獲得,如“作者”和“出版社”都是查詢目標,因此在動態生成Sparql查詢時只需要將這兩者作爲查詢目標即可。

1
Select ?author ?publisher

第三部分:查詢主體,前面兩個步驟的主要目標就是獲得查詢語句的主體部分,按照前面的方法我們已經可以獲得查詢的賓語和謂語,因此查詢主體的構造如下:

1
2
3
4
5
Where {
?s   dcterms:title    "數據倉庫和數據挖掘"@zh.
?s   dcterms:creator  ?author.
?s   dcterms:creator  ?publisher
}

當三個部分都構造好之後就可以將他們合併起來,生成一個完整的Sparql查詢語句。

1
2
3
4
5
6
7
prefix dcterms:<http://purl.org/dc/terms/>
Select ?author ?publisher
Where {
?s   dcterms:title    "數據倉庫和數據挖掘"@zh.
?s   dcterms:creator  ?author.
?s   dcterms: publisher  ?publisher
}

經過在Fuseki中的測試,查詢出來的結果爲:

這樣的查詢並只能夠把查詢出來的結果用URI的形式進行展示,爲了使系統更加的人性化,可以在已有的Sparql查詢語句增加下面兩條語句,

1
2
?author foaf:name ?authorname.
?publisher foaf:name ?publishername.

並將查詢目標改爲:?authorname ?publishername。這樣就可以查詢出作者的名字和出版社的名稱。

1
2
authorname:"蘇新寧" @zh
publishername:"清華大學出版社" @zh

6.中期研究成果

(1)實現關聯數據的發佈,本系統中涉及的所有的圖書館數據都能以關聯數據的形式進行發佈。
例如:
一本書的URI地址爲http://example/nju.edu.cn/book/7302126488#i,Pubby會將該URI自動重寫爲http://127.0.0.1:8080/webapp/page/book/7302126488%23i。 這本書的出版社爲“清華大學出版社”,在系統中所對應的URI地址爲http://example/nju.edu.cn/organization/TsinghuaUniversityPress#i,系統同樣會自動重寫這個URI,使得前面的圖書和這個組織機構相互關聯。
下圖爲以關聯數據形式發佈的“數據倉庫和數據挖掘”這本圖書的書目元數據。
關聯數據發佈
(2)開發出一個針對語義網數據的自動問答DEMO系統,系統提供自然語言和Sparql查詢兩種查詢界面。SPARQL查詢界面可供專業人員使用,直接輸入SPARQL查詢;自然語言查詢界面可以面向普通用戶,以自然語言問句的形式輸入要查詢的信息, 界面更加友好和易用。
所有查詢出來的資源,都採用一個URI地址進行表示,這個URI地址時可訪問的,能夠點擊進去顯示更多相關信息。 

下面給出系統查詢演示效果。
自然語言查詢演示

1
問題1:網絡信息資源蒐集與利用這本書的作者感興趣的課題有哪些?

自然語言

1
問題2:歐石燕老師感興趣的課題有哪些?

自然語言2
SPARQL查詢演示
下面給出一個Sparql查詢,它查詢出“蘇新寧”老師所著書籍。

1
2
3
4
5
6
7
8
prefix dcterms:<http://purl.org/dc/terms/>
prefix foaf:<http://xmlns.com/foaf/1.0/>
Select  ?title
from <http://book/book>
Where{  ?author  foaf:name      "蘇新寧"@zh.
            ?s      dcterms:creator  ?author;
                    dcterms:title    ?title.   
}

sparql
查詢結果
sparqlres
(3)完成多篇與本項目相關的綜述以及技術博文,詳細內容參見附件。

7、研究心得

通過本次項目的經歷,我們對語義網的概念有了進一步的瞭解和認識,接觸到了許多語義網相關的前沿技術。例如:SPARQL查詢、JENA、ARC2等。不僅如此,我們還學習了許多其他的實用技術,如爲了發佈關聯數據,我們認真學習了PHP腳本語言。爲了實現中英文的分詞和句子解析樹的生成,我們學習了stanford parser和lucene-core提供的中文分詞方法。爲了學習JENA,我們認真學習了JAVA相關的技術。此外,我們還閱讀了許多英文文獻,從中汲取了許多知識和思想。
在DEMO系統開發的過程當中,遇到了很多難題。首先,剛開始的着手開發系統時,並沒有可以參考的原型,因此,很多實現細節都需要自己邊動手寫程序,邊思考問題如何解決。雖然進入並不如人意。但是進過反覆不斷的實驗和測試,系統最終實現了我們想要的基本功能。
在關聯數據的發佈中,曾經花了很多時間在測試Pubby上面,無數次的失敗使得我們想放棄使用Pubby而使用其他的工具來代替它。但是最終我們還是堅持下來,測試成功,完成了關聯數據的發佈。
總而言之,本次創新項目,讓我們學習到了許多的技術,也鍛鍊了我們做研究的思維。從中我們體會到了學術研究過程的艱辛與曲折,以及做出成果之後的興奮感。

8. DEMO系統的小部分的代碼

Sparql查詢生成函數

1
2
3
4
5
6
7
8
9
10
11
12
functioncase1($book_query_target,$book_query_pre,$book_arr,$len_book_arr,$main_predicate){
$Function_Compose_Query= newFunctionComposeQuery();
  $query="
  prefix dcterms:<http://purl.org/dc/terms/>
  prefix metaonto:<http://example/nju.edu.cn/Ontology/metaonto.owl#>
  prefix foaf:<http://xmlns.com/foaf/1.0/>
  Select".$Function_Compose_Query->query_target($book_query_target,$len_book_arr)."
  from <http://book/book>
  Where
  {".$Function_Compose_Query->book_query($book_arr,$book_query_pre,$book_query_target,$main_predicate)."}";
   return$query;
  }

結果處理程序片段

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
    functionURIprocess($urivar){
        if(strchr($urivar,"http://")){
            $var=$urivar;
            $rep_str1="127.0.0.1:8080/webapp/page/";
            $rep_str2="%23";
            $result=str_replace("example/nju.edu.cn/",$rep_str1,$var);
            $res=str_replace("#",$rep_str2,$result);
            echo"<td style=\"word-break:break-all\" width=\"5%\"><a href=".$res." target=\"_blank\">";
            echo$urivar;
            echo"</a></td>";
        }
        else{
            echo"<td style=\"word-break:break-all\" width=\"5%\">";
            //print_r($urivar);
            echo$urivar;
            echo"<br/></td>";
        }
     
   }
 ?>

ARC2配置片段

1
2
3
4
5
6
7
8
/* configuration */
$config= array(
  /* remote endpoint */
  'remote_store_endpoint'=> 'http://localhost:3030/ds/Sparql',
);
 
/* instantiation */
$store= ARC2::getRemoteStore($config);

自然語言處理的程序片段

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
functionlanguageparser($text){
    $sh= scws_open();
    scws_set_charset($sh,'utf8');
    //添加自己的詞典,該詞典用於書名、人名等的查詢;這樣就可以把書名和人名等完整的分類出來;
    scws_add_dict($sh,'D:/Program Files/scws/etc/mydict.txt',SCWS_XDICT_TXT);
    //系統默認的詞典
    scws_add_dict($sh,'D:/Program Files/scws/etc/dict.utf8.xdb');
    scws_set_rule($sh,'D:/Program Files/scws/etc/rules_cht.utf8.ini');                   
    //送入函數進行句子處理
    scws_send_text($sh,$text);
    //獲取結果
    $top=scws_get_result($sh);
    //返回結果
    return$top;
}
?>

參考網站:scws

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章