我正在尝试使用networkx来计算图表的特征向量中心性:
import networkx as nx
import pandas as pd
import numpy as np
a = nx.eigenvector_centrality(my_graph)
但我收到错误:
NetworkXError: eigenvector_centrality():
power iteration failed to converge in %d iterations."%(i+1))
我的图表有什么问题?
答案 0 :(得分:7)
TL / DR:尝试nx.eigenvector_centrality_numpy
。
以下是正在发生的事情:nx.eigenvector_centrality
依赖于电源迭代。它所采取的动作相当于将矢量重复乘以相同的矩阵(然后对结果进行归一化)。这通常会收敛到最大的特征向量。然而,当存在具有相同(最大)幅度的多个特征值时,失败。
您的图表是星形图。星图有多个“最大”特征值。对于只有两个“外围节点”的星形,您可以轻松检查sqrt(2)
和-sqrt(2)
是否都是特征值。更一般地,sqrt(N)
和-sqrt(N)
都是特征值,而其他特征值的幅度较小。我相信适用于任何双网网络,这种情况会发生,标准算法也会失败。
数学原因是在n轮迭代之后,解决方案看起来像是c_i lambda_i ^ n v_i / K_n的总和,其中c_i是取决于初始猜测的常数,lambda_i是第i个特征值,v_i是其特征向量和K是归一化因子(应用于总和中的所有项)。当存在显性特征值时,lambda_i ^ n / K_n对于显性特征值变为非零常数,而对于其他特征值变为0。
但是在你的情况下,你有两个同样大的特征值。较小特征值的贡献仍然为零。但是你留下了(c_1 lambda_1 ^ n v_1 + c_2 lambda_2 ^ n v_2)/ K_n。这不会收敛,因为lambda_2是负数。每次迭代时,都会从添加一些v_2的倍数到减去该倍数。
因此,networkx使用的简单eigenvalue_centrality
将无效。您可以改为使用nx.eigenvector_centrality_numpy
以便使用numpy。
注意:快速浏览一下文档,我不是100%肯定numpy算法保证是最大(正)特征值。它使用numpy算法来寻找特征向量,但我没有在文档中看到它保证它是主要的特征向量。大多数用于查找单个特征向量的算法都会产生显性特征向量,因此您可能没问题。
我们可以添加一张支票:
nx.eigenvector_centrality_numpy
返回所有正值,Perron-Frobenius定理就保证这对应于最大的特征值。