Example06 / 15
中心性家族在同一网络上的比较
在空手道网络(无权)上计算 8 种中心性:度、接近、调和接近、介数、特征向量、Katz、PageRank、k 核数, 列出各指标排名前 5 的节点,并计算它们两两之间的 Spearman 秩相关。 先用两个可手算的小图核对定义:星形图中心的归一化介数为 1;路径图 1-2-3-4-5 中节点 3 的介数为 4。 输出:多数指标都把节点 0、33 排在前列,但第 3–5 名各不相同(k 核数有大量并列,前 5 名只是并列者之一); 与度的秩相关在 0.78–0.98 之间,说明各指标高度相关却不可互换,选哪一个取决于研究问题。
Output输出图

Output文字输出
星形图中心介数(归一化)= 1.0 ;叶子接近中心性 = 0.571(手算 4/7=0.571)
路径图未归一化介数: {1: 0.0, 2: 3.0, 3: 4.0, 4: 3.0, 5: 0.0}
最大特征值 λ1 = 6.726,Katz 取 α = 0.5/λ1 = 0.0743
degree 前 5: [33, 0, 32, 2, 1]
closeness 前 5: [0, 2, 33, 31, 8]
harmonic 前 5: [33, 0, 2, 32, 31]
betweenness 前 5: [0, 33, 32, 2, 31]
eigenvector 前 5: [33, 0, 2, 32, 1]
katz 前 5: [33, 0, 32, 2, 1]
pagerank 前 5: [33, 0, 32, 2, 1]
k-core 前 5: [0, 1, 2, 3, 7]
与度中心性的 Spearman 秩相关:
degree 1.00
closeness 0.89
harmonic 0.87
betweenness 0.90
eigenvector 0.78
katz 0.93
pagerank 0.98
k-core 0.93Code代码
# 在空手道网络(无权)上计算 8 种中心性:度、接近、调和接近、介数、特征向量、Katz、PageRank、k 核数,
# 列出各指标排名前 5 的节点,并计算它们两两之间的 Spearman 秩相关。
# 先用两个可手算的小图核对定义:星形图中心的归一化介数为 1;路径图 1-2-3-4-5 中节点 3 的介数为 4。
# 输出:多数指标都把节点 0、33 排在前列,但第 3–5 名各不相同(k 核数有大量并列,前 5 名只是并列者之一);
# 与度的秩相关在 0.78–0.98 之间,说明各指标高度相关却不可互换,选哪一个取决于研究问题。
import networkx as nx
import numpy as np
from scipy.stats import spearmanr
star = nx.star_graph(4) # 中心 0 + 4 个叶子
path = nx.path_graph([1, 2, 3, 4, 5])
print("星形图中心介数(归一化)=", nx.betweenness_centrality(star)[0],
";叶子接近中心性 = %.3f(手算 4/7=%.3f)" % (nx.closeness_centrality(star)[1], 4 / 7))
print("路径图未归一化介数:", nx.betweenness_centrality(path, normalized=False))
G = nx.karate_club_graph()
lam1 = max(np.linalg.eigvalsh(nx.to_numpy_array(G, weight=None)))
C = {
"degree": nx.degree_centrality(G),
"closeness": nx.closeness_centrality(G),
"harmonic": nx.harmonic_centrality(G),
"betweenness": nx.betweenness_centrality(G),
"eigenvector": nx.eigenvector_centrality_numpy(G, weight=None),
"katz": nx.katz_centrality_numpy(G, alpha=0.5 / lam1, beta=1.0, weight=None),
"pagerank": nx.pagerank(G, alpha=0.85, weight=None),
"k-core": nx.core_number(G),
}
print("最大特征值 λ1 = %.3f,Katz 取 α = 0.5/λ1 = %.4f" % (lam1, 0.5 / lam1))
for name, c in C.items():
print("%-12s 前 5: %s" % (name, sorted(c, key=c.get, reverse=True)[:5]))
names = list(C)
X = np.array([[C[m][i] for i in G] for m in names])
rho = spearmanr(X.T).correlation
print("\n与度中心性的 Spearman 秩相关:")
for m, r in zip(names, rho[0]):
print(" %-12s %.2f" % (m, r))
# 作图:8 种中心性两两之间的 Spearman 秩相关热图
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(6.4, 5.2))
im = ax.imshow(rho, cmap="RdBu_r", vmin=-1, vmax=1)
for i in range(len(names)):
for j in range(len(names)):
ax.text(j, i, "%.2f" % rho[i, j], ha="center", va="center", fontsize=8,
color="white" if rho[i, j] > 0.8 else "black")
ax.set_xticks(range(len(names))); ax.set_xticklabels(names, rotation=45, ha="right")
ax.set_yticks(range(len(names))); ax.set_yticklabels(names)
fig.colorbar(im, ax=ax, label="Spearman rho")
ax.set_title("Centralities correlate but are not interchangeable", fontsize=10)
plt.tight_layout(); plt.show()Run在浏览器中运行
首次加载 Python 环境约需 20–40 秒;可以修改参数后重新运行。