本篇文章接《電影知識圖譜問答(一)|爬取豆瓣電影與書籍詳細資訊》,學習如何利用爬取的資料,建構知識圖譜所需的三元組。主要内容包括如何從Json類型的資料,轉換成RDF資料,并最終存儲到Jena之中,然後利用SPARQL進行查詢。
實踐之前,請自主學習相關背景知識。
- 語義網絡, 語義網, 連結資料, 知識圖譜是什麼。
- RDF, RDFS, OWL, Protege, 本體建構。
- MySQL資料庫, pymysql。
- D2rq, Jena, fuseki, SPARQL。
1.資料清洗
- 電影資訊包括電影id、圖檔連結、名稱、導演名稱、編劇名稱、主演名稱、類型、制片國家、語言、上映日期、片長、季數、其他名稱、劇情簡介、評分、評分人數,共67245條資料資訊。雖說是電影資訊,但其中也包括電視劇、綜藝、動漫、紀錄片、短片。
- 電影演員資訊包括演員id、姓名、圖檔連結、性别、星座、出生日期、出生地、職業、更多中文名、更多外文名、家庭成員、簡介,共89592條資料資訊。這裡所指的演員包括電影演員、編劇、導演。
- 書籍資訊包括書籍id、圖檔連結、姓名、子标題、原作名稱、作者、譯者、出版社、出版年份、頁數、價格、内容簡介、目錄簡介、評分、評分人數,共64321條資料資訊。
- 書籍作者資訊包括作者id,姓名、圖檔連結、性别、出生日期、國家、更多中文名、更多外文名、簡介,共6231條資料資訊。這裡作者包括書籍作者和譯者。
上述為我們爬取的資料類别,但資料有很多噪音,比如中文電影名稱會外接英文電影名稱、某些類型資料嚴重缺失、資料格式不統一等等,這就需要我們根據具體資料進行具體分析。此處需要多搬搬磚,沒什麼技術,不多講。
2. Json2MySQL
首先我們将json類型的資料存儲到MySQL之中,這裡共建構了13個表,包含
- movie_genre: 包含movie_genre_id, movie_genre_name屬性,表示movie類别資訊。
- movie_info: 包含movie_info_id, movie_info_name, movie_info_image_url, movie_info_country, movie_info_language, movie_info_pubdate, movie_info_duration, movie_info_other_name, movie_info_summary, movie_info_rating, movie_info_review_count屬性,表示movie資訊。
- movie_person: 包含movie_person_id, movie_person_name, movie_person_image_url, movie_person_gender, movie_person_constellation, movie_person_birthday, movie_person_birthplace, movie_person_profession, movie_person_other_name, movie_person_introduction屬性,表示movie_person資訊。
- movie_to_gender: 包含movie_info_id, movie_genre_id屬性,設定兩個外鍵,分别關聯到movie_info表和movie_genre表,表示movie到genre的關聯。
- actor_to_movie: 包含movie_info_id, movie_actor_id屬性,設定兩個外鍵,分别關聯到movie_info表和movie_person表,表示movie到actor的關聯。
- writer_to_movie: 包含movie_info_id, movie_writer_id,設定兩個外鍵,分别關聯到movie_info表和movie_person表,表示movie到writer的關聯。
- director_to_movie: 包含movie_info_id, movie_director_id,設定兩個外鍵,分别關聯到movie_info表和movie_person表,表示movie到director的關聯。
- 同理,根據圖書資訊建構book_genre, book_info, book_person_info, book_to_genre, author_to_book, translator_to_book表。
表建構好之後,利用pymysql将Json類型資料導入到MySQL之中。
3. RDB2RDF
我們已經将Json類型的資料導入到關系型資料庫RDB之中,現在問題是怎麼将RDB Data轉換成RDF。轉換之前,我們先根據資料建構本體。
3.1 本體建構
什麼是本體?本體有點哲學的含義,在計算機領域,可以了解為一種模型,用于描述由一套對象類型(概念或者說類)屬性以及關系類型所構成的世界。此處我們使用Protege進行本體模組化。
首先下載下傳protege,下載下傳連結為https://protege.stanford.edu/。安裝完成之後,建立class,如果沒有的話,在window->Tabs->Classes尋找。根據MySQL之中建構的表,此處建構相應的類,如下所示。紅色箭頭表示的是建構子類,右邊圖示指的是建構兄弟類,最右邊指的是删除目前類。

類建構完成之後,進行建構對象屬性,共包含
- has_movie_genre: domains為movie_info, ranges為movie_genre,表示某電影有某類别。
- has_book_genre: domains為book_info, ranges為book_genre,表示某書籍有某類别。
- has_actor: domains為movie_info, ranges為movie_actor,表示某電影有某演員。和has_acted_in為互逆關系。
- has_acted_in: domains為movie_actor, ranges為movie_info,表示某演員出演了某電影。和has_actor為互逆關系。
- 同理has_writer, has_writed_in, has_director, has_directed_in, has_author, has_authored_in, has_translator, has_translator_in建構方法相同。
對象屬性建構完成之後,進行建構資料屬性。資料屬性建構比較簡單,指明資料類别和值類别即可。
建構完成之後,可以通過OntoGrap看到關系圖。可以去window->Tabs->OntoGrap尋找OntoGrap。
最後通過File->Save as儲存成Turtle Syntax形式,命名為douban_kgqa_ontology.owl。
3.2 D2RQ
RDB轉換成RDF有兩種方式,一是direct mapping,即直接映射。規則為
- 資料庫的表作為本體中的類(Class)。
- 表的列作為屬性(Property)。
- 表的行作為執行個體/資源。
- 表的單元格值為字面量。
- 如果單元格所在的列是外鍵,那麼其值為IRI,或者說實體/資源。
但實際中,我們很少使用這種方法,因為不能把RDB中資料映射到我們定義的本體上面。是以我們采用另外一種方法,R2RDF(RDB to RDF Mapping Language),連結為https://www.w3.org/TR/r2rml/。下面我們使用D2RQ工具将RDB資料轉換到RDF形式。
D2RQ提供了自己的mapping language,其形式和R2RML類似,具體文法連結為https://www.w3.org/TR/2004/REC-owl-features-20040210/。D2RQ有一個比較友善的地方,可以根據已定義的資料庫自動生成預定義的mapping檔案,使用者可以在mapping檔案上修改,把資料映射到自己的本體上。
首先下載下傳D2RQ檔案,連結為http://d2rq.org/,進入到目錄之中,利用下列指令生成douban_kgqa_mapping.ttl檔案。
mac, linux系統指令為
./generate-mapping -u root -p 123456 -o douban_kgqa_mapping.ttl jdbc:mysql:///douban_kgqa
windows系統指令為
generate-mapping.bat -u root -o douban_kgqa_mapping.ttl jdbc:mysql:///douban_kgqa
參數解讀:root是mysql使用者名,123456是root密碼,douban_kgqa_mapping.ttl是輸出檔案名稱,douban_kgqa是MySQL資料庫名稱。注:如果Mac使用者如果提示permission denied, 可以用chmod改變通路權限,chmod 777 generate-mapping。
現在根據我們的MySQL資料庫已經生成了預設的douban_kgqa_mapping.ttl檔案,然後根據douban_kgqa_ontology.owl中定義的本體修改douban_kgqa_mapping.ttl檔案。修改規則如下
- 将id和label屬性删除,因為我們不需要這兩個屬性。
- 修改類型值,将vocab:xxxx修改為我們owl檔案中定義的類。例如将d2rq:class vocab: movie_genre;修改為d2rq:class :movie_genre;
3.3 D2RQ RDF
利用下列指令将資料轉換成我們需要的RDF資料。
mac, linux指令為
./dump-rdf -o douban_kgqa.nt ./douban_kgqa_mapping.ttl
windows指令為
.\dump-rdf -o douban_kgqa.nt .\douban_kgqa_mapping.ttl
參數解讀:douban_kgqa_mapping.ttl是我們修改後的mapping檔案,其支援導出的RDF格式有TURTLE, RDF/XML, RDF/XML-ABBREV, N3, N-TRIPLE,N-TRIPLE是預設的輸出格式。
利用下列指令,我們能夠在http://localhost:2020/ 上進行SPARQL資料查詢,有興趣的讀者可以嘗試一下。
./d2r-server ./douban_kgqa_mapping.ttl
最後檢視一下我們生成的RDF資料,可以看到共298萬行,前10行的資料格式。其實我們爬蟲隻運作了兩天,資料還是太少,以後有空閑時間再更新更多資料。