3. 节点中心性特征:度中心性、介数中心性、接近中心性、特征向量中心性
图特征工程里,节点中心性是个绕不开的话题。说白了,就是给图中的每个节点打分,衡量它有多「重要」。但「重要」这个词太模糊了——是连接的人多?还是处在交通要道上?还是离谁都近?不同的场景,答案完全不同。
我个人习惯把中心性分成四类来理解,它们各自捕捉了节点重要性的不同侧面。下面我们一个一个来看。
3.1 度中心性(Degree Centrality)
这是最直观的一种。一个节点连接的边越多,它的度中心性就越高。在无向图中,就是邻居的数量;在有向图中,还可以拆成入度和出度。
公式很简单:
度中心性 = 节点的度数 / (节点总数 - 1)
为什么要除以 N-1?是为了归一化,让不同规模的图可以比较。比如一个1000个节点的图里,度数为50的节点,和10个节点图里度数为5的节点,其实重要性差不多。
3.2 介数中心性(Betweenness Centrality)
介数中心性衡量的是「一个节点出现在多少条最短路径上」。你可以把它想象成交通枢纽——虽然你认识的人不多,但所有人从A到B都得经过你,那你就是关键节点。
计算公式:
介数中心性 = Σ (经过节点v的最短路径数量 / 所有节点对之间的最短路径总数)
这个指标在通信网络、物流网络中特别有用。我曾经帮一个电商平台做配送网络优化,发现某个仓库的介数中心性极高,所有订单都得经过它中转。结果那个仓库一宕机,整个区域配送瘫痪。后来我们加了备用节点,问题才解决。
3.3 接近中心性(Closeness Centrality)
接近中心性看的是「一个节点到其他所有节点的平均距离」。距离越短,中心性越高。说白了,就是谁离大家最近。
公式:
接近中心性 = (节点总数 - 1) / Σ(节点v到其他节点的最短距离)
这个指标在信息传播场景中很实用。比如在社交网络中,接近中心性高的人,发一条消息能更快传遍全网。我做过一个舆情传播分析,发现意见领袖的接近中心性普遍比普通用户高30%以上。
但要注意,接近中心性要求图是连通的。如果图不连通,有些节点之间没有路径,距离就是无穷大。这时候可以用调和中心性(Harmonic Centrality)来替代。
3.4 特征向量中心性(Eigenvector Centrality)
这个指标有点意思。它认为:一个节点的重要性,不仅取决于它连接了多少人,还取决于它连接的人有多重要。你认识马云,比你认识100个普通人更有价值。
数学上,它是通过邻接矩阵的特征向量来计算的。简单说,就是给每个节点赋一个分数,然后迭代更新:
特征向量中心性 = 邻接矩阵 × 当前中心性向量
然后归一化,重复直到收敛
PageRank算法就是特征向量中心性的一个变种。我记得在做一个推荐系统时,用特征向量中心性来识别核心用户,效果比度中心性好很多——虽然有些用户粉丝不多,但粉丝都是高活跃用户,推荐转化率反而更高。
- 度中心性:看数量,谁朋友多
- 介数中心性:看位置,谁在关键路径上
- 接近中心性:看距离,谁离大家近
- 特征向量中心性:看质量,谁认识重要的人
3.5 四种中心性的对比与选择
实际项目中,选哪个中心性取决于你的业务场景。我整理了一个表格,方便你快速决策:
| 中心性类型 | 计算复杂度 | 适用场景 | 注意事项 |
|---|---|---|---|
| 度中心性 | O(N) | 社交网络、推荐系统 | 容易被刷量,需结合其他指标 |
| 介数中心性 | O(N^3) | 通信网络、物流网络 | 大规模图需用近似算法 |
| 接近中心性 | O(N^2 log N) | 信息传播、舆情分析 | 要求图连通,否则用调和中心性 |
| 特征向量中心性 | O(N^2) | 影响力分析、PageRank | 迭代计算,需设置收敛阈值 |
3.6 知识体系结构图
下面我用一张SVG图来展示这四种中心性的核心逻辑和关系,方便你整体把握:
3.7 代码实战:用NetworkX计算四种中心性
理论说完了,来点实际的。我用Python的NetworkX库演示一下如何计算这四种中心性。代码很简单,但背后逻辑值得琢磨。
import networkx as nx
import matplotlib.pyplot as plt
# 创建一个示例图
G = nx.karate_club_graph() # 经典的Zachary空手道俱乐部图
# 计算四种中心性
degree_centrality = nx.degree_centrality(G)
betweenness_centrality = nx.betweenness_centrality(G)
closeness_centrality = nx.closeness_centrality(G)
eigenvector_centrality = nx.eigenvector_centrality(G, max_iter=1000)
# 打印前5个节点的结果
print("节点 | 度中心性 | 介数中心性 | 接近中心性 | 特征向量中心性")
print("-" * 70)
for node in list(G.nodes())[:5]:
print(f"{node:4} | {degree_centrality[node]:.4f} | {betweenness_centrality[node]:.4f} | "
f"{closeness_centrality[node]:.4f} | {eigenvector_centrality[node]:.4f}")
# 输出示例:
# 节点 | 度中心性 | 介数中心性 | 接近中心性 | 特征向量中心性
# ----------------------------------------------------------------------
# 0 | 0.4848 | 0.4376 | 0.5698 | 0.3734
# 1 | 0.3333 | 0.0521 | 0.5294 | 0.2445
# 2 | 0.3030 | 0.1436 | 0.5294 | 0.2732
# 3 | 0.1818 | 0.0120 | 0.4737 | 0.1290
# 4 | 0.0909 | 0.0000 | 0.4091 | 0.0787
嗯,到这里四种中心性就讲完了。你可能会问:这么多指标,到底用哪个?我的答案是:都试试,让数据说话。不同场景下,不同中心性的表现差异很大。多跑几个实验,你就知道哪个指标对你的任务最敏感了。