返回文章列表

NetworkX 加權網路視覺化與圖分析

本文探討 NetworkX 的應用,涵蓋加權網路視覺化、有向圖分析、不同圖形型別以及網路資料格式的讀寫。文章首先介紹如何使用 NetworkX 根據邊權重調整節點佈局和邊顏色,並解析如何區分內部邊和外部邊。接著,文章詳細說明有向圖的操作,包括讀取 GEXF

資料視覺化 圖演算法

NetworkX 是一個功能強大的 Python 函式庫,專門用於建立、操作和研究複雜網路的結構、動態和功能。本文將探討如何使用 NetworkX 進行加權網路視覺化和有向圖分析,並解析不同圖形型別及其應用場景。首先,我們會示範如何利用 spring_layout() 函式根據邊權重調整節點位置,並使用 draw_networkx() 函式根據邊權重繪製不同顏色的邊,以清晰地呈現網路結構。接著,將介紹如何使用 NetworkX 處理有向圖(DiGraph),包含讀取 GEXF 格式資料、繪製有向圖、區分前驅和後繼節點,以及將有向圖轉換為無向圖等操作。除了基本圖形操作,本文還會探討 NetworkX 支援的不同圖形型別,例如無向圖、有向圖、多圖和多有向圖,並說明它們在不同網路分析場景下的應用。最後,我們將深入研究 NetworkX 如何處理不同格式的網路資料,例如邊列表、加權邊列表、鄰接列表和 GEXF 格式,並示範如何讀取和設定節點屬性和邊屬性,以便進行更深入的網路分析和視覺化。

加權網路視覺化與有向圖分析

在網路分析中,節點之間的連線強度往往具有重要意義。以Zachary的空手道俱樂部網路為例,透過引入邊權重(edge weight)來表示成員間的聯絡緊密程度,能夠更準確地呈現網路結構。

加權網路視覺化

在NetworkX中,可以透過spring_layout()函式的weight引數來實作根據邊權重的佈局調整。以下程式碼展示瞭如何視覺化加權網路:

weighted_pos = nx.spring_layout(G, pos=karate_pos, k=0.3, weight="weight")
nx.draw_networkx(
    G, weighted_pos, width=8, node_color=node_color,
    edge_color=edge_weights, edge_cmap=plt.cm.Blues,
    edge_vmin=0, edge_vmax=6)
nx.draw_networkx_edges(
    G, weighted_pos, edgelist=internal, edge_color="gray")
nx.draw_networkx_edges(
    G, weighted_pos, edgelist=external, edge_color="gray", style="dashed")

內容解密:

  1. spring_layout()函式根據邊權重調整節點位置,使強連線的節點更為接近。
  2. draw_networkx()函式根據邊權重為邊著色,使用Blues色彩對映表,使權重較高的邊呈現較深的藍色。
  3. 透過兩次呼叫draw_networkx_edges(),分別繪製內部和外部邊,內部邊使用實線,外部邊使用虛線,以區分不同型別的連線。

有向圖(DiGraph)分析

在許多實際網路中,節點之間的關係具有方向性,例如員工與上司之間的關係。NetworkX中的DiGraph類別支援有向圖的操作。

有向圖的基本操作

G = nx.read_gexf("data/knecht2008/klas12b-net-1.gexf")
student_pos = nx.spring_layout(G, k=1.5)
nx.draw_networkx(G, pos, arrowsize=20)

內容解密:

  1. read_gexf()函式讀取GEFX格式的網路資料。
  2. spring_layout()函式計算節點位置。
  3. draw_networkx()函式繪製有向圖,並透過arrowsize引數調整箭頭大小,使方向性更為明顯。

有向圖中的鄰居節點

在有向圖中,一個節點的鄰居可以分為前驅(predecessor)和後繼(successor)。

list(G.neighbors(0))
list(G.successors(0))
list(G.predecessors(0))

內容解密:

  1. neighbors()方法傳回節點的後繼節點,等同於successors()方法。
  2. predecessors()方法傳回節點的前驅節點。
  3. 一個節點可能同時是另一個節點的前驅和後繼。

有向圖轉無向圖

有時需要將有向圖轉換為無向圖進行分析,DiGraph類別提供了to_undirected()方法。

G_either = G.to_undirected()
G_both = G.to_undirected(reciprocal=True)

內容解密:

  1. to_undirected()方法預設建立一個無向圖,只要原有向圖中任一方向存在邊,就會在無向圖中建立一條無向邊。
  2. 設定reciprocal=True時,只有當原有向圖中雙向都存在邊時,才會在無向圖中建立一條無向邊。

從資料到網路:NetworkX 的應用

在利用 NetworkX 分析系統時,首先需要將該系統建模為網路,然後在 NetworkX 中表示為物件。本章節將闡述建立資料網路表示的基本過程。第一部分涵蓋在腦海中進行的過程:將資料建模為網路。其餘部分則透過程式碼展示如何實作:使用兩種不同的方法從資料建立 NetworkX 圖形。

將資料建模為網路

在將資料表示為網路時,需要做出許多決定。不同型別的網路有助於理解不同型別的資料,並提出不同型別的問題。本文將更仔細地探討一些重要的考慮因素。

定義節點和邊緣

在從資料建立網路時,最重要的問題之一是節點和邊緣究竟應該代表什麼。通常,即使對於相同的資料集,也有許多可能性。任何特定的選擇都會聚焦於資料的某些方面,可能會丟棄其他方面。網路從根本上講是關於關係和連線,因此定義節點和邊緣的一種方法是思考你感興趣的關係型別。一些可能性包括:

  • 社會關係,如友誼、戀愛關係,甚至是競爭對手關係
  • 流動,如資訊、人、資金、流體或能量
  • 影響力,如科學參照、軟體依賴或蛋白質互動作用
  • 連線,如網路電腦之間的連線、骨骼中的骨骼、鄰國或鐵路線路
  • 互動,如捕食者與獵物的關係或國際條約
  • 文字中共現的詞語

一旦你知道你想了解什麼型別的關係,節點的選擇應該是顯而易見的:社交網路中的人、蛋白質互動作用中的蛋白質、國際條約中的國家等。同樣,關係的性質通常會建議使用什麼型別的網路。流動具有方向性,建議使用有向網路。鐵路線允許雙向行駛,建議使用無向網路。如果你對非常具有傳染性的疾病是否能在兩個人之間傳播感興趣,你可能只需要一個未加權的網路。但是,如果感染通常需要多次接觸,你可能需要一個加權網路來跟蹤兩個人互動的次數。當然,總是可以從相同的資料集建立多個網路,以研究多個問題。

網路檔案:將網路儲存到檔案中

NetworkX 支援多種標準的網路格式,可以將建立的網路儲存到檔案中,以便於後續使用或與其他工具分享。

從程式碼建立網路

對於更複雜的資料,可以透過程式碼逐步新增節點和邊緣,從頭開始建立網路。這種方法提供了更大的靈活性,可以根據特定的需求自定義網路建立的過程。

NetworkX 中的不同圖形型別

有向與無向圖

NetworkX 提供了 Graph 類別用於無向網路,以及 DiGraph 類別用於有向網路。這兩種類別分別適用於不同型別的關係和連線。

多圖與多有向圖

在某些情況下,兩個節點之間可能存在多條邊緣,例如柯尼斯堡七橋問題中的橋樑。在這種情況下,MultiGraphMultiDiGraph 類別就派上了用場,它們允許在相同的兩個端點之間新增任意數量的邊緣。

# 柯尼斯堡七橋
G = nx.MultiGraph()
G.add_edges_from([
    ("北岸", "克奈珀霍夫島", {"橋樑": "克拉默橋"}),
    ("北岸", "克奈珀霍夫島", {"橋樑": "施密德橋"}),
    ("北岸", "洛姆瑟島", {"橋樑": "霍爾茨橋"}),
    ("洛姆瑟島", "克奈珀霍夫島", {"橋樑": "大教堂橋"}),
    ("南岸", "克奈珀霍夫島", {"橋樑": "綠橋"}),
    ("南岸", "克奈珀霍夫島", {"橋樑": "科特爾橋"}),
    ("南岸", "洛姆瑟島", {"橋樑": "高橋"})
])

內容解密:

此範例程式碼展示瞭如何使用 MultiGraph 類別來表示柯尼斯堡七橋問題。在這個例子中,我們建立了一個多圖 G,並新增了代表七座橋樑的邊緣,每個邊緣都有一個屬性 橋樑 用於標識橋樑的名稱。這種表示方法允許我們在相同的兩個節點之間新增多條邊緣,從而準確地建模柯尼斯堡七橋問題。

從資料到網路:網路檔案的讀取與寫入

在網路科學的研究中,將資料轉化為網路結構是至關重要的步驟。Wikipedia 的文章之間存在多種關係,例如主題相關性、編輯者之間的合作關係等,這些都可以被建模成不同的網路結構。接下來,我們將探討如何使用 NetworkX 來讀取和寫入網路檔案,並介紹幾種常見的網路檔案格式。

網路檔案的格式

NetworkX 支援多種網路檔案格式,包括鄰接表(Adjacency List)、邊列表(Edge List)、GEXF 和 JSON 等。這些格式各有其特點和適用場景。

邊列表(Edge List)

邊列表是一種簡單且實用的純文字格式。它支援邊屬性,但不支援節點屬性。邊列表的讀取和寫入可以透過 read_edgelist()write_edgelist() 函式來實作。

邊列表檔案的內容

一個邊列表檔案的示例內容如下:

# 示例邊列表網路
# 源 目標
Winegroom Uptown
Winegroom Strawshop
Uptown Strawshop
Uptown Amazelake
Strawshop Province

在這個示例中,每一行代表一條邊,節點 ID 之間用空白字元分隔。以 # 開頭的行被視為註解,會被 NetworkX 忽略。

加權邊列表

邊列表格式也支援加權邊。透過在每行的第三個位置新增權重值,並使用 read_weighted_edgelist() 函式讀取檔案,可以將權重值新增到邊屬性中。

加權邊列表檔案的內容

一個加權邊列表檔案的示例內容如下:

# 示例加權邊列表網路
# 源 目標 權重
Winegroom Uptown 1
Winegroom Strawshop 5
Uptown Strawshop 9
Uptown Amazelake 6
Strawshop Province 3

使用 NetworkX 讀取邊列表檔案

要讀取邊列表檔案,首先需要匯入必要的模組並指定資料目錄:

from pathlib import Path
import networkx as nx
import matplotlib.pyplot as plt

data_dir = Path('.') / 'data'

然後,可以使用 read_edgelist() 函式讀取邊列表檔案並建立一個 Graph 物件:

G = nx.read_edgelist(data_dir / 'example.edgelist')

對於有向網路,可以透過指定 create_using 引數為 nx.DiGraph 來建立一個 DiGraph 物件:

G = nx.read_edgelist(data_dir / 'example.edgelist', create_using=nx.DiGraph)

視覺化網路

讀取網路後,可以使用 draw_networkx() 函式進行視覺化:

pos = nx.spring_layout(G)
nx.draw_networkx(G, pos)
plt.gca().margins(0.15, 0.15)
plt.show()

對於加權網路,可以提取邊權重並根據權重繪製網路:

G = nx.read_weighted_edgelist(data_dir / 'weighted.edgelist')
weights = [d['weight'] for s, t, d in G.edges(data=True)]
# 繪製網路並根據權重設定邊顏色

#### 內容解密:

  1. 匯入必要的模組:使用 from pathlib import Pathimport networkx as nx 分別匯入處理路徑和網路分析所需的模組。
  2. 指定資料目錄:透過 data_dir = Path('.') / 'data' 指定存放資料的目錄。
  3. read_edgelist() 函式:用於讀取邊列表檔案並建立 Graph 或 DiGraph 物件,取決於是否指定 create_using=nx.DiGraph
  4. draw_networkx() 函式:用於繪製網路圖,結合 spring_layout() 可以實作美觀的佈局。
  5. 提取邊權重:透過列表推導式 [d['weight'] for s, t, d in G.edges(data=True)] 提取每條邊的權重,用於後續的視覺化或分析。

圖表翻譯:

此圖示展示了一個簡單的有向或無向網路結構,以及如何透過 NetworkX 將其視覺化。節點代表實體(如 Wikipedia 文章或編輯者),邊代表它們之間的關係(如連結或合作)。透過調整引數(如是否為有向圖、是否包含權重),可以滿足不同的分析需求。

從資料到網路:深入理解網路資料格式與屬性

在網路分析與視覺化的過程中,資料的表示方式對於後續的處理和分析至關重要。NetworkX 提供了多種讀取和寫入網路資料的格式,包括邊列表(edge list)、鄰接列表(adjacency list)以及 GEXF 格式等。本章節將探討這些格式的特點、應用場景以及如何使用 NetworkX 進行操作。

邊列表格式及其屬性

邊列表是一種常見的網路表示方法,每一行代表一條邊,通常包含源節點、目標節點以及可選的邊屬性。例如,在一個模擬的地鐵網路中,我們可以使用邊列表來表示站點之間的連線關係,並附上權重和其他屬性,如顏色。

# 示例邊列表網路
# 源 目標 資料1 資料2 ...
Winegroom Uptown 1 red
Winegroom Strawshop 5 orange
Uptown Strawshop 9 blue
Uptown Amazelake 6 red
Strawshop Province 3 orange

內容解密:

  • 每行代表一條邊,第一列是源節點,第二列是目標節點,後續列可表示邊的屬性,如權重和顏色。
  • 在這個例子中,WinegroomUptown 之間有一條權重為 1 且顏色為紅色的邊。
  • 這種格式允許我們指定邊的屬性,但不直接支援節點屬性的表示。

讀取邊列表及其屬性

NetworkX 提供了 read_edgelist()read_weighted_edgelist() 函式來讀取邊列表。透過傳遞 data 引數,我們可以指定如何解析邊屬性。

# 讀取邊列表
G = nx.read_edgelist(
    data_dir / 'attributes.edgelist',
    data=[('weight', float), ('color', str)])

# 提取顏色屬性
colors = [d['color'] for s, t, d in G.edges(data=True)]

# 繪製網路
nx.draw_networkx(
    G, width=4, edge_color=colors)
plt.gca().margins(0.15, 0.15)

內容解密:

  • read_edgelist() 函式用於讀取邊列表,並透過 data 引數指定邊屬性的解析方式。
  • 在這個例子中,我們定義了兩個屬性:weightcolor,分別對應浮點數和字串型別。
  • 將提取的顏色屬性傳遞給 draw_networkx()edge_color 引數,實作了根據顏色屬性繪製網路。

鄰接列表格式

鄰接列表是一種簡潔的網路表示方法,每一行代表一個節點及其鄰居節點。這種格式不直接支援邊屬性的表示,但在某些場景下非常方便。

# 示例鄰接列表網路
# 源 目標1 目標2 ...
Winegroom Uptown Strawshop
Uptown Strawshop Amazelake Winegroom
Strawshop Winegroom
Province Strawshop

內容解密:

  • 每行第一個節點與後續節點之間存在邊的關係。
  • 這種格式簡潔,但無法直接表示邊屬性。

GEXF 格式與節點屬性

GEXF 是一種根據 XML 的網路表示格式,支援節點和邊的多種屬性。NetworkX 可以輕鬆讀寫 GEXF 檔案,使其成為跨工具合作的首選格式之一。

# 新增節點屬性
for v in G.nodes:
    G.nodes[v]['abbreviation'] = v[0]

# 匯出為 GEXF 格式
import sys
nx.write_gexf(G, sys.stdout)

內容解密:

  • 為每個節點增加了一個名為 abbreviation 的屬性,其值為節點名稱的第一個字元。
  • 使用 write_gexf() 將網路匯出為 GEXF 格式,並輸出到標準輸出。

此圖示

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

title NetworkX 加權網路視覺化與圖分析

package "網路架構" {
    package "應用層" {
        component [HTTP/HTTPS] as http
        component [WebSocket] as ws
        component [gRPC] as grpc
    }

    package "傳輸層" {
        component [TCP] as tcp
        component [UDP] as udp
        component [TLS/SSL] as tls
    }

    package "網路層" {
        component [IP] as ip
        component [ICMP] as icmp
        component [路由協議] as routing
    }

    package "鏈路層" {
        component [Ethernet] as eth
        component [WiFi] as wifi
        component [ARP] as arp
    }
}

http --> tcp
ws --> tcp
grpc --> tcp
tcp --> tls : 加密
tls --> ip
udp --> ip
ip --> routing
routing --> eth
routing --> wifi
eth --> arp

@enduml

圖表翻譯:

此圖表呈現了不同網路資料格式之間的關係與特性。資料格式主要分為三類別:邊列表、鄰接列表和GEXF。其中,邊列表支援邊屬性的表示;鄰接列表以簡潔著稱,但不直接支援邊屬性;GEXF則全面支援節點和邊的多種屬性。透過這樣的分類別,可以根據具體需求選擇最合適的資料表示方法,以最佳化後續的網路分析和視覺化工作。