如何用Python从邻接矩阵构建多层网络并计算广义中心性?
Python构建多层网络并计算广义特征向量中心性解决方案
一、修复pymnet多层网络构建问题
你之前的pymnet代码无法正常生成多层网络的核心原因是:add_layer方法不能直接传入NetworkX图对象,需要手动映射节点并添加层内边。以下是修正后的完整构建代码:
import pymnet import networkx as nx # 初始化Multiplex网络(aspects=1对应单层维度的多层网络) # fullyInterconnected=True默认添加同一节点跨层的连接,不需要可设为False mnet = pymnet.MultilayerNetwork(aspects=1, fullyInterconnected=True) # 提取所有矩阵共享的节点集(假设matrix_1是pandas邻接矩阵) nodes = matrix_1.index.tolist() # 先把所有节点添加到每一层 for node in nodes: mnet.add_node(node, layer="layer_1") mnet.add_node(node, layer="layer_2") mnet.add_node(node, layer="layer_3") # 定义从邻接矩阵批量添加层内边的工具函数 def add_layer_edges(network, adj_matrix, layer_name): nx_graph = nx.convert_matrix.from_pandas_adjacency(adj_matrix) for u, v, _ in nx_graph.edges(data=True): # 无向边添加双向连接,如需有向可指定directed=True network.add_edge(u, v, layer=layer_name) # 为三个层分别添加边 add_layer_edges(mnet, matrix_1, "layer_1") add_layer_edges(mnet, matrix_2, "layer_2") add_layer_edges(mnet, matrix_3, "layer_3") # 验证网络结构 print(f"总节点数:{mnet.num_nodes}") print(f"总层数:{mnet.num_layers}")
执行以上代码后,你可以用pymnet.draw(mnet)生成可分析的多层网络可视化图。
二、计算多层广义特征向量中心性
方法1:使用pymnet内置函数
pymnet原生支持多层网络的广义特征向量中心性计算,通过eigenvector_centrality函数实现,核心参数gamma控制层间连接对中心性的影响权重:
# 计算广义特征向量中心性,gamma=1.0表示层间连接与层内边权重相当 centralities = pymnet.eigenvector_centrality(mnet, gamma=1.0) # 按节点+层输出结果 for node in nodes: print(f"节点 {node} 的中心性:") for layer in ["layer_1", "layer_2", "layer_3"]: print(f" {layer}: {centralities[(node, layer)]:.4f}")
方法2:手动构建超邻接矩阵计算(自定义性更强)
如果需要更灵活的权重配置(比如不同层赋予不同权重),可以手动构建多层网络的超邻接矩阵,再通过特征值分解计算中心性:
import numpy as np from scipy.linalg import eig num_nodes = len(nodes) num_layers = 3 gamma = 1.0 # 层间连接权重 # 初始化超邻接矩阵(大小为 节点数×层数 × 节点数×层数) super_adj = np.zeros((num_nodes * num_layers, num_nodes * num_layers)) # 填充层内边 layer_mats = [matrix_1.values, matrix_2.values, matrix_3.values] for i in range(num_layers): start = i * num_nodes end = (i + 1) * num_nodes super_adj[start:end, start:end] = layer_mats[i] # 添加跨层节点连接(同一节点在不同层之间的边) for node_idx in range(num_nodes): for i in range(num_layers): for j in range(num_layers): if i != j: super_adj[i*num_nodes + node_idx, j*num_nodes + node_idx] = gamma # 计算最大特征值对应的特征向量 vals, vecs = eig(super_adj) max_idx = np.argmax(vals.real) centrality_vec = vecs[:, max_idx].real # 整理为节点-层的中心性字典 centrality_dict = {} for i in range(num_layers): layer_name = f"layer_{i+1}" for node_idx, node in enumerate(nodes): centrality_dict[(node, layer_name)] = centrality_vec[i*num_nodes + node_idx]
三、可视化验证
用pymnet绘制构建好的多层网络,确认结构符合预期:
import matplotlib.pyplot as plt fig = plt.figure(figsize=(10, 8)) ax = fig.add_subplot(111) pymnet.draw(mnet, ax=ax, layout="spring", node_size=50, edge_width=0.5) plt.title("Multiplex Network Visualization") plt.show()
内容的提问来源于stack exchange,提问作者Daniel Alexsandrovich
相关产品推荐
相关产品推荐

