NetworkX 是 Python 上最常用的圖分析包,GraphScoep 兼容 NetworkX 接口。本文中我們將分享如何用 GraphScope 像 NetworkX 一樣在(大)圖上進(jìn)行分析。
NetworkX 是一個用 Python 語言開發(fā)的圖論與復(fù)雜網(wǎng)絡(luò)建模工具,它內(nèi)置了常用的圖與復(fù)雜網(wǎng)絡(luò)分析算法,提供了一套簡單易用的圖分析接口,可以方便地進(jìn)行復(fù)雜網(wǎng)絡(luò)數(shù)據(jù)分析、仿真建模等工作。NetworkX 的接口設(shè)計十分簡潔,對于作為剛進(jìn)入圖算法領(lǐng)域的小白來說,NetworkX 的接口可以幫助使用者快速建立起對圖數(shù)據(jù)的感知,并且對于中小型數(shù)據(jù)集,NetworkX 的接口也是非常好上手的。
但由于 NetworkX 是基于 Python 語言開發(fā),算法的性能并不是它的強(qiáng)項,而且也無法有效地處理工業(yè)級別的大規(guī)模圖數(shù)據(jù)?;谶@一背景,GraphScope 提供了一套兼容 NetworkX 的圖分析接口,在能使用像 NetworkX 這樣簡單易用的接口的同時,也能提供高性能的圖分析算法以支持超大規(guī)模圖數(shù)據(jù)的處理。
我們通過一個小例子來簡單介紹一下 NetworkX 的圖分析過程。
# NetworkX 的圖分析過程從圖的構(gòu)建開始
import networkx
# 初始化一個空的無向圖
G = networkx.Graph()
# 通過 add_edges_from 接口添加邊列表
# 此處添加了兩條邊(1, 2)和(1, 3)
G.add_edges_from([(1, 2), (1, 3)])
# 通過 add_node 添加點4
G.add_node(4)
# 接著查看一些圖的信息
# 使用 G.number_of_nodes 查詢圖G目前點的數(shù)目
G.number_of_nodes()
# 4
# 類似地,G.number_of_edges 可以查詢圖G中
# 邊的數(shù)量
G.number_of_edges()
# 2
# 通過 G.degree 來查看圖G中每個點的度數(shù)
sorted(d for n, d in G.degree())
# [0, 1, 1, 2]
# 最后調(diào)用 NetworkX 內(nèi)置的算法對對圖進(jìn)行分析
# 調(diào)用 connected_components 算法分析圖G的
# 聯(lián)通分量
list(networkx.connected_components(G))
# [{1, 2, 3}, {4},]
# 調(diào)用 clustering 算法分析圖G的聚類情況
networkx.clustering(G)
# {1: 0, 2: 0, 3: 0, 4: 0}
上述例子只是對 NetworkX 做圖分析的一個簡單的介紹,更多 NetworkX 的接口介紹以及詳細(xì)的使用說明,內(nèi)置的算法等可以參考 NetworkX 官方文檔[1]。
NetworkX 官方的 NetworkX tutorial[2] 是一個 NetworkX 接口使用以及圖的入門教程。為了演示 GraphScope 對 NetworkX 的兼容性以及如何使用 GraphScope 的 NetworkX 接口進(jìn)行圖分析,下面我們使用 GraphScope 來執(zhí)行教程中的例子。
使用 GraphScope 的 NetworkX 兼容接口,我們只需要簡單地將教程中的import netwokx as nx
替換為import graphscope.nx as nx
即可, 當(dāng)然這里只是依照 NetworkX 的慣例使用nx
作為別名, 你也可以其他自定義的別名,例如 import graphscope.nx as gs_nx
。
GraphScope 支持與 NetworkX 完全相同的載圖語法,示例里我們使用nx.Graph()
來建立一個空的無向圖。
import graphscope.nx as nx
# 我們可以建立一個空的無向圖
G = nx.Graph()
GraphScope 的圖操作接口也保持了與 NetworkX 的兼容,用戶可以通過add_node
和add_nodes_from
來添加節(jié)點,通過add_edge
和add_edges_from
來添加邊。
# 通過 add_node 一次添加一個節(jié)點
G.add_node(1)
# 或從任何 iterable 容器中添加節(jié)點,如列表
G.add_nodes_from([2, 3])
# 如果容器中是元組的形式,還可以在添加節(jié)點的同時,
# 添加節(jié)點屬性
G.add_nodes_from([(4, {"color": "red"}), (5, {"color": "green"})])
# 對于邊,可以通過 add_edge 的一次添加一條邊
G.add_edge(1, 2)
e = (2, 3)
G.add_edge(*e)
# 通過 add_edges_from 添加邊列表
G.add_edges_from([(1, 2), (1, 3)])
# 或者通過邊元組的方式,在添加邊的同時,
# 添加邊的屬性
G.add_edges_from([(1, 2), (2, 3, {'weight': 3.1415})])
GraphScope 支持兼容 NetworkX 的圖查詢接口。用戶可以通過number_of_nodes
和number_of_edges
來獲取圖點和邊的數(shù)量,通過nodes
, edges
,adj
和degree
等接口來獲取圖當(dāng)前的點和邊,以及點的鄰居和度數(shù)等信息。
# 查詢目前圖中點和邊的數(shù)目
G.number_of_nodes()
# 5
G.number_of_edges()
# 3
# 列出目前圖中的點和邊
list(G.nodes)
# [1, 2, 3, 4, 5]
list(G.edges)
# [(1, 2), (1, 3), (2, 3)]
# 查詢某個點的鄰居
list(G.adj[1])
# [2, 3]
# 查詢某個點的度
G.degree(1)
# 2
像 NetworkX 一樣, GraphScope 也可以使用與添加元素相類似的方式從圖中刪除點和邊,對圖進(jìn)行修改。例如可以通過remove_node
和remove_nodes_from
來刪除圖中的節(jié)點,通過remove_edge
和remove_edges_from
來刪除圖中的邊。
# 通過 remove_node 刪除一個點
G.remove_node(5)
# 查看圖 G 現(xiàn)有的點,發(fā)現(xiàn)點5已經(jīng)被刪除了
list(G.nodes)
# [1, 2, 3, 4]
# 通過 remove_nodes_from 刪除多個點
G.remove_nodes_from([4, 5])
# 再查看圖 G 現(xiàn)有的點,點4也已經(jīng)被刪除了
list(G.nodes)
# [1, 2, 3]
# 通過 remove_edge 刪除一條邊
G.remove_edge(1, 2)
# 查看圖 G 現(xiàn)有的邊,(1, 2) 這條邊在G中
# 已經(jīng)被刪除
list(G.edges)
# [(1, 3), (2, 3)]
# 通過 remove_edges_from 刪除多條邊
G.remove_edges_from([(1, 3), (2, 3)])
# 查看圖 G 現(xiàn)有的邊,(1, 3), (2, 3) 這兩條邊
# 在 G 中已經(jīng)不存在了
list(G.edges)
# []
# 我們再來看一下現(xiàn)在的點和邊的數(shù)目
G.number_of_nodes()
# 3
G.number_of_edges()
# 0
GraphScope 可以通過兼容 NetworkX 的接口來對圖進(jìn)行各種算法的分析,示例里我們構(gòu)建了一個簡單圖,然后分別使用connected_components
分析圖的聯(lián)通分量,使用clustering
來得到圖中每個點的聚類系數(shù),以及使用all_pairs_shortest_path
來獲取節(jié)點兩兩之間的最短路徑。
# 首先構(gòu)建圖
G = nx.Graph()
G.add_edges_from([(1, 2), (1, 3)])
G.add_node(4)
# 通過 connected_components 算法找出
# 圖中的聯(lián)通分量
list(nx.connected_components(G))
# [{4}, {1, 2, 3},]
# 通過 clustering 算法計算每個點的聚類系數(shù)
nx.clustering(G)
# {4: 0.0, 1: 0.0, 2: 0.0, 3: 0.0}
# 計算圖中節(jié)點兩兩之間的最短路徑
sp = dict(nx.all_pairs_shortest_path(G))
# 查看節(jié)點3與其他節(jié)點的最短路徑
sp[3]
# {3: [3], 1: [3, 1], 2: [3, 1, 2]}
同 NetworkX 一樣,GraphScope 支持通過draw
將圖進(jìn)行簡單地繪制出來。
(依賴matplotlib
的繪圖功能,如果未安裝,需要先通過 pip install atplotlib 安裝)
import graphscope.nx as nx
# 創(chuàng)建一個5個點的 star graph
G = nx.star_graph(5)
# 使用 nx.draw 繪制圖
nx.draw(G, with_labels=True)
通過一些簡單的例子,我們展示了 GraphScope 對于 NetworkX 接口的兼容性和一些圖操作/分析接口的使用。更詳細(xì)的使用可以參考 GraphScope 文檔[3]。
GraphScope 支持了部分 NetworkX 內(nèi)置的圖算法,我們可以通過 NetworkX 的調(diào)用算法的方式來調(diào)用這些算法。下面我們通過一個簡單的實驗來看一下 GraphScope 對比 NetworkX 在算法性能上到底提升多少。
這個實驗使用來自 SNAP 的 twitter[4] 圖數(shù)據(jù),測試算法是 NetworkX 內(nèi)置的 Clustering[5] 算法。實驗所用的機(jī)器配置為8核CPU, 16G內(nèi)存。
我們首先準(zhǔn)備下數(shù)據(jù),使用 wget 將數(shù)據(jù)集下載到本地
wget https://raw.githubusercontent.com/GraphScope/gstest/master/twitter.e ${HOME}/twitter.e
接著我們分別使用 GraphScope 和 NetworkX 載入 snap-twitter 數(shù)據(jù)
import os
import graphscope.nx as gs_nx
import networkx as nx
# 使用 NetworkX 載入 snap-twitter 圖數(shù)據(jù)
g1 = nx.read_edgelist(
os.path.expandvars('$HOME/twitter.e'),
nodetype=int,
data=False,
create_using=nx.Graph
)
type(g1)
# networkx.classes.graph.Graph
# 使用 GraphScope 載入 snap-twitter 圖數(shù)據(jù)
g2 = gs_nx.read_edgelist(
os.path.expandvars('$HOME/twitter.e'),
nodetype=int,
data=False,
create_using=gs_nx.Graph
)
type(g2)
# graphscope.nx.classes.graph.Graph
我們使用 Clustering 算法來對圖進(jìn)行聚類分析,來看一下 GraphScope 對比 NetworkX 在算法性能上有多少提升
%%time
# 使用 GraphScope 計算圖中每個點的聚類系數(shù)
ret_gs = gs_nx.clustering(g2)
# CPU times: user 213 ms, sys: 163 ms, total: 376 ms
# Wall time: 2.9 s
%%time
# 使用 NetworkX 計算圖中每個點的聚類系數(shù)
ret_nx = nx.clustering(g1)
# CPU times: user 54.8 s, sys: 0 ns, total: 54.8 s
# Wall time: 54.8 s
# 對比下兩者的結(jié)果是否一致
ret_gs == ret_nx
# True
從實驗結(jié)果我們可以看到,GraphScope 在兼容 NetworkX 接口的同時,內(nèi)置的算法對比 NetworkX 可以達(dá)到幾個數(shù)量級的性能提升。GraphScope 在提供兼容 NetworkX 簡單易用的接口的同時,也能提供非常高效的算法分析。
本文介紹了如何讓 GraphScope 使用 NetworkX 風(fēng)格的方式對圖數(shù)據(jù)進(jìn)行操作和分析,同時,本文也通過在snap-twitter 圖數(shù)據(jù)上聚類算法分析的對比來展示了 GraphScope 在兼容 NetworkX 接口的同時,提供了高效的算法分析能力。
在后續(xù)的文章中,我們將會通過 benchmark 的方式更細(xì)致地對比 GraphScope 與 NetworkX 在圖操作,圖查詢和圖分析上的一些性能比較,以及使用 GraphScope 來執(zhí)行一些 github 社區(qū)中基于 NetworkX 的有趣的數(shù)據(jù)分析項目。
本文中涉及的代碼都已經(jīng)在 GraphScope Playground 中,感興趣的讀者可以直接點擊下方的 閱讀原文,進(jìn)入 Playground 試用這些代碼。
NetworkX 官方文檔: https://networkx.org/documentation/stable/index.html
[2]NetworkX tutorial: https://networkx.org/documentation/stable/tutorial.html
[3]GraphScope 文檔: https://graphscope.io/docs/reference/networkx/index.html
[4]Snap-twitter: https://snap.stanford.edu/data/ego-Twitter.html
[5]Clustering 算法: https://networkx.org/documentation/stable/reference/algorithms/generated/networkx.algorithms.cluster.clustering.html#networkx.algorithms.cluster.clustering
聯(lián)系客服