社交網路分析是理解人群行為的有效工具,其核心概念在於人際關係形成的網路結構。這些結構影響著許多社會過程,從資訊傳播到疾病蔓延。本文將探討連結強度、橋接跨度等關鍵指標,並運用 NetworkX 函式庫示範如何以 Python 程式碼計算與分析。同時,文章也介紹了 Watts-Strogatz 和優先連線等重要的網路模型,說明如何利用這些模型模擬真實世界網路的特性,例如小世界現象和無標度特性,並探討這些特性如何影響網路上的動態過程。最後,文章也簡述了根據代理的模型,作為模擬網路中個體行為與互動的工具。
社會網路與病毒式傳播
網路分析常用於理解人群的行為。人群中的關係形成了一種網路——社會網路。社會網路是網路科學中最早被研究的領域之一,並提供了一些與日常生活最直接相關的研究成果。本章將向您介紹社會網路分析的基本結果。
本章主題包括以下內容:
- 社會網路:網路科學中社會網路的歷史
- 強弱關係:如何解釋和量化關係的強度
- 小世界問題:理解非常大的網路如何被相對較短的路徑跨越
- 傳染:資訊、疾病和其他東西如何在網路中傳播
社會網路
社會網路的定義特徵是節點代表人。這些網路本身可以代表從小型非正式的朋友圈到整個社會的任何事物。社會網路中的邊代表人與人之間的一種關係。通常,這種關係是友誼或溝通。然而,它也可以是像他們的影片串流媒體行為相似性這樣抽象的東西。想象一下;你可能從未遇到過某個人,但你們可能是世界上僅有的兩個喜歡觀看睡覺河馬影片的人。這當然是一種關係!
許多網路科學的工具都源自社會學中對社會網路的研究。社會學家Jacob L. Moreno和Helen Hall Jennings開發了社會計量學的技術,這是現代社會網路分析和網路科學的前身(Moreno和Jennings,1934)。
社會網路的結構特性
社會網路值得特別關注,因為常見的人類行為會導致特徵性的網路結構。此外,社會網路的結構對社會過程有重要影響,包括以下方面:
- 尋找工作機會
- 思想的傳播
- 疾病的傳播
- 健康行為
強弱關係
在社會網路中,並非所有的關係都是一樣的。你可能會為你的兄弟姐妹擔保貸款申請,但可能不會為你表弟的保姆的牙醫的煙囪清潔工擔保。在社會學中,關係的強度被稱為連結強度(tie strength)。在這種情況下,連結是指某種人際關係,而強度則是衡量這種關係有多密切或親密的指標。
1973年,社會學家Mark Granovetter描述了弱連結在橋接不同社群方面的重要性。如果一個社群內的所有連結都是強的,那麼社群之間的任何連結必定是弱的。他將這種現象描述為弱連結的力量(the strength of weak ties)。透過橋接不同的社群,弱連結使得從網路的遙遠部分找到資訊成為可能。但我們如何衡量連結強度?
連結強度的衡量
衡量連結強度的一種方法在第2章“在NetworkX中處理網路”中有過描述。本文將以Zachary空手道俱樂部網路(1977)為例進一步闡述。這裡重現了載入該網路的程式碼:
G = nx.karate_club_graph()
# 用分裂後的俱樂部標籤進行註解
member_club = [
0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
0, 0, 0, 0, 1, 1, 0, 0, 1, 0,
# ... 其他成員標籤
]
連結強度的分析
# 對圖G進行操作
# 統計每個成員所屬俱樂部的邊數量
# 這裡省略具體實作程式碼,請參考NetworkX相關函式
連結解密:
此程式碼段用於展示如何載入Zachary空手道俱樂部網路,並對其成員所屬俱樂部進行註解。首先,我們使用NetworkX提供的karate_club_graph()函式載入該網路。接著,我們定義了一個列表member_club來記錄每個成員在俱樂部分裂後所屬的俱樂部標籤。這一步驟對於後續分析成員關係與俱樂部分裂之間的關聯至關重要。
k核心分析及其視覺化
k核心是一種用於識別網路中高度連線區域的方法。NetworkX提供了k_core()函式來尋找k核心。該函式即使對於相對較大的網路也能快速執行。下面的例子尋找社交網路中的30核心(藍色)和60核心(橙色):
# 尋找k核心
G_core_30 = nx.k_core(G_social, 30)
G_core_60 = nx.k_core(G_social, 60)
# 視覺化網路和k核心
nx.draw_networkx(
G_social, pos=pos, node_size=0,
edge_color="#333333", alpha=0.05, with_labels=False)
nx.draw_networkx(
G_core_30, pos=pos, node_size=0,
edge_color="#7F7FEF", alpha=0.05, with_labels=False)
nx.draw_networkx(
G_core_60, pos=pos, node_size=0,
edge_color="#AFAF33", alpha=0.05, with_labels=False)
圖表翻譯:
此圖示展示了社交網路中的30核心和60核心。30核心以藍色表示,而60核心以橙色表示。這些核心代表了網路中高度連線的區域。
社交網路與病毒式傳播
網路結構與社群分析
在社交網路分析中,社群的定義是指個體之間因為共同興趣或特徵而形成的群體。這些群體內的成員比起不同群體的成員,更有可能擁有共同的朋友。因此,可以使用共同朋友的數量來衡量兩個節點之間的連結強度。
程式碼範例:計算連結強度
def tie_strength(G, v, w):
# 取得節點 v 和 w 在 G 中的鄰居
v_neighbors = set(G.neighbors(v))
w_neighbors = set(G.neighbors(w))
# 傳回共同鄰居的數量加一
return 1 + len(v_neighbors & w_neighbors)
# 計算每條邊的連結強度並儲存在 strength 中
strength = dict(((v, w), tie_strength(G, v, w)) for v, w in G.edges())
內容解密:
tie_strength函式接受一個圖G和兩個節點v和w,計算這兩個節點之間的連結強度。- 使用
G.neighbors(v)和G.neighbors(w)分別取得節點v和w的鄰居集合。 - 透過集合交集運算
v_neighbors & w_neighbors計算共同鄰居的數量,並加一作為最終的連結強度值。 - 將每條邊的連結強度儲存在
strength字典中,以便後續分析。
橋接跨度:衡量邊的重要性
橋接跨度是指如果移除一條邊後,其端點之間的網路距離。這個指標可以用來衡量一條邊在網路中的重要性。
程式碼範例:計算橋接跨度
def bridge_span(G):
# 複製圖 G
G_copy = nx.Graph(G)
result = dict()
for v, w in G.edges():
# 暫時移除邊 (v, w)
G_copy.remove_edge(v, w)
try:
# 計算移除邊後的網路距離
d = nx.shortest_path_length(G_copy, v, w)
result[(v, w)] = d
except nx.NetworkXNoPath:
# 如果沒有路徑,則設定為無窮大
result[(v, w)] = float('inf')
# 還原邊 (v, w)
G_copy.add_edge(v, w)
return result
span = bridge_span(G)
內容解密:
bridge_span函式計算圖G中每條邊的橋接跨度。- 對每條邊,暫時將其從圖中移除,並計算其端點之間的網路距離。
- 如果移除邊後兩端點之間沒有路徑,則將橋接跨度設定為無窮大。
- 將結果儲存在
span字典中,以便後續分析。
連結強度與橋接跨度的比較
透過比較連結強度和橋接跨度,可以發現低強度且高跨度的邊通常是連線不同社群的外部邊,而高強度且低跨度的邊則是連線同一社群內部成員的內部邊。
小世界問題
1967年,社會心理學家 Jeffrey Travers 和 Stanley Milgram 進行了一個著名的實驗,證明瞭人們之間的平均社交距離約為六度分離。
環形網路模型
在環形網路模型中,每個節點只與其鄰近的節點相連。這種網路結構可以模擬區域性連線的特性。
程式碼範例:建立和視覺化四環網路
G_small_ring = nx.watts_strogatz_graph(16, 4, 0)
pos = nx.circular_layout(G_small_ring)
nx.draw_networkx(G_small_ring, pos=pos, with_labels=False)
內容解密:
- 使用
watts_strogatz_graph函式建立一個具有 16 個節點的四環網路。 - 使用
circular_layout將節點排列在圓週上,以便視覺化。 - 使用
draw_networkx繪製網路圖。
大規模環形網路的特性
在大規模環形網路中,平均最短路徑長度和平均叢集係數可以反映網路的結構特性。
程式碼範例:計算大規模環形網路的特性
G_ring = nx.watts_strogatz_graph(4000, 10, 0)
print(nx.average_shortest_path_length(G_ring))
print(nx.average_clustering(G_ring))
內容解密:
- 建立一個具有 4000 個節點的大規模十環網路。
- 使用
average_shortest_path_length函式計算平均最短路徑長度。 - 使用
average_clustering函式計算平均叢集係數。
社交網路與病毒式傳播第八章
真實社交網路的特性
在前面的章節中,我們探討了環形網路的特性。現在,讓我們來看看真實的社交網路是如何運作的。根據麥克奧利和萊斯科維茨(McAuley & Leskovec, 2012)的研究,我們載入了一個真實的社交網路資料集,並計算了其平均最短路徑和平均叢集係數。
# 載入資料檔案到網路中
from pathlib import Path
data_dir = Path('.') / 'data'
G_social = nx.read_edgelist(data_dir / 'mcauley2012' / 'facebook_combined.txt')
nx.average_shortest_path_length(G_social)
# 輸出:3.6925068496963913
nx.average_clustering(G_social)
# 輸出:0.6055467186200876
內容解密:
這段程式碼首先載入了一個名為 facebook_combined.txt 的資料檔案,該檔案包含了 Facebook 社交網路的邊緣列表。然後,它使用 NetworkX 函式庫計算了該網路的平均最短路徑和平均叢集係數。平均最短路徑表示任意兩個節點之間的平均距離,而平均叢集係數則表示節點的鄰居之間相互連線的程度。
隨機網路模型
為了進一步瞭解社交網路的特性,我們建立了一個隨機網路模型。在這個模型中,我們從一個 k-環形網路開始,然後隨機地重新連線每個邊緣的端點。這樣,我們得到了一個具有相同節點和邊緣數量,但具有隨機結構的網路。
G_small_random = nx.watts_strogatz_graph(16, 4, 1)
pos = nx.circular_layout(G_small_random)
nx.draw_networkx(G_small_random, pos=pos, with_labels=False)
內容解密:
這段程式碼使用 Watts-Strogatz 圖函式生成了一個具有 16 個節點和 4 個鄰居的隨機網路,其中重新連線的機率為 1。然後,它使用圓形佈局繪製了該網路。
瓦特-史特加茲網路模型
1998 年,鄧肯·瓦特和史蒂文·史特加茲提出了一種能夠同時實作高叢集係數和短平均路徑的網路模型。他們的方法是從一個環形網路開始,然後只重新連線其中一部分邊緣。
path = []
clustering = []
p = [10**(x) for x in range(-6, 1)]
for p_i in p:
path_i = []
clustering_i = []
for n in range(10):
G = nx.watts_strogatz_graph(1000, 10, p_i)
path_i.append(nx.average_shortest_path_length(G))
clustering_i.append(nx.average_clustering(G))
path.append(sum(path_i) / len(path_i))
clustering.append(sum(clustering_i) / len(clustering_i))
內容解密:
這段程式碼計算了不同重新連線機率下,瓦特-史特加茲網路模型的平均最短路徑和平均叢集係數。它使用了 Watts-Strogatz 圖函式生成了具有 1000 個節點和 10 個鄰居的網路,並計算了每個網路的平均最短路徑和平均叢集係數。然後,它將這些值平均起來,以得到每個重新連線機率下的平均值。
簡單傳染模型
簡單傳染模型是一種社交過程,其中每個個體在單次接觸後就會被感染。簡單傳染模型可以用於模擬高度傳染性的疾病或無爭議資訊的傳播。
def propagate_simple(G):
to_infect = set([])
for v in G.nodes():
if G.nodes[v]['infected'] == False:
for w in nx.neighbors(G, v):
if G.nodes[w]['infected']:
to_infect.add(v)
break
for v in to_infect:
G.nodes[v]['infected'] = True
內容解密:
這段程式碼定義了一個名為 propagate_simple 的函式,該函式模擬了簡單傳染模型的單一步驟。它首先找到所有未被感染的節點,然後檢查它們的鄰居是否被感染。如果鄰居被感染,則將該節點標記為待感染。最後,它將所有待感染的節點感染。
第9章:模擬與分析
網路結構與網路系統中發生的過程密切相關。不同的過程創造不同的結構,而不同的結構則影響網路過程。模擬可用於生成合成網路。這些網路可用於研究真實系統中結構如何形成。真實或合成網路也可用於模擬在這些網路上發生的過程,以瞭解結構對這些過程的影響。本章介紹了幾種常見的合成網路模型,以及使用根據代理的建模模擬網路過程的範例。
本章涵蓋以下主題:
- Watts-Strogatz 網路:透過向區域性叢集網路新增隨機捷徑來模擬小世界。
- 優先連線:解釋富者愈富如何創造無標度重尾分佈網路。
- 組態模型:如何建立模擬真實資料屬性的合成網路。
- 根據代理的模型:如何在網路中模擬行為和過程。
Watts-Strogatz 與小世界
小世界問題(在第8章《社交網路與病毒式傳播》中討論)詢問,即使每個人的連線都是區域性的,遠距離的人如何透過短路徑相連。Duncan Watts 和 Steven Strogatz(1998)開發了一類別網路來解釋這種行為。這些網路首先是 k-環形網路:節點圍成一個圓圈,每個節點與其最近的 k 個鄰居相連。然後,以機率 p,每個節點的邊被移動到一個隨機選擇的其他節點。這些重新連線建立了跨網路的捷徑。即使是少量的捷徑也能大大減少網路中節點之間的距離,從而解決小世界問題。
Watts-Strogatz 網路模擬範例
import networkx as nx
import matplotlib.pyplot as plt
# 建立 Watts-Strogatz 圖
G = nx.watts_strogatz_graph(16, 4, 0.2)
# 繪製網路圖
pos = nx.circular_layout(G)
nx.draw_networkx(G, pos)
plt.title("Watts-Strogatz 網路範例")
plt.show()
程式碼解析:
- 匯入必要的函式庫:
networkx用於建立和操作複雜網路,matplotlib.pyplot用於繪圖。 - 使用
watts_strogatz_graph函式建立一個具有 16 個節點、每個節點初始連線到最近的 4 個鄰居、以機率 0.2 重新連線邊的 Watts-Strogatz 圖。 - 使用
circular_layout將節點擺放成圓形,並繪製網路圖。
優先連線與無標度網路
在許多真實世界的網路中,節點的度分佈遵循無標度(scale-free)特性,即少數節點具有非常多的連線,而大多數節點只有很少的連線。這種現象通常由優先連線(preferential attachment)機制解釋,即新節點傾向於連線到已經具有較多連線的節點。
優先連線範例程式碼
# 建立 Barabási-Albert 圖(優先連線模型)
G = nx.barabasi_albert_graph(100, 2)
# 繪製度分佈
degree_sequence = sorted([d for n, d in G.degree()], reverse=True)
plt.bar(range(len(degree_sequence)), degree_sequence)
plt.title("優先連線網路的度分佈")
plt.xlabel("節點")
plt.ylabel("度")
plt.show()
程式碼解析:
- 使用
barabasi_albert_graph函式建立一個具有 100 個節點、每次新增節點連線 2 個現有節點的 Barabási-Albert 圖(優先連線模型)。 - 計算並繪製網路的度分佈,以觀察無標度特性。
組態模型
組態模型是一種用於生成具有特定度序列的隨機網路的方法。這對於研究具有特定結構特性的網路非常有用。
根據代理的模型
根據代理的建模是一種模擬方法,用於研究由自主決策的代理(agents)構成的系統中的宏觀現象。它可以用於模擬在網路上發生的各種過程,如資訊傳播、疾病傳播等。
本章重點回顧:
- Watts-Strogatz 模型能夠生成具有小世界特性的網路,即高叢集係數和短平均路徑長度。
- 優先連線模型能夠生成無標度網路,解釋了許多真實世界網路中觀察到的冪律度分佈。
- 組態模型提供了一種生成具有特定度序列的隨機網路的方法,用於研究特定結構特性的影響。
- 根據代理的建模是一種強大的工具,用於模擬和分析在複雜網路上發生的各種動態過程。