在前面的文章中,有介紹過 Neo4j Bloom,不過在產品定位上,它仍比較是一個視覺化的資料互動工具,如果我們需要跑一些特殊的演算法,例如要尋找一個圖的中心點或重要連接點、或是群聚分析等,就還是得使用 Neo4j 的資料科學函式庫。
GDS 函式庫提供了一些常用的圖形資料演算法,包括群落分析、圖形中心、節點相似度、尋找路徑、連接預測 ... 等等,並且對大量資料的運算做最佳化的處理,例如平行運算,以及在記憶體內執行。
Neo4j GDS 官網 有對這些演算法做更近一步的解釋。
所有的演算法清單可以看這裡
安裝 GDS Library 就跟其他 Plugins 類似,參考圖如下:
如果是安裝在 Neo4j Server,之後介紹到 Server 版的時候再一起說明~
註:
Graph Data Science library 的前身是 Graph Algorithms library,但 GA 已不再更新;請直接安裝 GDS。兩者請勿同時安裝,避免 Neo4j 無法正常啟動。
要體驗 GDS 還是得有足夠大量的圖形資料,這部分 Neo4j 官方已經在 Sandbox 準備好環境,進入後預設就會開啟 GDS 教學,資料集來自於「冰與火之歌:權力遊戲」這部小說。後續用到的範例都是節錄部分官網的教學,全部的詳細範例與教學還是請自行參考官網喔。
對於 Sandbox 還不熟的朋友們可以先回去看看之前的文章。Neo4j & Sandbox
首先,在做資料分析前,如之前所說,還是得先了解一下 DB Schema
CALL db.schema.visualization()
Dead, King, Knight 這三個標籤常與 Person 標籤出現在同一個節點上,所以先暫時隱藏比較好查看 schema。
對人物彼此關係的連接數先有些感覺
MATCH (c:Person)-[:INTERACTS]->()
WITH c, count(*) AS num
RETURN min(num) AS min, max(num) AS max, avg(num) AS avg_interactions, stdev(num) AS stdev
為何要評估記憶體呢?因為 GDS 為了達到運算效能的最佳化,會先把需要用到的圖形資料暫存一份到記憶體,然後才開始跑演算法,如果資料庫愈大,或是演算法用到的節點與關係數非常多,就會需要大量記憶體。
以下就是用到 GDS 函數庫,估算所有的 Person 節點以及 INTERACTS 關係的數量,以及需要多少記憶體:
// GDS ver 1.8
CALL gds.graph.create.estimate('Person', 'INTERACTS') YIELD nodeCount, relationshipCount, requiredMemory
// GDS ver 2.0+
CALL gds.graph.project.estimate('Person', 'INTERACTS') YIELD nodeCount, relationshipCount, requiredMemory
nodeCount | relationshipCount | requiredMemory |
---|---|---|
2166 | 3907 | "329 KiB" |
以上述結果來看,仍然是小資料量,所以直接在記憶體中建立一個子圖形
// GDS ver 1.8
CALL gds.graph.create('got-interactions', 'Person', 'INTERACTS')
// GDS ver 2.0+
CALL gds.graph.project('got-interactions', 'Person', 'INTERACTS')
接著我們可以再次評估如果在這個子圖形上,跑某個演算法,還會需要額外多少記憶體用量:
// GDS ver 1.8
CALL gds.pageRank.stream.estimate('got-interactions') YIELD requiredMemory
// GDS ver 2.0+
CALL gds.pageRank.stream.estimate('got-interactions', {}) YIELD requiredMemory
也可以將上述兩道指令合併,評估所有記憶體用量:
// GDS ver 1.8
CALL gds.pageRank.stream.estimate({nodeProjection: 'Person', relationshipProjection: 'INTERACTS'})
// GDS ver 2.0+
CALL gds.pageRank.stream.estimate({nodeProjection: 'Person', relationshipProjection: 'INTERACTS'}, {})
如果不再使用某個子圖形,記得釋放記憶體:
CALL gds.graph.drop('got-interactions');
操作 Neo4j GDS - 建立更小的子圖形以節省記憶體
前面說明如何將需要運算的標籤與關係圖放進記憶體,但如果我們想要指定更明確範圍的標籤與關係,就需要用 Cypher 語法,會更節省記憶體,不過缺點是,建立子圖形的過程會比較慢!
GDS 使用 Cypher 建立子圖的指令是 gds.graph.create.cypher,官網已有範例,就不再贅述囉。
查看目前已經建立的子圖形
CALL gds.graph.list('got-interactions-cypher')
CALL gds.graph.list()
以上先分享用 GDS 建立子圖與記憶體用量評估,這都是開始圖形演算法之前的準備動作,下次將聚焦在演算法的操作囉~
參考來源:
https://neo4j.com/graph-data-science-library/
https://neo4j.com/docs/graph-data-science/current/
https://github.com/neo4j/graph-data-science/
https://medium.com/neo4j/hands-on-with-the-neo4j-graph-data-science-sandbox-7b780be5a44f