Search code examples
python-3.xnetworkxeigenvector

Different results in eigenvector centrality numpy


The following example gives different results obtained with eigenvector_centrality and eigenvector_centrality_numpy. Is there a way to make such calculation more robust? I'm using networkx 2.4, numpy 1.18.5 and scipy 1.5.0.

import numpy as np
import networkx as nx

AdjacencyMatrix = {
    0: {
        1: 0.6,
    },
    1: {
        2: 0,
        3: 0,
    },
    2: {
        4: 0.5,
        5: 0.5,
    },
    3: {
        6: 0.5,
        7: 0.5,
        8: 0.5,
    },
    4: {},
    5: {},
    6: {},
    7: {},
    8: {},
}

G = nx.DiGraph()

for nodeID in AdjacencyMatrix.keys():
    G.add_node(nodeID)

for k1 in AdjacencyMatrix.keys():
    for k2 in AdjacencyMatrix[k1]:
        weight = AdjacencyMatrix[k1][k2]
        split_factor = len(AdjacencyMatrix[k1])
        G.add_edge(k1, k2, weight=weight / split_factor, reciprocal=1.0 / (split_factor * weight) if weight != 0 else np.inf)

eigenvector_centrality = {v[0]: v[1] for v in sorted(nx.eigenvector_centrality(G.reverse() if G.is_directed() else G, max_iter=10000, weight="weight").items(), key=lambda x: x[1], reverse=True)}
print(eigenvector_centrality)

eigenvector_centrality_numpy = {v[0]: v[1] for v in sorted(nx.eigenvector_centrality_numpy(G.reverse() if G.is_directed() else G, max_iter=10000, weight="weight").items(), key=lambda x: x[1], reverse=True)}
print(eigenvector_centrality_numpy)

Here's my output:

{0: 0.6468489798823026, 3: 0.5392481399595738, 2: 0.5392481399595732, 1: 0.0012439403459275048, 4: 0.0012439403459275048, 5: 0.0012439403459275048, 6: 0.0012439403459275048, 7: 0.0012439403459275048, 8: 0.0012439403459275048}
{3: 0.9637027924175013, 0: 0.0031436862826891288, 6: 9.593026373266866e-11, 8: 3.5132785569658154e-11, 4: 1.2627565659784068e-11, 1: 9.433263632036004e-14, 7: -2.6958851817582286e-11, 5: -3.185304797703736e-11, 2: -0.26695888283266833}

Solution

  • edit - see the response by dshult. He's one of the main people who maintains/updates networkx.


    I think this may be a bug, but not the way you think. This graph is directed and acyclic. So for this graph, I don't think there is a nonzero eigenvalue.

    It looks like the algorithm seems to implicitly assume an undirected graph, or at least that if it's directed it has cycles. And I would expect the algorithm to break if there's no cycle.

    I'm going to encourage the networkx people to look at this in more detail.

    I'm actually surprised that it converges for the non-numpy version.