知識圖譜的建立讓我們得以探索資料間的深層關聯。透過鄰居節點搜尋,我們可以找出與特定術語相關的摘要和術語,並利用 igraph 的多層次社群偵測演算法,將圖譜劃分為不同的社群,每個社群代表一個特定的研究領域。此方法有助於理解圖譜結構、識別研究主題,並評估知識圖譜構建的引數設定。然而,當資料量龐大時,記憶體中的圖表分析就顯得力不從心,這時就需要圖資料函式庫的支援。Neo4j 作為一個高效能圖資料函式庫,提供永續性儲存、高效查詢和可擴充套件性,並支援易於上手的 Cypher 查詢語言。透過 Python 的 Neo4j 驅動程式,我們可以輕鬆地與 Neo4j 互動,進行圖資料的建立、查詢和分析,例如最佳化旅行路線。此外,Neo4j 的節點標籤和關係屬性,也讓異質圖的處理更加便捷。
知識圖譜分析與社群偵測
在前面的章節中,我們成功建立了一個生物醫學知識圖譜,並利用它來找出與特定術語相關的摘要。現在,我們將更深入地探討如何利用這個圖譜進行社群偵測,以識別出相關的研究領域。
識別與特定術語相關的術語
首先,我們需要使用 neighbors() 方法來找出包含特定術語(如「yoga」)的摘要節點的鄰居節點,也就是與這些摘要相關的術語節點。我們可以透過列表推導式來實作這一點:
related_term_nodes = [g.neighbors(node) for node in yoga_abstract_nodes]
內容解密:
g.neighbors(node)用於找出圖譜中某個節點的所有鄰居節點。yoga_abstract_nodes是一個包含所有與「yoga」相關的摘要節點 ID 的列表。- 列表推導式對
yoga_abstract_nodes中的每個節點執行g.neighbors(node),並將結果彙總成一個列表。
這個操作會傳回一個列表的列表,每個內部列表包含了一個摘要節點的所有鄰居節點(即相關的術語節點)。接下來,我們需要將這個列表的列表扁平化,以獲得所有唯一術語節點的列表。
import itertools
related_term_nodes = itertools.chain.from_iterable(related_term_nodes)
內容解密:
itertools.chain.from_iterable()用於將多個迭代器(在這裡是列表)合併成一個單一的迭代器。- 透過這個函式,我們將
related_term_nodes這個列表的列表轉換成一個扁平化的迭代器。
然後,我們使用 g.vs 來取得這些術語節點的文字屬性,並利用 set() 去除重複項:
related_terms = set(g.vs(related_term_nodes)['text'])
print(related_terms)
print(len(related_terms))
內容解密:
g.vs(related_term_nodes)用於根據節點 ID 列表取得對應的節點物件。['text']用於提取這些節點的text屬性,即術語本身。set()用於去除重複的術語。
執行上述程式碼後,我們可以得到與「yoga」相關的所有生物醫學術語,以及這些術語的數量。在這個例子中,我們找到了 168 個與「yoga」相關的唯一術語,包括「mental health」、「visceral fat」和「chronic stroke」等。
社群偵測
社群偵測是一種用於識別圖譜中高度相互連線的節點群組(即社群)的方法。我們可以使用 igraph 中的多層次社群偵測演算法(Louvain 方法)來實作這一點:
# 省略具體實作程式碼,假設使用 igraph 的 community_multilevel() 方法
communities = g.community_multilevel()
內容解密:
- 多層次社群偵測演算法透過逐漸將每個節點分配給鄰近社群,並計算社群的模組度(modularity),來找出最佳的社群劃分。
- 模組度用於衡量社群內部的連線密度與社群之間的連線密度之間的差異。
透過社群偵測,我們可以將圖譜劃分為不同的社群,每個社群代表了一個特定的研究領域或概念。這種方法可以幫助我們更好地理解圖譜中的結構資訊,並識別出潛在的研究主題或領域。
總之,知識圖譜分析與社群偵測為我們提供了一種強大的工具,用於探索和分析複雜的資料集,並從中提取出有價值的資訊和見解。透過結合圖譜構建、術語提取和社群偵測等技術,我們可以更深入地理解資料背後的結構和關係,並發現新的研究機會和方向。
知識圖譜分析與社群偵測
圖表展示不同社群的概念
下圖展示了不同社群中的術語和摘要,這些社群代表著與特定主題相關的研究領域。例如,這些可能是關於某些醫療狀況的醫學摘要,如心血管和腫瘤學狀況。
多層級社群偵測演算法的執行步驟
我們將介紹如何在知識圖譜上執行多層級社群偵測演算法,以找出相關摘要和術語的聚集區域。
- 轉換為無向圖
首先,我們需要將有向圖轉換為無向圖,因為igraph中的多層級社群偵測演算法不支援有向邊。使用
as_undirected()方法可以輕鬆完成此轉換。
g_u = g.as_undirected()
2. **執行社群偵測**
使用igraph的`community_multilevel()`方法執行多層級社群偵測演算法。
```python
community_membership = g_u.community_multilevel()
print(len(community_membership))
community_membership變數包含了一個igraph特定的VertexClustering物件列表,每個物件包含一個社群標籤和屬於該社群的節點。
- 檢視社群大小
透過列舉
community_membership中的VertexClustering元素,可以列印出每個社群的ID和大小。
for i, community in enumerate(community_membership): size = len(community) print(f’社群:{i},大小:{size}')
4. **檢視單一社群的成員**
將`VertexClustering`元素轉換為僅包含節點成員的列表,並找出最小社群中的節點。
```python
smallest_community = sorted(list(community_membership), key=len)[0]
print(smallest_community)
進一步篩選出最小社群中的術語節點及其文字屬性。
community_nodes = g.vs[smallest_community].select(type_eq='term')
community_terms = community_nodes['text']
print(community_terms)
內容解密:
g_u = g.as_undirected():將有向圖g轉換為無向圖g_u,因為多層級社群偵測演算法不支援有向邊。community_membership = g_u.community_multilevel():執行多層級社群偵測演算法,找出圖中的社群結構。for i, community in enumerate(community_membership):遍歷每個社群,並列印其ID和大小。smallest_community = sorted(list(community_membership), key=len)[0]:找出節點數量最少的社群。community_nodes = g.vs[smallest_community].select(type_eq='term'):在最小社群中篩選出型別為“term”的節點。community_terms = community_nodes['text']:取得這些術語節點的文字屬性。
社群偵測的應用與意義
透過社群偵測,可以幫助我們瞭解不同研究領域或檔案之間的關聯性,找出潛在的聯絡和模式。這對於回答業務問題或研究問題非常有幫助。此外,社群偵測也可以用於評估知識圖譜構建過程中的引數設定是否合理。
使用圖資料函式庫
在前面的章節中,我們一直在Python指令碼中建立記憶體中的圖表。這種做法適用於分析工作或建立概念驗證應用程式,但對於需要擴充套件的工作流程或長期儲存,Python和igraph就顯得力不從心。
在涉及圖表的生產系統中,圖資料函式庫充當永續性資料儲存解決方案。除了儲存大量資料外,圖資料函式庫通常還設計為高效平行執行大量讀寫操作。它們很可能是依賴大量圖表資料處理的任何生產管道的一部分,例如大型線上零售商的推薦系統。
除了儲存資料外,圖資料函式庫還允許對其儲存的資料執行基本查詢。許多這些資料函式庫可以使用至少一種常見的圖查詢語言進行查詢。
圖資料函式庫的技術需求
本章節將使用Jupyter Notebook來執行我們的程式設計練習,這需要python>=3.8.0,以及以下需要使用pip install命令安裝到環境中的套件:
- igraph==0.9.8
- geopy==2.3.0
- neo4j==5.5.0
安裝步驟
- 安裝Neo4j Desktop:這是免費的。我們主要將Neo4j用於其長期圖表資料函式庫儲存,不過Neo4j Desktop還會安裝一個桌面圖表瀏覽器。要安裝Neo4j Desktop,請前往https://neo4j.com/download-center/#desktop,並填寫一些詳細資訊。請記下啟動金鑰,因為在安裝過程中需要用到它,並選擇與您的機器相應的作業系統安裝程式。
- 建立新資料函式庫:安裝Neo4j後,開啟Neo4j Desktop並建立一個新的資料函式庫(這可以透過導航到應用程式中的資料函式庫標籤並使用“新增”下拉式選單來建立新的本地DBMS),並為其命名,例如“Python DB”。在本章中,請使用您願意在開放程式碼中寫下的密碼作為此資料函式庫的密碼——我們將使用“testpython”。在實際的Neo4j設定中,您可能希望透過加密來遮罩此密碼,但這超出了本章的範圍。
為什麼使用圖資料函式庫?
在生產系統中,圖資料函式庫是儲存大量資料並高效執行大量讀寫操作的理想解決方案。它們非常適合需要處理大量圖表資料的應用程式,例如推薦系統或社交網路分析。
圖資料函式庫的主要功能
- 永續性資料儲存:圖資料函式庫提供了一個永續性資料儲存解決方案,可以儲存大量資料。
- 高效查詢:圖資料函式庫允許對其儲存的資料執行基本查詢,並支援多種常見的圖查詢語言。
- 可擴充套件性:圖資料函式庫設計為可以擴充套件以滿足大型應用程式的需求。
Neo4j簡介
Neo4j是一種流行的圖資料函式庫,它提供了高效的資料儲存和查詢功能。本章將重點介紹如何使用Neo4j來儲存和查詢圖表資料。
Neo4j的主要特點
- 高效的資料儲存:Neo4j提供了一個高效的資料儲存解決方案,可以儲存大量資料。
- Cypher查詢語言:Neo4j支援Cypher查詢語言,這是一種強大的查詢語言,可以用來查詢圖表資料。
- 易於使用:Neo4j提供了一個易於使用的介面,可以輕鬆地建立和查詢圖表資料。
使用Python與Neo4j互動
本章將介紹如何使用Python與Neo4j互動,包括如何建立和查詢圖表資料。
使用Python與Neo4j互動的步驟
- 安裝Neo4j套件:使用pip install命令安裝neo4j套件。
- 連線到Neo4j:使用neo4j套件連線到Neo4j資料函式庫。
- 建立圖表資料:使用neo4j套件建立圖表資料。
- 查詢圖表資料:使用Cypher查詢語言查詢圖表資料。
使用Python和Cypher最佳化旅行路線
在本章中,我們將學習如何使用Python和Cypher來最佳化旅行路線。這將涉及使用Neo4j來儲存和查詢圖表資料,以及使用Python來處理和視覺化結果。
步驟1:建立城市和路線的圖表資料
首先,我們需要建立一個包含城市和路線的圖表資料。這可以透過使用Cypher查詢語言在Neo4j中建立節點和關係來實作。
// 建立城市節點
CREATE (city1:City {name: '台北'})
CREATE (city2:City {name: '新竹'})
CREATE (city3:City {name: '台中'})
// 建立路線關係
CREATE (city1)-[:ROUTE {distance: 70}]->(city2)
CREATE (city2)-[:ROUTE {distance: 100}]->(city3)
CREATE (city1)-[:ROUTE {distance: 150}]->(city3)
內容解密:
這段Cypher程式碼建立了三個城市節點(台北、新竹、台中)和它們之間的路線關係。每個路線關係都有一個距離屬性,用於表示城市之間的距離。
步驟2:使用Python查詢圖表資料
接下來,我們可以使用Python來查詢圖表資料並計算最優路線。
from neo4j import GraphDatabase
# 連線到Neo4j
driver = GraphDatabase.driver("bolt://localhost:7687", auth=("neo4j", "testpython"))
# 查詢最優路線
def find_shortest_path(driver, start_city, end_city):
with driver.session() as session:
result = session.run("""
MATCH p=shortestPath((start:City {name: $start_city})-[*]-(end:City {name: $end_city}))
RETURN p
""", start_city=start_city, end_city=end_city)
return result.single()["p"]
# 計算最優路線
shortest_path = find_shortest_path(driver, "台北", "台中")
# 列印最優路線
for node in shortest_path.nodes:
print(node["name"])
內容解密:
這段Python程式碼使用Neo4j的Python驅動程式連線到Neo4j資料函式庫,並使用Cypher查詢語言計算兩個城市之間的最優路線。find_shortest_path函式接受起始城市和終點城市作為引數,並傳回最優路線。最後,我們列印出最優路線中的城市名稱。
與圖資料函式庫的互動:以Neo4j為例
在處理複雜的網路資料時,圖資料函式庫提供了一個強大的解決方案。本章節將介紹如何使用Python與圖資料函式庫Neo4j進行互動,並展示如何利用igraph進行複雜的分析。
Neo4j:一個高效能的圖資料函式庫
Neo4j是一個廣泛使用的高效能圖資料函式庫,它提供了免費的本地版本。Neo4j可以使用Cypher查詢語言進行查詢,Cypher是圖查詢語言中最容易上手的一種,非常適合初學者。要深入瞭解Cypher的使用,請參考官方檔案:https://neo4j.com/developer/cypher/。
Neo4j的基本概念
在Neo4j中,節點(nodes)仍然被稱為節點,而邊(edges)則被稱為關係(relationships)。節點和邊的屬性(attributes)被稱為屬性(properties)。在異質圖中,不同型別的節點具有不同的標籤(labels),這些標籤在Cypher查詢語言中被大量使用,以便存取特定的節點和模式。
設定Neo4j
要開始使用Neo4j,需要執行以下步驟:
- 按照本章技術需求部分提供的說明安裝Neo4j。
- 啟動新建立的資料函式庫,並刪除範例資料函式庫,因為Neo4j的桌面版只支援同時執行一個資料函式庫。
- 開啟Neo4j Browser視窗,並建立一個新使用者,用於從Python存取資料函式庫。
在Neo4j Browser中建立新使用者
- 在Neo4j Browser視窗頂部的命令列中輸入
:server user add。 - 在出現的視窗中填寫新使用者的資訊,包括使用者名稱、密碼和角色。使用者名稱設為
admin,密碼設為testpython,並選擇admin和PUBLIC角色。 - 點選
Add User建立新使用者。
Cypher查詢語言
Cypher是一種開源的查詢語言,相容多種圖資料函式庫,包括Neo4j。它與SQL等常見查詢語言有相似之處,但專為圖資料設計。Cypher的設計圍繞著匹配節點和邊的模式,使用特殊的語法,看起來像是繪製網路路徑。
基本的Cypher查詢
要參照一個節點,使用括號將其括起來。要表示一條特定的邊,使用方括號。節點和邊透過短劃線和箭頭連線,如下所示:
(node)-[edge]->(node)
這種模式將匹配圖中以有向方式連線的節點。
建立節點
- 使用
CREATE函式建立新的節點。例如,建立一個名為Jeremy的Person型別的節點:CREATE (:Person {name: "Jeremy"}) - 建立另一個名為Mark的Person節點:
CREATE (:Person {name: "Mark"})
連線節點
- 使用
MATCH函式查詢現有的節點,並使用CREATE函式在它們之間建立一條邊。例如,讓Jeremy關注Mark:MATCH (jeremy:Person {name: "Jeremy"}) MATCH (mark:Person {name: "Mark"}) CREATE (jeremy)-[:FOLLOWS]->(mark)
MERGE函式
MERGE函式結合了MATCH和CREATE的功能,用於處理重複資訊或更新資料函式庫。如果指定的模式已經存在於圖資料函式庫中,則不進行寫入操作;否則,使用CREATE函式新增新的資料。
MERGE (:Person {name: "Jeremy"}) // 由於Jeremy已存在,不會產生任何效果
MERGE (:Person {name: "Sophie"}) // 建立一個新的Person節點,名為Sophie
讀取資料
使用MATCH和RETURN函式可以檢索圖中的資訊。例如,傳回所有Person節點:
MATCH (n: Person)
RETURN n
或者,只傳回這些節點的name屬性:
MATCH (n: Person)
RETURN n.name
程式碼解析
以下是展示如何使用Cypher建立節點、連線節點以及查詢節點的程式碼範例:
// 建立兩個Person節點
CREATE (:Person {name: "Jeremy"})
CREATE (:Person {name: "Mark"})
// 連線Jeremy和Mark,表示Jeremy關注Mark
MATCH (jeremy:Person {name: "Jeremy"})
MATCH (mark:Person {name: "Mark"})
CREATE (jeremy)-[:FOLLOWS]->(mark)
// 使用MERGE函式,避免重複建立Jeremy
MERGE (:Person {name: "Jeremy"})
// 建立一個新的Person節點Sophie
MERGE (:Person {name: "Sophie"})
// 傳回所有Person節點
MATCH (n: Person)
RETURN n
// 傳回所有Person節點的name屬性
MATCH (n: Person)
RETURN n.name
內容解密:
CREATE (:Person {name: "Jeremy"}):這條Cypher陳述式建立了一個新的節點,標籤為Person,並具有一個屬性name,其值為"Jeremy"。MATCH (jeremy:Person {name: "Jeremy"}):這條陳述式在圖資料函式庫中查詢標籤為Person且name屬性為"Jeremy"的節點,並將其指定給變數jeremy。CREATE (jeremy)-[:FOLLOWS]->(mark):這條陳述式在jeremy和mark兩個節點之間建立了一條有向邊,關係型別為FOLLOWS,表示Jeremy關注Mark。MERGE (:Person {name: "Jeremy"}):由於Jeremy已經存在,這條陳述式不會產生任何效果。MERGE用於避免重複建立相同的節點或關係。MATCH (n: Person) RETURN n.name:這條陳述式查詢所有標籤為Person的節點,並傳回它們的name屬性值。
本章介紹瞭如何使用Neo4j和Cypher查詢語言來處理圖資料。透過學習這些基本操作,可以進一步探索更複雜的圖分析和應用。### 下一步
掌握了Neo4j和Cypher的基本操作後,我們可以進一步探索如何利用這些工具進行更複雜的圖分析和應用。未來,我們可以深入研究如何在Python中使用igraph與Neo4j結合,進行更高效的圖資料分析和處理。