Neo4j 從入門到構建一個簡單知識圖譜

Neo4j 對於大多數人來說,可能是比較陌生的。其實,Neo4j 是一個圖形數據庫,就像傳統的關係數據庫中的 Oracel 和 MySQL一樣,用來持久化數據。Neo4j 是最近幾年發展起來的新技術,屬於 NoSQL 數據庫中的一種。

本文主要從 Neo4j 爲什麼被用來做知識圖譜,Neo4j 的簡單安裝,在 Neo4j 瀏覽器中創建節點和關係,Neo4j 的 Python 接口操作以及用 Neo4j 構建一個簡單的農業知識圖譜五個方面來講。

Neo4j 爲什麼被用來做知識圖譜

從第19課《知識挖掘與知識圖譜概述》中,我們已經明白,知識圖譜是一種基於圖的數據結構,由節點和邊組成。其中節點即實體,由一個全局唯一的 ID 標示,關係(也稱屬性)用於連接兩個節點。通俗地講,知識圖譜就是把所有不同種類的信息連接在一起而得到一個關係網絡,提供了從“關係”的角度去分析問題的能力。

而 Neo4j 作爲一種經過特別優化的圖形數據庫,有以下優勢:

  • 數據存儲:不像傳統數據庫整條記錄來存儲數據,Neo4j 以圖的結構存儲,可以存儲圖的節點、屬性和邊。屬性、節點都是分開存儲的,屬性與節點的關係構成邊,這將大大有助於提高數據庫的性能。

  • 數據讀寫:在 Neo4j 中,存儲節點時使用了 Index-free Adjacency 技術,即每個節點都有指向其鄰居節點的指針,可以讓我們在時間複雜度爲 O(1) 的情況下找到鄰居節點。另外,按照官方的說法,在 Neo4j 中邊是最重要的,是 First-class Entities,所以單獨存儲,更有利於在圖遍歷時提高速度,也可以很方便地以任何方向進行遍歷。

  • 資源豐富:Neo4j 作爲較早的一批圖形數據庫之一,其文檔和各種技術博客較多。

  • 同類對比:Flockdb 安裝過程中依賴太多,安裝複雜;Orientdb,Arangodb 與 Neo4j 做對比,從易用性來說都差不多,但是從穩定性來說,neo4j 是最好的。

綜合上述以及因素,我認爲 Neo4j 是做知識圖譜比較簡單、靈活、易用的圖形數據庫。

Neo4j 的簡單安裝

Neo4j 是基於 Java 的圖形數據庫,運行 Neo4j 需要啓動 JVM 進程,因此必須安裝 Java SE 的 JDK。從 Oracle 官方網站下載 Java SE JDK,選擇版本 JDK8 以上版本即可。

下面簡單介紹下 Neo4j 在 Linux 和 Windows 的安裝過程。首先去官網下載對應版本。解壓之後,Neo4j 應用程序有如下主要的目錄結構:

  • bin 目錄:用於存儲 Neo4j 的可執行程序;
  • conf 目錄:用於控制 Neo4j 啓動的配置文件;
  • data 目錄:用於存儲核心數據庫文件;
  • plugins 目錄:用於存儲 Neo4j 的插件。

Linux 系統下的安裝

通過 tar 解壓命令解壓到一個目錄下:

tar -xzvf neo4j-community-3.3.1-unix.tar.gz

然後進入 Neo4j 解壓目錄:

cd /usr/local/neo4j/neo4j-community-3.1.0

通過啓動命令,可以實現啓動、控制檯、停止服務:

bin/neo4j  start/console/stop(啓動/控制檯/停止)

通過 cypher-shell 命令,可以進入命令行:

bin/cypher-shell

在 Neo4j 瀏覽器中創建節點和關係

下面,我們簡單編寫 Cypher 命令,Cypher 命令可以通過 Neo4j 教程學習,在瀏覽器中通過 Neo4j 創建兩個節點和兩個關係。

$ 命令行中,編寫 Cypher 腳本代碼,點擊 Play 按鈕完成創建,依次執行下面的語句:

CREATE (n:Person { name: 'Andres', title: 'Developer' }) return n;

作用是創建一個 Person,幷包含屬性名字和職稱。

enter image description here

下面這條語句也創建了一個 Person 對象,屬性中只是名字和職稱不一樣。

CREATE (n:Person { name: 'Vic', title: 'Developer' }) return n;

緊接着,通過下面兩行命令進行兩個 Person 的關係匹配:

match(n:Person{name:"Vic"}),(m:Person{name:"Andres"}) create (n)-[r:Friend]->(m) return r;

match(n:Person{name:"Vic"}),(m:Person{name:"Andres"}) create (n)<-[r:Friend]-(m) return r;

最後,在創建完兩個節點和關係之後,查看數據庫中的圖形:

match(n) return n;

如下圖,返回兩個 Person 節點,以及其關係網,兩個 Person 之間組成 Friend 關係:

enter image description here

Neo4j 的 Python 操作

既然 Neo4j 作爲一個圖庫數據庫,那我們在項目中使用的時候,必然不能通過上面那種方式完成任務,一般都要通過代碼來完成數據的持久化操作。其中,對於 Java 編程者來說,可通過 Spring Data Neo4j 達到這一目的。

而對於 Python 開發者來說,Py2neo 庫也可以完成對 Neo4j 的操作,操作過程如下。

首先 安裝 Py2neo。Py2neo 的安裝過程非常簡單,在命令行通過下面命令即可安裝成功。

pip install py2neo

安裝好之後,我們來看一下簡單的圖關係構建,看下面代碼:

from py2neo.data import Node, Relationship
a = Node("Person", name="Alice")
b = Node("Person", name="Bob")
ab = Relationship(a, "KNOWS", b)

第一行代碼,首先引入 Node 和 Relationship 對象,緊接着,創建 a 和 b 節點對象,最後一行匹配 a 和 b 之間的工作僱傭關係。接着來看看 ab 對象的內容是什麼:

print(ab)

通過 print 打印出 ab 的內容:

(Alice)-[:KNOWS {}]->(Bob)

通過這樣,就完成了 Alice 和 Bob 之間的工作關係,如果有多組關係將構建成 Person 之間的一個關係網。

瞭解更多 Py2neo 的使用方法,建議查看官方文檔。

用 Neo4j 構建一個簡單的農業知識圖譜

我們來看一個基於開源語料的簡單農業知識圖譜,由於過程比較繁雜,數據和知識圖譜數據預處理過程這裏不再贅述,下面,我們重點看基於 Neo4j 來創建知識圖譜的過程。

整個過程主要包含以下步驟:

環境準備
語料準備
語料加載
知識圖譜查詢展示
Neo4j 環境準備。

根據上面對 Neo4j 環境的介紹,這裏默認你已經搭建好 Neo4j 的環境,並能正常訪問,如果沒有環境,請自行搭建好 Neo4j 的可用環境。

本次提供的語料是已經處理好的數據,包含6個 csv 文件,文件內容和描述如下。

attributes.csv:文件大小 2M,內容是通過互動百科頁面得到的部分實體的屬性,包含字段:Entity、AttributeName、Attribute,分別表示實體、屬性名稱、屬性值。文件前5行結構如下:

Entity,AttributeName,Attribute
密度板,別名,纖維板
葡萄蔓枯病,主要爲害部位,枝蔓
坎德拉,性別,男
坎德拉,國籍,法國
坎德拉,場上位置,後衛

hudong_pedia.csv:文件大小 94.6M,內容是已經爬好的農業實體的百科頁面的結構化數據,包含字段:title、url、image、openTypeList、detail、baseInfoKeyList、baseInfoValueList,分別表示名稱、百科 URL 地址、圖片、分類類型、詳情、關鍵字、依據來源。文件前2行結構如下:

"title","url","image","openTypeList","detail","baseInfoKeyList","baseInfoValueList"
"菊糖","http://www.baike.com/wiki/菊糖","http://a0.att.hudong.com/72/85/20200000013920144736851207227_s.jpg","健康科學##分子生物學##化學品##有機物##科學##自然科學##藥品##藥學名詞##藥物中文名稱列表","[藥理作用] 診斷試劑 人體內不含菊糖,靜注後,不被機體分解、結合、利用和破壞,經腎小球濾過,通過測定血中和尿中的菊糖含量,可以準確計算腎小球的濾過率。菊糖廣泛存在於植物組織中,約有3.6萬種植物中含有菊糖,尤其是菊芋、菊苣塊根中含有豐富的菊糖[6,8]。菊芋(Jerusalem artichoke)又名洋姜,多年生草本植物,在我國栽種廣泛,其適應性廣、耐貧瘠、產量高、易種植,一般畝產菊芋塊莖爲2 000~4 000 kg,菊芋塊莖除水分外,還含有15%~20%的菊糖,是加工生產菊糖及其製品的良好原料。","中文名:","菊糖"
"密度板","http://www.baike.com/wiki/密度板","http://a0.att.hudong.com/64/31/20200000013920144728317993941_s.jpg","居家##巧克力包裝##應用科學##建築材料##珠寶盒##禮品盒##科學##糖果盒##紅酒盒##裝修##裝飾材料##隔斷##首飾盒","密度板(英文:Medium Density Fiberboard (MDF))也稱纖維板,是以木質纖維或其他植物纖維爲原料,施加脲醛樹脂或其他適用的膠粘劑製成的人造板材。按其密度的不同,分爲高密度板、中密度板、低密度板。密度板由於質軟耐衝擊,也容易再加工,在國外是製作傢俬的一種良好材料,但由於國家關於高密度板的標準比國際標準低數倍,所以,密度板在中國的使用質量還有待提高。","中文名:##全稱:##別名:##主要材料:##分類:##優點:","密度板##中密度板纖維板##纖維板##以木質纖維或其他植物纖維##高密度板、中密度板、低密度板##表面光滑平整、材質細密性能穩定"

hudong_pedia2.csv:文件大小 41M,內容結構和 hudong_pedia.csv 文件保持一致,只是增加數據量,作爲 hudong_pedia.csv 數據的補充。

new_node.csv:文件大小 2.28M,內容是節點名稱和標籤,包含字段:title、lable,分別表示節點名稱、標籤,文件前5行結構如下:

title,lable
藥物治療,newNode
膳食纖維,newNode
Boven Merwede,newNode
亞美尼亞蘇維埃百科全書,newNode

wikidata_relation.csv:文件大小 1.83M,內容是實體和關係,包含字段 HudongItem1、relation、HudongItem2,分別表示實體1、關係、實體2,文件前5行結構如下:

HudongItem1,relation,HudongItem2
菊糖,instance of,化合物
菊糖,instance of,多糖
瓦爾,instance of,河流
菊糖,subclass of,食物
瓦爾,origin of the watercourse,萊茵河

wikidata_relation2.csv:大小 7.18M,內容結構和 wikidata_relation.csv 一致,作爲 wikidata_relation.csv 數據的補充。
語料加載。

語料加載,利用 Neo4j 的 LOAD CSV WITH HEADERS FROM... 功能進行加載,具體操作過程如下。

首先,依次執行以下命令:

// 將hudong_pedia.csv 導入
LOAD CSV WITH HEADERS  FROM "file:///hudong_pedia.csv" AS line  
CREATE (p:HudongItem{title:line.title,image:line.image,detail:line.detail,url:line.url,openTypeList:line.openTypeList,baseInfoKeyList:line.baseInfoKeyList,baseInfoValueList:line.baseInfoValueList})

執行成功之後,控制檯顯示成功:

enter image description here

上面這張圖,表示數據加載成功,並顯示加載的數據條數和耗費的時間。

// 新增了hudong_pedia2.csv
LOAD CSV WITH HEADERS  FROM "file:///hudong_pedia2.csv" AS line  
CREATE (p:HudongItem{title:line.title,image:line.image,detail:line.detail,url:line.url,openTypeList:line.openTypeList,baseInfoKeyList:line.baseInfoKeyList,baseInfoValueList:line.baseInfoValueList})

// 創建索引
CREATE CONSTRAINT ON (c:HudongItem)
ASSERT c.title IS UNIQUE

以上命令的意思是,將 hudong_pedia.csv 和 hudong_pedia2.csv 導入 Neo4j 作爲結點,然後對 titile 屬性添加 UNIQUE(唯一約束/索引)。

注意: 如果導入的時候出現 Neo4j JVM 內存溢出錯誤,可以在導入前,先把 Neo4j 下的 conf/neo4j.conf 中的 dbms.memory.heap.initial_size 和 dbms.memory.heap.max_size 調大點。導入完成後再把值改回去即可。

下面繼續執行數據導入命令:

// 導入新的節點
LOAD CSV WITH HEADERS FROM "file:///new_node.csv" AS line
CREATE (:NewNode { title: line.title })

//添加索引
CREATE CONSTRAINT ON (c:NewNode)
ASSERT c.title IS UNIQUE

//導入hudongItem和新加入節點之間的關係
LOAD CSV  WITH HEADERS FROM "file:///wikidata_relation2.csv" AS line
MATCH (entity1:HudongItem{title:line.HudongItem}) , (entity2:NewNode{title:line.NewNode})
CREATE (entity1)-[:RELATION { type: line.relation }]->(entity2)

LOAD CSV  WITH HEADERS FROM "file:///wikidata_relation.csv" AS line
MATCH (entity1:HudongItem{title:line.HudongItem1}) , (entity2:HudongItem{title:line.HudongItem2})
CREATE (entity1)-[:RELATION { type: line.relation }]->(entity2)

執行完這些命令後,我們導入 new_node.csv 新節點,並對 titile 屬性添加 UNIQUE(唯一約束/索引),導入 wikidata_relation.csv 和 wikidata_relation2.csv,並給節點之間創建關係。

緊接着,繼續導入實體屬性,並創建實體之間的關係:

LOAD CSV WITH HEADERS FROM "file:///attributes.csv" AS line
MATCH (entity1:HudongItem{title:line.Entity}), (entity2:HudongItem{title:line.Attribute})
CREATE (entity1)-[:RELATION { type: line.AttributeName }]->(entity2);

LOAD CSV WITH HEADERS FROM "file:///attributes.csv" AS line
MATCH (entity1:HudongItem{title:line.Entity}), (entity2:NewNode{title:line.Attribute})
CREATE (entity1)-[:RELATION { type: line.AttributeName }]->(entity2);

LOAD CSV WITH HEADERS FROM "file:///attributes.csv" AS line
MATCH (entity1:NewNode{title:line.Entity}), (entity2:NewNode{title:line.Attribute})
CREATE (entity1)-[:RELATION { type: line.AttributeName }]->(entity2);

LOAD CSV WITH HEADERS FROM "file:///attributes.csv" AS line
MATCH (entity1:NewNode{title:line.Entity}), (entity2:HudongItem{title:line.Attribute})
CREATE (entity1)-[:RELATION { type: line.AttributeName }]->(entity2)  

這裏注意,建索引的時候帶了 label,因此只有使用 label 時纔會使用索引,這裏我們的實體有兩個 label,所以一共做 2*2=4 次。當然也可以建立全局索引,即對於不同的 label 使用同一個索引。

以上過程,我們就完成了語料加載,並創建了實體之間的關係和屬性匹配,下面我們來看看 Neo4j 圖譜關係展示。

知識圖譜查詢展示

最後通過 cypher 語句查詢來看看農業圖譜展示。

首先,展示 HudongItem 實體,執行如下命令:

MATCH (n:HudongItem) RETURN n LIMIT 25

對 HudongItem 實體進行查詢,返回結果的25條數據,結果如下圖:

enter image description here

接着,展示 NewNode 實體,執行如下命令:

MATCH (n:NewNode) RETURN n LIMIT 25

對 NewNode 實體進行查詢,返回結果的25條數據,結果如下圖:

enter image description here

之後,展示 RELATION 直接的關係,執行如下命令:

MATCH p=()-[r:RELATION]->() RETURN p LIMIT 25

展示實體屬性關係,結果如下圖:

enter image description here

總結

本節內容到此結束,回顧下整篇文章,主要講了以下內容:

  1. 解釋了 Neo4j 被用來做知識圖譜的原因;
  2. Neo4j 的簡單安裝以及在 Neo4j 瀏覽器中創建節點和關係;
  3. Neo4j 的 Python 接口操作及使用;
  4. 從五個方面講解了如何使用 Neo4j 構建一個簡單的農業知識圖譜。

最後,強調一句,知識圖譜未來會通過自然語言處理技術和搜索技術結合應用會越來越廣,工業界所出的地位也會越來越重要。

 

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