non_randomness.py 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. r""" Computation of graph non-randomness
  2. """
  3. import math
  4. import networkx as nx
  5. from networkx.utils import not_implemented_for
  6. __all__ = ["non_randomness"]
  7. @not_implemented_for("directed")
  8. @not_implemented_for("multigraph")
  9. def non_randomness(G, k=None, weight="weight"):
  10. """Compute the non-randomness of graph G.
  11. The first returned value nr is the sum of non-randomness values of all
  12. edges within the graph (where the non-randomness of an edge tends to be
  13. small when the two nodes linked by that edge are from two different
  14. communities).
  15. The second computed value nr_rd is a relative measure that indicates
  16. to what extent graph G is different from random graphs in terms
  17. of probability. When it is close to 0, the graph tends to be more
  18. likely generated by an Erdos Renyi model.
  19. Parameters
  20. ----------
  21. G : NetworkX graph
  22. Graph must be symmetric, connected, and without self-loops.
  23. k : int
  24. The number of communities in G.
  25. If k is not set, the function will use a default community
  26. detection algorithm to set it.
  27. weight : string or None, optional (default=None)
  28. The name of an edge attribute that holds the numerical value used
  29. as a weight. If None, then each edge has weight 1, i.e., the graph is
  30. binary.
  31. Returns
  32. -------
  33. non-randomness : (float, float) tuple
  34. Non-randomness, Relative non-randomness w.r.t.
  35. Erdos Renyi random graphs.
  36. Raises
  37. ------
  38. NetworkXException
  39. if the input graph is not connected.
  40. NetworkXError
  41. if the input graph contains self-loops.
  42. Examples
  43. --------
  44. >>> G = nx.karate_club_graph()
  45. >>> nr, nr_rd = nx.non_randomness(G, 2)
  46. >>> nr, nr_rd = nx.non_randomness(G, 2, 'weight')
  47. Notes
  48. -----
  49. This computes Eq. (4.4) and (4.5) in Ref. [1]_.
  50. If a weight field is passed, this algorithm will use the eigenvalues
  51. of the weighted adjacency matrix to compute Eq. (4.4) and (4.5).
  52. References
  53. ----------
  54. .. [1] Xiaowei Ying and Xintao Wu,
  55. On Randomness Measures for Social Networks,
  56. SIAM International Conference on Data Mining. 2009
  57. """
  58. import numpy as np
  59. if not nx.is_connected(G):
  60. raise nx.NetworkXException("Non connected graph.")
  61. if len(list(nx.selfloop_edges(G))) > 0:
  62. raise nx.NetworkXError("Graph must not contain self-loops")
  63. if k is None:
  64. k = len(tuple(nx.community.label_propagation_communities(G)))
  65. # eq. 4.4
  66. eigenvalues = np.linalg.eigvals(nx.to_numpy_array(G, weight=weight))
  67. nr = np.real(np.sum(eigenvalues[:k]))
  68. n = G.number_of_nodes()
  69. m = G.number_of_edges()
  70. p = (2 * k * m) / (n * (n - k))
  71. # eq. 4.5
  72. nr_rd = (nr - ((n - 2 * k) * p + k)) / math.sqrt(2 * k * p * (1 - p))
  73. return nr, nr_rd