bethehessianmatrix.py 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. """Bethe Hessian or deformed Laplacian matrix of graphs."""
  2. import networkx as nx
  3. from networkx.utils import not_implemented_for
  4. __all__ = ["bethe_hessian_matrix"]
  5. @not_implemented_for("directed")
  6. @not_implemented_for("multigraph")
  7. def bethe_hessian_matrix(G, r=None, nodelist=None):
  8. r"""Returns the Bethe Hessian matrix of G.
  9. The Bethe Hessian is a family of matrices parametrized by r, defined as
  10. H(r) = (r^2 - 1) I - r A + D where A is the adjacency matrix, D is the
  11. diagonal matrix of node degrees, and I is the identify matrix. It is equal
  12. to the graph laplacian when the regularizer r = 1.
  13. The default choice of regularizer should be the ratio [2]_
  14. .. math::
  15. r_m = \left(\sum k_i \right)^{-1}\left(\sum k_i^2 \right) - 1
  16. Parameters
  17. ----------
  18. G : Graph
  19. A NetworkX graph
  20. r : float
  21. Regularizer parameter
  22. nodelist : list, optional
  23. The rows and columns are ordered according to the nodes in nodelist.
  24. If nodelist is None, then the ordering is produced by ``G.nodes()``.
  25. Returns
  26. -------
  27. H : scipy.sparse.csr_array
  28. The Bethe Hessian matrix of `G`, with parameter `r`.
  29. Examples
  30. --------
  31. >>> k = [3, 2, 2, 1, 0]
  32. >>> G = nx.havel_hakimi_graph(k)
  33. >>> H = nx.bethe_hessian_matrix(G)
  34. >>> H.toarray()
  35. array([[ 3.5625, -1.25 , -1.25 , -1.25 , 0. ],
  36. [-1.25 , 2.5625, -1.25 , 0. , 0. ],
  37. [-1.25 , -1.25 , 2.5625, 0. , 0. ],
  38. [-1.25 , 0. , 0. , 1.5625, 0. ],
  39. [ 0. , 0. , 0. , 0. , 0.5625]])
  40. See Also
  41. --------
  42. bethe_hessian_spectrum
  43. adjacency_matrix
  44. laplacian_matrix
  45. References
  46. ----------
  47. .. [1] A. Saade, F. Krzakala and L. Zdeborová
  48. "Spectral Clustering of Graphs with the Bethe Hessian",
  49. Advances in Neural Information Processing Systems, 2014.
  50. .. [2] C. M. Le, E. Levina
  51. "Estimating the number of communities in networks by spectral methods"
  52. arXiv:1507.00827, 2015.
  53. """
  54. import scipy as sp
  55. import scipy.sparse # call as sp.sparse
  56. if nodelist is None:
  57. nodelist = list(G)
  58. if r is None:
  59. r = sum(d**2 for v, d in nx.degree(G)) / sum(d for v, d in nx.degree(G)) - 1
  60. A = nx.to_scipy_sparse_array(G, nodelist=nodelist, format="csr")
  61. n, m = A.shape
  62. # TODO: Rm csr_array wrapper when spdiags array creation becomes available
  63. D = sp.sparse.csr_array(sp.sparse.spdiags(A.sum(axis=1), 0, m, n, format="csr"))
  64. # TODO: Rm csr_array wrapper when eye array creation becomes available
  65. I = sp.sparse.csr_array(sp.sparse.eye(m, n, format="csr"))
  66. return (r**2 - 1) * I - r * A + D