使用NetworkX计算特征向量中心性

时间:2013-01-28 13:47:33

标签: networkx eigenvector

我正在使用NetworkX库来处理一些表示Web 2.0站点使用情况的中小型未加权,无符号有向图(最小图:少于24个节点,最大:几千个)。我想要计算的一件事是特征向量中心性,如下:

>>> eig = networkx.eigenvector_centrality(my_graph)
>>> eigs = [(v,k) for k,v in eig.iteritems()]
>>> eigs.sort()
>>> eigs.reverse() 

然而,这给出了意想不到的结果:具有0 outdegree但从非常中心节点接收内向弧的节点出现在列表的最后面,具有0.0特征向量中心性(不是数学家,我可能已经弄得很混乱,但我不是'我认为外向弧应该对节点对有向图的中心性产生任何影响。在调查这些结果的过程中,我从文档中注意到NetworkX默认计算“正确的”特征向量中心性;出于好奇,我决定用推荐的方法计算“左”特征向量中心性,即在计算特征向量中心性(see Networkx documentation)之前反转图形。令我惊讶的是,我得到了完全相同的结果:每个节点都被计算为具有与以前完全相同的特征向量中心性。我认为这应该是一个非常不可能的结果(see Wikipedia article),但我已经将其与我正在使用的所有图表一起复制了。谁能向我解释我做错了什么?

N.B。使用PageRank算法的NetworkX实现提供了我期望的结果,即从非常中心节点接收内向弧的节点具有高中心性,即使它们的outdegree为0. PageRank通常被认为是特征向量中心性的变体({{3} })。

编辑:根据Aric的请求,我已经包含了一些数据。这是我最小图的匿名版本。 (我不能发布玩具数据,以防问题特定于我的图形结构。)在我的机器上运行下面的代码(使用Python 2.7)似乎表明(a)每个节点的左右特征向量中心性是同样,并且(b)具有outdegree 0 的节点总是也具有特征向量中心0,即使它们作为整体(例如节点61)对图形来说是非常重要的。

import networkx

anon_e_list = [(10, 59), (10, 15), (10, 61), (15, 32), (16, 31), (16, 0), (16, 37), (16, 54), (16, 45), (16, 56), (16, 10), (16, 8), (16, 36), (16, 24), (16, 30), (18, 34), (18, 36), (18, 30), (19, 1), (19, 3), (19, 51), (19, 21), (19, 40), (19, 41), (19, 30), (19, 14), (19, 61), (21, 64), (26, 1), (31, 1), (31, 3), (31, 51), (31, 62), (31, 33), (31, 40), (31, 23), (31, 30), (31, 18), (31, 13), (31, 46), (31, 61), (32, 3), (32, 2), (32, 33), (32, 6), (32, 7), (32, 9), (32, 15), (32, 17), (32, 18), (32, 23), (32, 30), (32, 5), (32, 27), (32, 34), (32, 35), (32, 38), (32, 40), (32, 42), (32, 43), (32, 46), (32, 47), (32, 62), (32, 56), (32, 57), (32, 59), (32, 64), (32, 61), (33, 0), (33, 31), (33, 2), (33, 7), (33, 9), (33, 10), (33, 12), (33, 64), (33, 14), (33, 46), (33, 16), (33, 17), (33, 18), (33, 19), (33, 20), (33, 21), (33, 22), (33, 23), (33, 30), (33, 26), (33, 28), (33, 11), (33, 34), (33, 32), (33, 35), (33, 37), (33, 38), (33, 39), (33, 41), (33, 43), (33, 45), (33, 24), (33, 47), (33, 48), (33, 49), (33, 58), (33, 62), (33, 53), (33, 54), (33, 55), (33, 60), (33, 57), (33, 59), (33, 5), (33, 52), (33, 63), (33, 61), (34, 58), (34, 4), (34, 33), (34, 20), (34, 55), (34, 28), (34, 11), (34, 64), (35, 18), (35, 60), (35, 61), (37, 34), (37, 48), (37, 49), (37, 18), (37, 33), (37, 39), (37, 21), (37, 42), (37, 26), (37, 59), (37, 44), (37, 12), (37, 11), (37, 61), (41, 3), (41, 50), (41, 18), (41, 52), (41, 33), (41, 54), (41, 19), (41, 22), (41, 5), (41, 46), (41, 25), (41, 44), (41, 13), (41, 62), (41, 29), (44, 32), (44, 3), (44, 18), (44, 33), (44, 40), (44, 41), (44, 30), (44, 23), (44, 61), (50, 17), (50, 37), (50, 62), (50, 41), (50, 25), (50, 43), (50, 27), (50, 28), (50, 29), (54, 33), (54, 41), (54, 10), (54, 59), (54, 63), (54, 61), (58, 62), (58, 46), (59, 31), (59, 34), (59, 30), (59, 49), (59, 18), (59, 33), (59, 9), (59, 10), (59, 8), (59, 13), (59, 24), (59, 61), (60, 34), (60, 16), (60, 35), (60, 50), (60, 4), (60, 6), (60, 59), (60, 24), (63, 40), (63, 33), (63, 30), (63, 61), (63, 53)]

my_graph = networkx.DiGraph()
my_graph.add_edges_from(anon_e_list)
r_eig = networkx.eigenvector_centrality(my_graph)
my_graph2 = my_graph.reverse()
l_eig = networkx.eigenvector_centrality(my_graph2)

for nd in my_graph.nodes():
    print 'node: {} indegree: {} outdegree: {} right eig: {} left eig: {}'.format(nd,my_graph.in_degree(nd),my_graph.out_degree(nd),r_eig[nd],l_eig[nd])

1 个答案:

答案 0 :(得分:4)

这两行

my_graph2 = my_graph.copy()
my_graph2.reverse()

应替换为

my_graph2 = my_graph.reverse()

因为默认情况下reverse()方法会返回图形的副本。