返回文章列表

網路資料格式與屬性處理技術

本文探討了 NetworkX 處理網路資料的技術,包含邊列表、鄰接列表和 GEXF 等格式,以及如何讀取、寫入和視覺化網路資料。文章同時介紹瞭如何處理邊和節點的屬性,以及如何構建詞共現網路和關聯網路等不同型別的網路。

圖論 資料分析

NetworkX 提供了便捷的函式來處理不同格式的網路資料,例如 read_edgelist() 可以讀取邊列表,read_adjlist() 可以讀取鄰接列表,write_gexf() 可以將網路資料儲存為 GEXF 格式。這些函式支援讀取和寫入節點和邊的屬性,例如權重、顏色或縮寫,方便進行更細緻的網路分析和視覺化。透過 G.edges(data=True)G.nodes(data=True) 可以存取這些屬性,並將其應用於網路圖的繪製,例如設定邊的顏色或節點的大小。此外,文章還介紹瞭如何從文字資料構建詞共現網路,以及如何使用 NetworkX 建立和分析關聯網路,例如電影演員和電影之間的關係。關聯網路可以透過投影操作轉換為單一型別的網路,方便分析特定型別節點之間的關係。

從資料到網路:網路資料格式與屬性處理

在網路分析中,正確地讀取和寫入網路資料至關重要。NetworkX 提供了多種格式來處理網路資料,包括邊列表(edge list)、鄰接列表(adjacency list)以及 GEXF 格式等。每種格式都有其特定的應用場景和優缺點。

邊列表格式與屬性處理

邊列表是一種常見的網路資料表示方式,其中每行代表一條邊,通常包含源節點、目標節點以及可選的邊屬性。以下是一個簡單的邊列表範例:

Winegroom Uptown 1 red
Winegroom Strawshop 5 orange
Uptown Strawshop 9 blue
Uptown Amazelake 6 red
Strawshop Province 3 orange

在這個範例中,每行不僅定義了節點之間的連線,還包含了邊的權重(weight)和顏色(color)屬性。要讀取這種包含屬性的邊列表,可以使用 read_edgelist() 函式並傳遞 data 引數:

G = nx.read_edgelist(data_dir / 'attributes.edgelist', data=[('weight', float), ('color', str)])

讀取後,可以透過遍歷 G.edges(data=True) 來提取邊的屬性,例如顏色,並將其用於網路視覺化:

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)

內容解密:

  1. read_edgelist() 函式:用於讀取邊列表檔案,並可透過 data 引數指定邊屬性。
  2. data 引數:一個包含元組的列表,用於定義邊屬性的名稱和型別。
  3. G.edges(data=True):遍歷所有邊並傳回包含邊屬性的資料。
  4. edge_color 引數:在 draw_networkx() 中使用邊的顏色屬性進行視覺化。

鄰接列表格式

鄰接列表是一種更簡潔的表示網路的方式,其中每行第一個節點與後續節點之間存在邊。以下是一個鄰接列表範例:

Winegroom Uptown Strawshop
Uptown Strawshop Amazelake Winegroom
Strawshop Winegroom
Province Strawshop

使用 read_adjlist() 可以輕鬆將鄰接列表轉換為 NetworkX 圖物件:

G = nx.read_adjlist(data_dir / 'example.adjlist')

內容解密:

  1. read_adjlist() 函式:讀取鄰接列表檔案並建立圖物件。
  2. 簡潔性:鄰接列表適合表示稠密網路,但無法直接攜帶邊屬性。

GEXF 格式與節點屬性

GEXF 是一種根據 XML 的格式,支援節點和邊的屬性,非常適合複雜網路的表示。要將節點屬性寫入 GEXF 檔案,可以先為節點新增屬性,例如縮寫(abbreviation):

for v in G.nodes:
    G.nodes[v]['abbreviation'] = v[0]

然後使用 write_gexf() 將圖物件匯出為 GEXF 檔案:

nx.write_gexf(G, sys.stdout)

輸出結果如下所示,這是一種結構化的表示方式,能夠完整保留節點和邊的屬性:

<?xml version='1.0' encoding='utf-8'?>
<gexf version="1.2" xmlns="http://www.gexf.net/1.2draft">
    <!-- 省略部分內容 -->
    <nodes>
        <node id="Winegroom" label="Winegroom">
            <attvalues>
                <attvalue for="0" value="W" />
            </attvalues>
        </node>
        <!-- 其他節點 -->
    </nodes>
</gexf>

內容解密:

  1. write_gexf() 函式:將 NetworkX 圖物件匯出為 GEXF 格式。
  2. 節點屬性:透過為節點新增自定義屬性(如縮寫),豐富網路資料。
  3. GEXF 結構:採用 XML 結構,能夠清晰地表示節點、邊及其屬性。

此圖示說明瞭不同網路資料格式之間的比較:

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

title 網路資料格式與屬性處理技術

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

此圖示內容解說:

  1. 邊列表:適用於需要攜帶豐富邊屬性的場景。
  2. 鄰接列表:適合表示稠密網路,簡潔高效。
  3. GEXF 格式:能夠完整儲存節點和邊的多種屬性,適用於複雜網路。

從資料到網路:探討網路格式與建構方法

在上一章中,我們探討瞭如何使用 NetworkX 來處理和分析網路資料。本章將進一步探討不同的網路格式,以及如何從原始資料構建網路。

網路格式的多樣性

在處理網路資料時,我們經常需要處理不同的檔案格式。NetworkX 支援多種格式,包括 GEXF、GDF、GraphML 和 JSON 等。這些格式各有其特點和適用場景。

GEXF 格式

GEXF(Graph Exchange XML Format)是一種根據 XML 的圖形交換格式。它支援節點和邊的屬性,並且可以包含層次結構。以下是一個 GEXF 檔案的範例:

<gexf xmlns="http://www.gexf.net/1.2draft" version="1.2">
  <graph mode="static" defaultedgetype="undirected">
    <nodes>
      <node id="Winegroom" label="Winegroom">
        <attvalues>
          <attvalue for="0" value="W" />
        </attvalues>
      </node>
      ...
    </nodes>
    <edges>
      <edge id="0" source="Winegroom" target="Uptown" weight="1.0">
        <attvalues>
          <attvalue for="1" value="red" />
        </attvalues>
      </edge>
      ...
    </edges>
  </graph>
</gexf>

JSON 格式

JSON(JavaScript Object Notation)是一種輕量級的資料交換格式。它易於閱讀和編寫,並且可以被多種程式語言支援。以下是一個 JSON 檔案的範例:

{
  "directed": false,
  "graph": {},
  "links": [
    {"color": "red", "source": "Winegroom", "target": "Uptown", "weight": 1.0},
    ...
  ],
  "multigraph": false,
  "nodes": [
    {"abbreviation": "W", "id": "Winegroom"},
    ...
  ]
}

從原始資料構建網路

有時候,我們需要從原始資料構建網路。這可以透過逐步新增節點和邊來實作。以下是一個使用 Python 和 NetworkX 建構詞共現網路的範例:

詞共現網路

詞共現網路是一種用於理解檔案中詞彙之間關係的網路。在這種網路中,節點代表詞彙,而邊的權重代表它們在同一句中出現的次數。

import re
import networkx as nx

def co_occurrence_network(text):
    # 建立一個新的網路
    G = nx.Graph()
    
    # 將文字分割成句子並迭代處理
    sentences = text.split('.')
    for s in sentences:
        # 移除標點符號並轉換為小寫
        clean = re.sub('[^\w\n ]+', '', s).lower()
        clean = re.sub('_+', '', clean).strip()
        
        # 建立詞彙清單
        words = re.split('\s+', clean)
        
        # 為每個詞彙建立節點和邊
        for v in words:
            try:
                G.nodes[v]['count'] += 1
            except KeyError:
                G.add_node(v)
                G.nodes[v]['count'] = 1
            
            for w in words:
                if v == w or v in ['the', 'of', 'and'] or w in ['the', 'of', 'and']:
                    continue
                if len(v) == 0 or len(w) == 0:
                    continue
                
                try:
                    G.edges[v, w]['count'] += 1
                except KeyError:
                    G.add_edge(v, w, count=1)
    
    return G

# 讀取文字資料
with open('frankenstein.txt') as f:
    text = f.read()

# 建立詞共現網路
G = co_occurrence_network(text)

# 對邊進行排序
pairs = sorted(G.edges(data=True), key=lambda e: e[2]['count'], reverse=True)
print(pairs[0:10])

內容解密:

  1. co_occurrence_network函式:該函式接受一個文字字串作為輸入,並傳回一個詞共現網路。
  2. 文字預處理:函式首先將文字分割成句子,然後移除標點符號並轉換為小寫。
  3. 建立節點和邊:函式為每個詞彙建立節點,並為每對在同一句中出現的詞彙建立邊。
  4. 排序邊:最後,函式對邊進行排序,以找出最常共現的詞彙對。

從資料到網路:關聯網路的建立與分析

在前一章節中,我們探討瞭如何將資料轉化為網路並進行基本分析。本章節將深入介紹關聯網路(Affiliation Networks)的概念及其在NetworkX中的實作。

節點與關聯

許多現實世界的關係涉及多於兩個節點。例如,在電影演員的關係網路中,一部電影通常有多位演員,而一位演員也可以出演多部電影。這種多對多的關係可以透過引入第二種型別的節點來表示,從而形成關聯網路。

六度分隔理論與關聯網路

「六度分隔理論」的一個著名應用是「Kevin Bacon的遊戲」。在這個遊戲中,目標是找到任意演員與Kevin Bacon之間的聯絡。例如,Jon Hamm透過與Rose Byrne共同出演《伴娘》等電影,而Rose Byrne又與Kevin Bacon共同出演《X戰警:第一戰》,從而建立了與Kevin Bacon的聯絡。

這種遊戲根據一個網路,其中節點代表演員,邊代表兩位演員共同出演的電影。然而,這種表示方法存在侷限性:每部電影需要多條邊來表示其所有演員之間的關係,如果一部電影只有一位演員,則不會在網路中出現。為瞭解決這個問題,可以引入一個新的網路結構——關聯網路,其中包含兩種型別的節點:演員和電影。每條邊連線一位演員和一部他參與的電影。

關聯網路的定義

正式來說,關聯網路(或稱二部網路)是一種具有兩種型別節點的網路,並且只允許不同型別節點之間的連線。這與標準的單一型別網路不同,後者只包含一種節點。兩種型別的節點可以被稱為「頂部」和「底部」或「左側」和「右側」,但這些只是用於區分的稱呼。

NetworkX中的關聯網路

NetworkX提供了對關聯網路的支援,使得建立、檢測、操作和視覺化這種網路變得容易。

import networkx as nx
import matplotlib.pyplot as plt

# 建立一個空的關聯網路
G = nx.Graph()

# 新增兩種型別的節點:演員和電影
actors = ['Jon Hamm', 'Rose Byrne', 'Kevin Bacon']
movies = ['Bridesmaids', 'X-Men: First Class']

G.add_nodes_from(actors, bipartite=0)  # 演員
G.add_nodes_from(movies, bipartite=1)  # 電影

# 新增邊:演員與電影之間的關係
G.add_edge('Jon Hamm', 'Bridesmaids')
G.add_edge('Rose Byrne', 'Bridesmaids')
G.add_edge('Rose Byrne', 'X-Men: First Class')
G.add_edge('Kevin Bacon', 'X-Men: First Class')

# 檢查網路是否是二部的
print(nx.is_bipartite(G))

# 視覺化關聯網路
pos = nx.spring_layout(G)
nx.draw_networkx_nodes(G, pos, nodelist=actors, node_color='lightblue')
nx.draw_networkx_nodes(G, pos, nodelist=movies, node_color='lightgreen')
nx.draw_networkx_edges(G, pos)
nx.draw_networkx_labels(G, pos)
plt.show()

內容解密:

  1. 建立關聯網路:首先,我們建立一個空圖G,然後分別新增兩種型別的節點(演員和電影),並使用bipartite屬性區分它們。
  2. 新增邊:根據實際關係,在不同型別的節點之間新增邊。
  3. 檢查二部性:使用nx.is_bipartite(G)檢查圖是否是二部的,以確保其結構正確。
  4. 視覺化:透過區分不同型別的節點顏色來視覺化關聯網路,使其更容易理解。

投影

在某些情況下,我們可能希望將關聯網路轉換為單一型別的網路,這可以透過投影實作。投影是將關聯網路中的一種型別的節點轉換為新的網路,其中兩個節點之間的邊根據它們在原網路中分享的鄰居數量。

投影示例

# 取得演員的投影
actors_projection = nx.bipartite.projected_graph(G, actors)

# 視覺化演員投影網路
pos = nx.spring_layout(actors_projection)
nx.draw_networkx_nodes(actors_projection, pos)
nx.draw_networkx_edges(actors_projection, pos)
nx.draw_networkx_labels(actors_projection, pos)
plt.show()

內容解密:

  1. 投影操作:使用nx.bipartite.projected_graph函式對指定的節點型別(例如演員)進行投影,生成新的單一型別網路。
  2. 視覺化投影網路:展示投影後的網路,有助於分析不同演員之間的合作關係。