我們現在處於“大數據時代”,而在浩繁的“大數據”中,絕大多數是文本形式的非結構化數據。圖其實可以非常靈活和有效地表示和處理文本內容中的詞語、概念、依存關係,並用作知識推理、情感分析、智能問答等豐富的應用中。
本文以百度雲的自然語言處理API服務爲例,介紹怎樣將文本分析的結果保存到Neo4j圖數據庫中。
1、準備
Neo4j圖數據庫3.5.*。
APOC擴展包。關於如何安裝APOC,請參見這裏。我們要用到APOC中訪問RESTful API的過程。關於APOC的介紹,請參見這篇文章。
一個百度雲賬號,並可以訪問百度智能雲。
2、創建百度雲NLP應用
在百度雲控制檯中選擇並創建一個“自然語言應用”:
對於有限的NLP API調用是免費的。把上面頁面中的AppID和 API Key的內容保存下來,我們後面要用到。
3、從Neo4j中訪問百度NLP API
3.1 概述
Neo4j的APOC擴展包提供豐富的過程和函數。要調用任何API,可以使用下面的過程:
- apoc.load.json:最簡單的URL訪問,請求不帶參數。URL可以是遠程的,也可以是文件。
- apoc.load.jsonParams:帶參數/payload的API調用過程,還可以指定JSON Path對結果進行過濾。這是我們下面要用的過程。
- apoc.load.jsonArray:與apoc.load.json類似,內容中可以包含JSON Array。
- apoc.import.json:導入由apoc.export.json導出的JSON數據文件。
關於相關過程的詳細文檔,請參見Neo4j文檔。
3.2 獲取Access Token
首先需要向授權服務地址https://aip.baidubce.com/oauth/2.0/token
發送請求(推薦使用POST),並在URL中帶上以下參數:
- grant_type: 必須參數,固定爲
client_credentials
; - client_id: 必須參數,應用的
API Key
;(參見第2部分) - client_secret: 必須參數,應用的
Secret Key
(參見第2部分)。
例如:
在返回的JSON數據中可以看到access_token,例如:
"access_token":"24.1170ea9dfdfe1edbce3830b78e92b4a0.2592000.1592653389.282335-19996420",
3.3 對句子進行詞法分析
詞法分析對文本內容進行分詞、詞性標註和專名識別;該操作識別出文本串中的基本詞彙(分詞),對這些詞彙進行重組、標註組合後詞彙的詞性,並進一步識別出命名實體。
可以先測試一下,看看返回的分詞結果是怎樣的(注意:請使用你自己的access_token替換下面的access_toekn參數值):
{
"log_id": 4752890392005512214,
"items": [
{
"formal": "",
"loc_details": [],
"item": "Neo4j",
"pos": "nz",
"ne": "",
"basic_words": [
"Neo4j"
],
"byte_length": 5,
"byte_offset": 0,
"uri": ""
},
{
"formal": "",
"loc_details": [],
"item": "是",
"pos": "v",
"ne": "",
"basic_words": [
"是"
],
"byte_length": 3,
"byte_offset": 5,
"uri": ""
},
... ...
}
結果中,每個詞語及其屬性包含在items列表中返回。在Cypher中可以使用諸如value.items[0].item的形式訪問詞語的內容。
下面是調用百度詞法分析API對兩個句子進行分析的完整Cypher查詢:
// ***************** 開始 ************************
// 初始化文本內容數組
WITH ["Neo4j是全球領先的圖數據庫軟件", "Neo4j於2007年在瑞典創建"] AS sentences
UNWIND sentences AS sentence
// 使用百度雲NLP對句子進行分詞,然後創建句子和詞的關係圖譜
CALL apoc.load.jsonParams(
'https://aip.baidubce.com/rpc/2.0/nlp/v1/lexer?charset=UTF-8&access_token=24.1170ea9dfdfe1edbce3830b78e92b4a0.2592000.1592653389.282335-19996420', {},
'{"text": "'+sentence + '"}', null, {}) YIELD value
WITH value
CREATE (s:Sentence{text:value.text})
WITH value, s, value.items AS items
UNWIND items AS item
// 過濾掉助詞如'的'
WITH s, item WHERE item.pos <> 'u'
MERGE (a:Word{word:item.item})
SET a.pos = item.pos, a.byte_offset = item.byte_offset, a.ne = item.ne, a.formal = item.formal, a.uri = item.uri
CREATE (s) <-[:IN_SENTENCE]- (a)
RETURN a
// ***************** 結束 ************************
對於創建的Word節點,我們根據它們在句子中的位置(byte_offset屬性),創建先後關係:
// 創建同一個句子的詞語之間的先後關係
MATCH (s:Sentence) <-[:IN_SENTENCE]- (w:Word)
WITH w ORDER BY w.byte_offset ASC
WITH collect (w) AS words
// 創建一個數組it, 其元素類型是整數序列,元素個數是所有詞的個數-1。該數組用作循環次數控制。
WITH words, range(0,size(words) - 2) AS it
UNWIND it AS i
WITH words[i] AS w1, words[i+1] AS w2
MERGE (w1) <-[:AFTER]- (w2)
RETURN w1, w2
這裏,UNWIND語句的作用逐一取出it數組中的元素,以循環執行後面的語句,其作用類似於FOR EACH i IN it DO ...。執行完成後,我們可以得到下面的包含句子(Sentence)和詞語(Word)的圖:
3.4 對句子進行句法分析
依存句法分析接口可自動分析文本中的依存句法結構信息,利用句子中詞與詞之間的依存關係來表示詞語的句法結構信息(如“主謂”、“動賓”、“定中”等結構關係),並用樹狀結構來表示整句的結構(如“主謂賓”、“定狀補”等)。有了依存結構信息,我們可以掌握詞語在句子中的作用,以及關於句子含義更豐富的描述。
因爲我們的句子已經保存在Sentence節點中,這裏我們直接讀取、並運行句法分析。
// ***************** 開始 ************************
// 使用百度雲NLP對句子中的詞進行依存關係分析,然後創建句子和詞的關係圖譜
MATCH (s:Sentence)
WITH s
CALL apoc.load.jsonParams('https://aip.baidubce.com/rpc/2.0/nlp/v1/depparser?charset=UTF-8&access_token=24.1170ea9dfdfe1edbce3830b78e92b4a0.2592000.1592653389.282335-19996420', {},
'{"text": "'+ s.text +'","mode":1}', null, {}) YIELD value
WITH s, value, value.items AS items
UNWIND items AS item
// 更新詞的屬性。
// 這裏過濾掉助詞如'的'。注意這裏返回結果中代表詞性的屬性名是postag。
WITH s, item WHERE item.postag <> 'u'
MATCH (a:Word{word:item.word})
SET a.id = item.id, a.head = item.head, a.deprel = item.deprel
WITH s
// 根據分析結果創建詞之間的依存關係,該關係包含一個屬性代表依存關係類型
MATCH (s) <-[:IN_SENTENCE]- (w)
WITH s,w WHERE w.head <> 0
MATCH (s) <-[:IN_SENTENCE]- (w1)
WHERE w.head = w1.id
MERGE (w) -[:DEPENDS_ON{type:w.deprel}]-> (w1)
RETURN w
// ***************** 結束 ************************
再看看文本分析的結果圖:
圖中關係舉例如下:
(Neo4j) -[:DEPENDS_ON{type:'SBV'}]-> ('是') <-[:DEPENDS_ON{type:'VOB'}]- ('軟件')
SBV表示“主謂關係”,VOB表示“動賓關係”。當我們擁有這樣的關係結構,就可以回答簡單的問題例如“Neo4j是什麼”?“Neo4j什麼時候創建的?”。關於所有34種詞語依賴關係的說明,請參見百度自然語言處理文檔。
4、總結
百度的自然語言API提供豐富的處理功能,除了詞法分析和句法分析,還包括詞的向量表示、短語相似度分析、文本的情感分析等。通過與 Neo4j的有機結合,可以創建語義豐富的知識圖譜,實現內容推理、文本分類、聊天機器人等新穎的應用。
注:由於web文本編輯器的限制,上面的Cyher代碼中可能有不可見字符從而造成執行錯誤。請訪問Github下載正確的代碼。
https://github.com/Joshua-Yu/baidu-neo4j-nlp