實踐篇(一):數據準備和本體建模
通過前面幾篇文章的介紹,讀者應該對知識圖譜,其相關概念,以及語義網技術棧中的RDF,RDFS/OWL有了一定的了解。然而,之前我們都是在介紹一些概念性的東西。實踐才出真知,理論掌握得再好,不能解決實際問題也只是紙上談兵。因此,筆者準備開一個實踐篇,結合理論篇,讓讀者能夠從無到有構建一個領域知識圖譜,並在其上搭建一個基於知識圖譜的問答小程序。demo比較簡單,問答實現是基於模板匹配和正則表達式,整個流程是為了讓讀者對知識圖譜及其相關應用有個直觀的認識。
本文作為實踐篇第一篇文章,首先介紹我們使用的數據、數據來源和數據獲取方法;其次,基於數據內部關係,介紹如何以自頂向下的方式構建本體結構。
一、數據準備
實踐篇使用的數據是與電影相關的。基本統計數據如下:
1. 演員數量:505人
2. 電影數量:4518部
3. 電影類型:19類
4. 人物與電影的關係:14451
5. 電影與類型的關係:7898
演員的基本信息包括:姓名、英文名、出生日期、死亡日期、出生地、個人簡介。
電影的基本信息包括:電影名稱、電影簡介、電影評分、電影發行日期、電影類型。
數據是從「The Movie Database (TMDb」網站獲取的,官方提供註冊用戶API KEY用於查詢和下載數據。我本來打算從豆瓣獲取電影數據,但現在豆瓣API已經關閉了個人用戶申請入口。
本實例數據獲取方法:以周星馳為初始入口,獲取其出演的所有電影;再獲取這些電影的所有參演演員;最後獲取所有參演演員所出演的全部電影。經過去重處理,我們得到了505個演員的基本信息和4518部電影的基本信息。數據保存在mysql中,其ER圖如下:
讀者可以直接下載我們獲取到的數據,或者用我們提供的腳本自己從網站獲取額外的數據,再或者根據自己的需要重新編寫腳本。
二、本體建模
本體的構建大體有兩種方式:自頂向下和自底向上。
1. 開放域知識圖譜的本體構建通常用自底向上的方法,自動地從知識圖譜中抽取概念、概念層次和概念之間的關係。這也很好理解,開放的世界太過複雜,用自頂向下的方法無法考慮周全,且隨著世界變化,對應的概念還在增長。
2. 領域知識圖譜多採用自頂向下的方法來構建本體。一方面,相對於開放域知識圖譜,領域知識圖譜涉及的概念和範圍都是固定或者可控的;另一方面,對於領域知識圖譜,我們要求其滿足較高的精度。現在大家接觸到的一些語音助手背後對接的知識圖譜大多都是領域知識圖譜,比如音樂知識圖譜、體育知識圖譜、烹飪知識圖譜等等。正因為是這些領域知識圖譜來滿足用戶的大多數需求,更需要保證其精度。
本實例是一個電影領域的知識圖譜,我們採用自頂向下的方法來構建本體結構。首先介紹下我們使用的工具protégé(點擊進入官網下載):
Protégé,又常常簡單地拼寫為「Protege」,是一個斯坦福大學開發的本體編輯和知識獲取軟體。開發語言採用Java,屬於開放源碼軟體。由於其優秀的設計和眾多的插件,Protégé已成為目前使用最廣泛的本體論編輯器之一(來自維基百科)。
打開protege,看到和下圖類似的界面。在Ontology IRI中填寫我們新建本體資源的IRI。讀者可以填寫自己的符合標準的IRI。
點擊「Entities」tab標籤,選擇「Classes」標籤。在這個界面,我們創建電影知識圖譜的類/概念。注意,所有的類都是「Thing」的子類。最左邊紅色小方框中的按鈕用於創建當前選中類的子類,中間的按鈕用於創建兄弟類(平行類),最右邊的按鈕刪除當前選中的類。我們創建了三個類,「人物」、「電影」、「類別」。右下方的界面是用於描述該類的一些特性,例如:"disjoint of"是用於表示該類與哪些類是互斥的。本例中,三個類都是互斥的。也就是說,一個實例只能是三個類中的一個。我們沒有在protege中顯式地定義互斥關係,讀者可以自己定義。
接下來我們切換到"Object Properties"頁面,我們在此界面創建類之間的關係,即,對象屬性。這裡我們創建了三個對象屬性,"hasActedIn"表示某人蔘演了某電影,因此我們在右下方的3號矩形框中定義該屬性的"domain"是人,4號框定義"range"是電影。這個很好理解,"domain"表示該屬性是屬於哪個類的,"range"表示該屬性的取值範圍。2號框表示該屬性的逆屬性是"hasActor",即,有了推理機,儘管我們的RDF數據只保存了A出演了B,我們在查詢的時候也能得到B的演員有A。1號方框中是一些描述該屬性的辭彙,我們在上一篇文章中已經介紹過,這裡不再贅述。同理,我們定義另外兩個屬性,這裡不再展示。
最後,我們切換到"Data properties",我們在該界面創建類的屬性,即,數據屬性。其定義方法和對象屬性類似,除了沒有這麼豐富的描述屬性特性的辭彙。其實不難理解,這些描述特性的辭彙是傳遞、對稱、反對稱、自反等,表明其必定有指向其他資源或自身的邊,而我們之前提到過,數據屬性相當於樹的葉子節點,只有入度,而沒有出度。
其實區分數據屬性和對象屬性還有一個很直觀的方法,我們觀察其"range",取值範圍即可。對象屬性的取值範圍是類,而數據屬性的取值範圍則是字面量,如下圖。
protege也支持以可視化的方式來展示本體結構。我們點擊"Window"選項,在"Tabs"中選擇"OntoGraf",然後"Entities"旁邊就多了一個標籤頁。在右側窗口中移動元素,可以很直觀地觀察本體之間的關係。
在這個小節,我們簡單地介紹了如何用protege自頂向下地構建知識圖譜的本體結構。對於Protege更詳細的操作和介紹,請參考這篇文檔。
總結
這篇文章介紹了接下來實踐中使用的數據,以及如何利用protege,根據我們的數據來進行本體建模。數據、代碼以及本體文件我都上傳到了github。之後實踐篇涉及到的所有文件我都會放在該項目中。下一篇實踐文章將介紹關係資料庫中的數據轉換為RDF的幾種方法,讓讀者學會如何把存在Mysql中的電影數據轉為RDF格式的數據。
推薦閱讀:
※Eric,基於多搜索引擎的自動問答機器人
※達觀數據智能問答技術研究
※《Easy Questions First? A Case Study on Curriculum Learning for Question Answering》讀書筆記