test_quality.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. """Unit tests for the :mod:`networkx.algorithms.community.quality`
  2. module.
  3. """
  4. import pytest
  5. import networkx as nx
  6. from networkx import barbell_graph
  7. from networkx.algorithms.community import modularity, partition_quality
  8. from networkx.algorithms.community.quality import inter_community_edges
  9. class TestPerformance:
  10. """Unit tests for the :func:`performance` function."""
  11. def test_bad_partition(self):
  12. """Tests that a poor partition has a low performance measure."""
  13. G = barbell_graph(3, 0)
  14. partition = [{0, 1, 4}, {2, 3, 5}]
  15. assert 8 / 15 == pytest.approx(partition_quality(G, partition)[1], abs=1e-7)
  16. def test_good_partition(self):
  17. """Tests that a good partition has a high performance measure."""
  18. G = barbell_graph(3, 0)
  19. partition = [{0, 1, 2}, {3, 4, 5}]
  20. assert 14 / 15 == pytest.approx(partition_quality(G, partition)[1], abs=1e-7)
  21. class TestCoverage:
  22. """Unit tests for the :func:`coverage` function."""
  23. def test_bad_partition(self):
  24. """Tests that a poor partition has a low coverage measure."""
  25. G = barbell_graph(3, 0)
  26. partition = [{0, 1, 4}, {2, 3, 5}]
  27. assert 3 / 7 == pytest.approx(partition_quality(G, partition)[0], abs=1e-7)
  28. def test_good_partition(self):
  29. """Tests that a good partition has a high coverage measure."""
  30. G = barbell_graph(3, 0)
  31. partition = [{0, 1, 2}, {3, 4, 5}]
  32. assert 6 / 7 == pytest.approx(partition_quality(G, partition)[0], abs=1e-7)
  33. def test_modularity():
  34. G = nx.barbell_graph(3, 0)
  35. C = [{0, 1, 4}, {2, 3, 5}]
  36. assert (-16 / (14**2)) == pytest.approx(modularity(G, C), abs=1e-7)
  37. C = [{0, 1, 2}, {3, 4, 5}]
  38. assert (35 * 2) / (14**2) == pytest.approx(modularity(G, C), abs=1e-7)
  39. n = 1000
  40. G = nx.erdos_renyi_graph(n, 0.09, seed=42, directed=True)
  41. C = [set(range(n // 2)), set(range(n // 2, n))]
  42. assert 0.00017154251389292754 == pytest.approx(modularity(G, C), abs=1e-7)
  43. G = nx.margulis_gabber_galil_graph(10)
  44. mid_value = G.number_of_nodes() // 2
  45. nodes = list(G.nodes)
  46. C = [set(nodes[:mid_value]), set(nodes[mid_value:])]
  47. assert 0.13 == pytest.approx(modularity(G, C), abs=1e-7)
  48. G = nx.DiGraph()
  49. G.add_edges_from([(2, 1), (2, 3), (3, 4)])
  50. C = [{1, 2}, {3, 4}]
  51. assert 2 / 9 == pytest.approx(modularity(G, C), abs=1e-7)
  52. def test_modularity_resolution():
  53. G = nx.barbell_graph(3, 0)
  54. C = [{0, 1, 4}, {2, 3, 5}]
  55. assert modularity(G, C) == pytest.approx(3 / 7 - 100 / 14**2)
  56. gamma = 2
  57. result = modularity(G, C, resolution=gamma)
  58. assert result == pytest.approx(3 / 7 - gamma * 100 / 14**2)
  59. gamma = 0.2
  60. result = modularity(G, C, resolution=gamma)
  61. assert result == pytest.approx(3 / 7 - gamma * 100 / 14**2)
  62. C = [{0, 1, 2}, {3, 4, 5}]
  63. assert modularity(G, C) == pytest.approx(6 / 7 - 98 / 14**2)
  64. gamma = 2
  65. result = modularity(G, C, resolution=gamma)
  66. assert result == pytest.approx(6 / 7 - gamma * 98 / 14**2)
  67. gamma = 0.2
  68. result = modularity(G, C, resolution=gamma)
  69. assert result == pytest.approx(6 / 7 - gamma * 98 / 14**2)
  70. G = nx.barbell_graph(5, 3)
  71. C = [frozenset(range(5)), frozenset(range(8, 13)), frozenset(range(5, 8))]
  72. gamma = 1
  73. result = modularity(G, C, resolution=gamma)
  74. # This C is maximal for gamma=1: modularity = 0.518229
  75. assert result == pytest.approx((22 / 24) - gamma * (918 / (48**2)))
  76. gamma = 2
  77. result = modularity(G, C, resolution=gamma)
  78. assert result == pytest.approx((22 / 24) - gamma * (918 / (48**2)))
  79. gamma = 0.2
  80. result = modularity(G, C, resolution=gamma)
  81. assert result == pytest.approx((22 / 24) - gamma * (918 / (48**2)))
  82. C = [{0, 1, 2, 3}, {9, 10, 11, 12}, {5, 6, 7}, {4}, {8}]
  83. gamma = 1
  84. result = modularity(G, C, resolution=gamma)
  85. assert result == pytest.approx((14 / 24) - gamma * (598 / (48**2)))
  86. gamma = 2.5
  87. result = modularity(G, C, resolution=gamma)
  88. # This C is maximal for gamma=2.5: modularity = -0.06553819
  89. assert result == pytest.approx((14 / 24) - gamma * (598 / (48**2)))
  90. gamma = 0.2
  91. result = modularity(G, C, resolution=gamma)
  92. assert result == pytest.approx((14 / 24) - gamma * (598 / (48**2)))
  93. C = [frozenset(range(8)), frozenset(range(8, 13))]
  94. gamma = 1
  95. result = modularity(G, C, resolution=gamma)
  96. assert result == pytest.approx((23 / 24) - gamma * (1170 / (48**2)))
  97. gamma = 2
  98. result = modularity(G, C, resolution=gamma)
  99. assert result == pytest.approx((23 / 24) - gamma * (1170 / (48**2)))
  100. gamma = 0.3
  101. result = modularity(G, C, resolution=gamma)
  102. # This C is maximal for gamma=0.3: modularity = 0.805990
  103. assert result == pytest.approx((23 / 24) - gamma * (1170 / (48**2)))
  104. def test_inter_community_edges_with_digraphs():
  105. G = nx.complete_graph(2, create_using=nx.DiGraph())
  106. partition = [{0}, {1}]
  107. assert inter_community_edges(G, partition) == 2
  108. G = nx.complete_graph(10, create_using=nx.DiGraph())
  109. partition = [{0}, {1, 2}, {3, 4, 5}, {6, 7, 8, 9}]
  110. assert inter_community_edges(G, partition) == 70
  111. G = nx.cycle_graph(4, create_using=nx.DiGraph())
  112. partition = [{0, 1}, {2, 3}]
  113. assert inter_community_edges(G, partition) == 2