scikit-network 0.33.0__cp312-cp312-macosx_10_9_x86_64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of scikit-network might be problematic. Click here for more details.

Files changed (216) hide show
  1. scikit_network-0.33.0.dist-info/AUTHORS.rst +43 -0
  2. scikit_network-0.33.0.dist-info/LICENSE +34 -0
  3. scikit_network-0.33.0.dist-info/METADATA +517 -0
  4. scikit_network-0.33.0.dist-info/RECORD +216 -0
  5. scikit_network-0.33.0.dist-info/WHEEL +5 -0
  6. scikit_network-0.33.0.dist-info/top_level.txt +1 -0
  7. sknetwork/__init__.py +21 -0
  8. sknetwork/base.py +67 -0
  9. sknetwork/classification/__init__.py +8 -0
  10. sknetwork/classification/base.py +142 -0
  11. sknetwork/classification/base_rank.py +133 -0
  12. sknetwork/classification/diffusion.py +134 -0
  13. sknetwork/classification/knn.py +139 -0
  14. sknetwork/classification/metrics.py +205 -0
  15. sknetwork/classification/pagerank.py +66 -0
  16. sknetwork/classification/propagation.py +152 -0
  17. sknetwork/classification/tests/__init__.py +1 -0
  18. sknetwork/classification/tests/test_API.py +30 -0
  19. sknetwork/classification/tests/test_diffusion.py +77 -0
  20. sknetwork/classification/tests/test_knn.py +23 -0
  21. sknetwork/classification/tests/test_metrics.py +53 -0
  22. sknetwork/classification/tests/test_pagerank.py +20 -0
  23. sknetwork/classification/tests/test_propagation.py +24 -0
  24. sknetwork/classification/vote.cpython-312-darwin.so +0 -0
  25. sknetwork/classification/vote.pyx +56 -0
  26. sknetwork/clustering/__init__.py +8 -0
  27. sknetwork/clustering/base.py +172 -0
  28. sknetwork/clustering/kcenters.py +253 -0
  29. sknetwork/clustering/leiden.py +242 -0
  30. sknetwork/clustering/leiden_core.cpython-312-darwin.so +0 -0
  31. sknetwork/clustering/leiden_core.pyx +124 -0
  32. sknetwork/clustering/louvain.py +286 -0
  33. sknetwork/clustering/louvain_core.cpython-312-darwin.so +0 -0
  34. sknetwork/clustering/louvain_core.pyx +124 -0
  35. sknetwork/clustering/metrics.py +91 -0
  36. sknetwork/clustering/postprocess.py +66 -0
  37. sknetwork/clustering/propagation_clustering.py +104 -0
  38. sknetwork/clustering/tests/__init__.py +1 -0
  39. sknetwork/clustering/tests/test_API.py +38 -0
  40. sknetwork/clustering/tests/test_kcenters.py +60 -0
  41. sknetwork/clustering/tests/test_leiden.py +34 -0
  42. sknetwork/clustering/tests/test_louvain.py +129 -0
  43. sknetwork/clustering/tests/test_metrics.py +50 -0
  44. sknetwork/clustering/tests/test_postprocess.py +39 -0
  45. sknetwork/data/__init__.py +6 -0
  46. sknetwork/data/base.py +33 -0
  47. sknetwork/data/load.py +406 -0
  48. sknetwork/data/models.py +459 -0
  49. sknetwork/data/parse.py +644 -0
  50. sknetwork/data/test_graphs.py +84 -0
  51. sknetwork/data/tests/__init__.py +1 -0
  52. sknetwork/data/tests/test_API.py +30 -0
  53. sknetwork/data/tests/test_base.py +14 -0
  54. sknetwork/data/tests/test_load.py +95 -0
  55. sknetwork/data/tests/test_models.py +52 -0
  56. sknetwork/data/tests/test_parse.py +250 -0
  57. sknetwork/data/tests/test_test_graphs.py +29 -0
  58. sknetwork/data/tests/test_toy_graphs.py +68 -0
  59. sknetwork/data/timeout.py +38 -0
  60. sknetwork/data/toy_graphs.py +611 -0
  61. sknetwork/embedding/__init__.py +8 -0
  62. sknetwork/embedding/base.py +94 -0
  63. sknetwork/embedding/force_atlas.py +198 -0
  64. sknetwork/embedding/louvain_embedding.py +148 -0
  65. sknetwork/embedding/random_projection.py +135 -0
  66. sknetwork/embedding/spectral.py +141 -0
  67. sknetwork/embedding/spring.py +198 -0
  68. sknetwork/embedding/svd.py +359 -0
  69. sknetwork/embedding/tests/__init__.py +1 -0
  70. sknetwork/embedding/tests/test_API.py +49 -0
  71. sknetwork/embedding/tests/test_force_atlas.py +35 -0
  72. sknetwork/embedding/tests/test_louvain_embedding.py +33 -0
  73. sknetwork/embedding/tests/test_random_projection.py +28 -0
  74. sknetwork/embedding/tests/test_spectral.py +81 -0
  75. sknetwork/embedding/tests/test_spring.py +50 -0
  76. sknetwork/embedding/tests/test_svd.py +43 -0
  77. sknetwork/gnn/__init__.py +10 -0
  78. sknetwork/gnn/activation.py +117 -0
  79. sknetwork/gnn/base.py +181 -0
  80. sknetwork/gnn/base_activation.py +89 -0
  81. sknetwork/gnn/base_layer.py +109 -0
  82. sknetwork/gnn/gnn_classifier.py +305 -0
  83. sknetwork/gnn/layer.py +153 -0
  84. sknetwork/gnn/loss.py +180 -0
  85. sknetwork/gnn/neighbor_sampler.py +65 -0
  86. sknetwork/gnn/optimizer.py +164 -0
  87. sknetwork/gnn/tests/__init__.py +1 -0
  88. sknetwork/gnn/tests/test_activation.py +56 -0
  89. sknetwork/gnn/tests/test_base.py +75 -0
  90. sknetwork/gnn/tests/test_base_layer.py +37 -0
  91. sknetwork/gnn/tests/test_gnn_classifier.py +130 -0
  92. sknetwork/gnn/tests/test_layers.py +80 -0
  93. sknetwork/gnn/tests/test_loss.py +33 -0
  94. sknetwork/gnn/tests/test_neigh_sampler.py +23 -0
  95. sknetwork/gnn/tests/test_optimizer.py +43 -0
  96. sknetwork/gnn/tests/test_utils.py +41 -0
  97. sknetwork/gnn/utils.py +127 -0
  98. sknetwork/hierarchy/__init__.py +6 -0
  99. sknetwork/hierarchy/base.py +96 -0
  100. sknetwork/hierarchy/louvain_hierarchy.py +272 -0
  101. sknetwork/hierarchy/metrics.py +234 -0
  102. sknetwork/hierarchy/paris.cpython-312-darwin.so +0 -0
  103. sknetwork/hierarchy/paris.pyx +316 -0
  104. sknetwork/hierarchy/postprocess.py +350 -0
  105. sknetwork/hierarchy/tests/__init__.py +1 -0
  106. sknetwork/hierarchy/tests/test_API.py +24 -0
  107. sknetwork/hierarchy/tests/test_algos.py +34 -0
  108. sknetwork/hierarchy/tests/test_metrics.py +62 -0
  109. sknetwork/hierarchy/tests/test_postprocess.py +57 -0
  110. sknetwork/linalg/__init__.py +9 -0
  111. sknetwork/linalg/basics.py +37 -0
  112. sknetwork/linalg/diteration.cpython-312-darwin.so +0 -0
  113. sknetwork/linalg/diteration.pyx +47 -0
  114. sknetwork/linalg/eig_solver.py +93 -0
  115. sknetwork/linalg/laplacian.py +15 -0
  116. sknetwork/linalg/normalizer.py +86 -0
  117. sknetwork/linalg/operators.py +225 -0
  118. sknetwork/linalg/polynome.py +76 -0
  119. sknetwork/linalg/ppr_solver.py +170 -0
  120. sknetwork/linalg/push.cpython-312-darwin.so +0 -0
  121. sknetwork/linalg/push.pyx +71 -0
  122. sknetwork/linalg/sparse_lowrank.py +142 -0
  123. sknetwork/linalg/svd_solver.py +91 -0
  124. sknetwork/linalg/tests/__init__.py +1 -0
  125. sknetwork/linalg/tests/test_eig.py +44 -0
  126. sknetwork/linalg/tests/test_laplacian.py +18 -0
  127. sknetwork/linalg/tests/test_normalization.py +34 -0
  128. sknetwork/linalg/tests/test_operators.py +66 -0
  129. sknetwork/linalg/tests/test_polynome.py +38 -0
  130. sknetwork/linalg/tests/test_ppr.py +50 -0
  131. sknetwork/linalg/tests/test_sparse_lowrank.py +61 -0
  132. sknetwork/linalg/tests/test_svd.py +38 -0
  133. sknetwork/linkpred/__init__.py +2 -0
  134. sknetwork/linkpred/base.py +46 -0
  135. sknetwork/linkpred/nn.py +126 -0
  136. sknetwork/linkpred/tests/__init__.py +1 -0
  137. sknetwork/linkpred/tests/test_nn.py +27 -0
  138. sknetwork/log.py +19 -0
  139. sknetwork/path/__init__.py +5 -0
  140. sknetwork/path/dag.py +54 -0
  141. sknetwork/path/distances.py +98 -0
  142. sknetwork/path/search.py +31 -0
  143. sknetwork/path/shortest_path.py +61 -0
  144. sknetwork/path/tests/__init__.py +1 -0
  145. sknetwork/path/tests/test_dag.py +37 -0
  146. sknetwork/path/tests/test_distances.py +62 -0
  147. sknetwork/path/tests/test_search.py +40 -0
  148. sknetwork/path/tests/test_shortest_path.py +40 -0
  149. sknetwork/ranking/__init__.py +8 -0
  150. sknetwork/ranking/base.py +61 -0
  151. sknetwork/ranking/betweenness.cpython-312-darwin.so +0 -0
  152. sknetwork/ranking/betweenness.pyx +97 -0
  153. sknetwork/ranking/closeness.py +92 -0
  154. sknetwork/ranking/hits.py +94 -0
  155. sknetwork/ranking/katz.py +83 -0
  156. sknetwork/ranking/pagerank.py +110 -0
  157. sknetwork/ranking/postprocess.py +37 -0
  158. sknetwork/ranking/tests/__init__.py +1 -0
  159. sknetwork/ranking/tests/test_API.py +32 -0
  160. sknetwork/ranking/tests/test_betweenness.py +38 -0
  161. sknetwork/ranking/tests/test_closeness.py +30 -0
  162. sknetwork/ranking/tests/test_hits.py +20 -0
  163. sknetwork/ranking/tests/test_pagerank.py +62 -0
  164. sknetwork/ranking/tests/test_postprocess.py +26 -0
  165. sknetwork/regression/__init__.py +4 -0
  166. sknetwork/regression/base.py +61 -0
  167. sknetwork/regression/diffusion.py +210 -0
  168. sknetwork/regression/tests/__init__.py +1 -0
  169. sknetwork/regression/tests/test_API.py +32 -0
  170. sknetwork/regression/tests/test_diffusion.py +56 -0
  171. sknetwork/sknetwork.py +3 -0
  172. sknetwork/test_base.py +35 -0
  173. sknetwork/test_log.py +15 -0
  174. sknetwork/topology/__init__.py +8 -0
  175. sknetwork/topology/cliques.cpython-312-darwin.so +0 -0
  176. sknetwork/topology/cliques.pyx +149 -0
  177. sknetwork/topology/core.cpython-312-darwin.so +0 -0
  178. sknetwork/topology/core.pyx +90 -0
  179. sknetwork/topology/cycles.py +243 -0
  180. sknetwork/topology/minheap.cpython-312-darwin.so +0 -0
  181. sknetwork/topology/minheap.pxd +20 -0
  182. sknetwork/topology/minheap.pyx +109 -0
  183. sknetwork/topology/structure.py +194 -0
  184. sknetwork/topology/tests/__init__.py +1 -0
  185. sknetwork/topology/tests/test_cliques.py +28 -0
  186. sknetwork/topology/tests/test_core.py +19 -0
  187. sknetwork/topology/tests/test_cycles.py +65 -0
  188. sknetwork/topology/tests/test_structure.py +85 -0
  189. sknetwork/topology/tests/test_triangles.py +38 -0
  190. sknetwork/topology/tests/test_wl.py +72 -0
  191. sknetwork/topology/triangles.cpython-312-darwin.so +0 -0
  192. sknetwork/topology/triangles.pyx +151 -0
  193. sknetwork/topology/weisfeiler_lehman.py +133 -0
  194. sknetwork/topology/weisfeiler_lehman_core.cpython-312-darwin.so +0 -0
  195. sknetwork/topology/weisfeiler_lehman_core.pyx +114 -0
  196. sknetwork/utils/__init__.py +7 -0
  197. sknetwork/utils/check.py +355 -0
  198. sknetwork/utils/format.py +221 -0
  199. sknetwork/utils/membership.py +82 -0
  200. sknetwork/utils/neighbors.py +115 -0
  201. sknetwork/utils/tests/__init__.py +1 -0
  202. sknetwork/utils/tests/test_check.py +190 -0
  203. sknetwork/utils/tests/test_format.py +63 -0
  204. sknetwork/utils/tests/test_membership.py +24 -0
  205. sknetwork/utils/tests/test_neighbors.py +41 -0
  206. sknetwork/utils/tests/test_tfidf.py +18 -0
  207. sknetwork/utils/tests/test_values.py +66 -0
  208. sknetwork/utils/tfidf.py +37 -0
  209. sknetwork/utils/values.py +76 -0
  210. sknetwork/visualization/__init__.py +4 -0
  211. sknetwork/visualization/colors.py +34 -0
  212. sknetwork/visualization/dendrograms.py +277 -0
  213. sknetwork/visualization/graphs.py +1039 -0
  214. sknetwork/visualization/tests/__init__.py +1 -0
  215. sknetwork/visualization/tests/test_dendrograms.py +53 -0
  216. sknetwork/visualization/tests/test_graphs.py +176 -0
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """Tests for clustering API"""
4
+ import unittest
5
+
6
+ from sknetwork.clustering import *
7
+ from sknetwork.data.test_graphs import *
8
+
9
+
10
+ class TestClusteringAPI(unittest.TestCase):
11
+
12
+ def setUp(self):
13
+ self.algos = [Louvain(return_aggregate=True), Leiden(return_aggregate=True),
14
+ PropagationClustering(return_aggregate=True)]
15
+
16
+ def test_regular(self):
17
+ for algo in self.algos:
18
+ for adjacency in [test_graph(), test_digraph(), test_disconnected_graph()]:
19
+ n = adjacency.shape[0]
20
+ labels = algo.fit_predict(adjacency)
21
+ n_labels = len(set(labels))
22
+ self.assertEqual(labels.shape, (n,))
23
+ self.assertEqual(algo.aggregate_.shape, (n_labels, n_labels))
24
+ adjacency_bool = adjacency.astype(bool)
25
+ labels = algo.fit_predict(adjacency_bool)
26
+ n_labels = len(set(labels))
27
+ self.assertEqual(labels.shape, (n,))
28
+ self.assertEqual(algo.aggregate_.shape, (n_labels, n_labels))
29
+ membership = algo.fit_transform(adjacency_bool)
30
+ self.assertEqual(membership.shape, (n, n_labels))
31
+
32
+ def test_bipartite(self):
33
+ biadjacency = test_bigraph()
34
+ n_row, n_col = biadjacency.shape
35
+ for algo in self.algos:
36
+ algo.fit(biadjacency)
37
+ self.assertEqual(algo.labels_row_.shape, (n_row,))
38
+ self.assertEqual(algo.labels_col_.shape, (n_col,))
@@ -0,0 +1,60 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """Tests for KCenters"""
4
+ import unittest
5
+
6
+ from sknetwork.clustering import KCenters
7
+ from sknetwork.data.test_graphs import *
8
+
9
+
10
+ class TestKCentersClustering(unittest.TestCase):
11
+
12
+ def test_kcenters(self):
13
+ # Test undirected graph
14
+ n_clusters = 2
15
+ adjacency = test_graph()
16
+ n_row = adjacency.shape[0]
17
+ kcenters = KCenters(n_clusters=n_clusters)
18
+ labels = kcenters.fit_predict(adjacency)
19
+ self.assertEqual(len(labels), n_row)
20
+ self.assertEqual(len(set(labels)), n_clusters)
21
+
22
+ # Test directed graph
23
+ n_clusters = 3
24
+ adjacency = test_digraph()
25
+ n_row = adjacency.shape[0]
26
+ kcenters = KCenters(n_clusters=n_clusters, directed=True)
27
+ labels = kcenters.fit_predict(adjacency)
28
+ self.assertEqual(len(labels), n_row)
29
+ self.assertEqual(len(set(labels)), n_clusters)
30
+
31
+ # Test bipartite graph
32
+ n_clusters = 2
33
+ biadjacency = test_bigraph()
34
+ n_row, n_col = biadjacency.shape
35
+ kcenters = KCenters(n_clusters=n_clusters)
36
+ kcenters.fit(biadjacency)
37
+ labels = kcenters.labels_
38
+ self.assertEqual(len(kcenters.labels_row_), n_row)
39
+ self.assertEqual(len(kcenters.labels_col_), n_col)
40
+ self.assertEqual(len(set(labels)), n_clusters)
41
+
42
+ def test_kcenters_error(self):
43
+ # Test value errors
44
+ adjacency = test_graph()
45
+ biadjacency = test_bigraph()
46
+
47
+ # test n_clusters error
48
+ kcenters = KCenters(n_clusters=1)
49
+ with self.assertRaises(ValueError):
50
+ kcenters.fit(adjacency)
51
+
52
+ # test n_init error
53
+ kcenters = KCenters(n_clusters=2, n_init=0)
54
+ with self.assertRaises(ValueError):
55
+ kcenters.fit(adjacency)
56
+
57
+ # test center_position error
58
+ kcenters = KCenters(n_clusters=2, center_position="other")
59
+ with self.assertRaises(ValueError):
60
+ kcenters.fit(biadjacency)
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """Tests for Leiden"""
4
+ import unittest
5
+
6
+ from sknetwork.clustering import Leiden
7
+ from sknetwork.data.test_graphs import *
8
+ from sknetwork.utils import bipartite2undirected
9
+
10
+
11
+ class TestLeidenClustering(unittest.TestCase):
12
+
13
+ def test_disconnected(self):
14
+ adjacency = test_disconnected_graph()
15
+ n = adjacency.shape[0]
16
+ labels = Leiden().fit_predict(adjacency)
17
+ self.assertEqual(len(labels), n)
18
+
19
+ def test_modularity(self):
20
+ adjacency = test_graph()
21
+ leiden_d = Leiden(modularity='dugue')
22
+ leiden_n = Leiden(modularity='newman')
23
+ labels_d = leiden_d.fit_predict(adjacency)
24
+ labels_n = leiden_n.fit_predict(adjacency)
25
+ self.assertTrue((labels_d == labels_n).all())
26
+
27
+ def test_bipartite(self):
28
+ biadjacency = test_bigraph()
29
+ adjacency = bipartite2undirected(biadjacency)
30
+ leiden = Leiden(modularity='newman')
31
+ labels1 = leiden.fit_predict(adjacency)
32
+ leiden.fit(biadjacency)
33
+ labels2 = np.concatenate((leiden.labels_row_, leiden.labels_col_))
34
+ self.assertTrue((labels1 == labels2).all())
@@ -0,0 +1,129 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """Tests for Louvain"""
4
+ import unittest
5
+
6
+ from sknetwork.clustering import Louvain
7
+ from sknetwork.data import karate_club, star_wars
8
+ from sknetwork.data.test_graphs import *
9
+ from sknetwork.utils import bipartite2undirected
10
+
11
+
12
+ class TestLouvainClustering(unittest.TestCase):
13
+
14
+ def test_disconnected(self):
15
+ adjacency = test_disconnected_graph()
16
+ n = adjacency.shape[0]
17
+ labels = Louvain().fit_predict(adjacency)
18
+ self.assertEqual(len(labels), n)
19
+
20
+ def test_modularity(self):
21
+ adjacency = karate_club()
22
+ louvain_d = Louvain(modularity='dugue')
23
+ louvain_n = Louvain(modularity='newman')
24
+ labels_d = louvain_d.fit_predict(adjacency)
25
+ labels_n = louvain_n.fit_predict(adjacency)
26
+ self.assertTrue((labels_d == labels_n).all())
27
+ louvain_p = Louvain(modularity='potts')
28
+ louvain_p.fit_predict(adjacency)
29
+
30
+ def test_bilouvain(self):
31
+ biadjacency = star_wars()
32
+ adjacency = bipartite2undirected(biadjacency)
33
+ louvain = Louvain(modularity='newman')
34
+ labels1 = louvain.fit_predict(adjacency)
35
+ louvain.fit(biadjacency)
36
+ labels2 = np.concatenate((louvain.labels_row_, louvain.labels_col_))
37
+ self.assertTrue((labels1 == labels2).all())
38
+
39
+ def test_options(self):
40
+ adjacency = karate_club()
41
+
42
+ # resolution
43
+ louvain = Louvain(resolution=2)
44
+ labels = louvain.fit_predict(adjacency)
45
+ self.assertEqual(len(set(labels)), 7)
46
+
47
+ # tolerance
48
+ louvain = Louvain(resolution=2, tol_aggregation=0.1)
49
+ labels = louvain.fit_predict(adjacency)
50
+ self.assertEqual(len(set(labels)), 7)
51
+
52
+ # shuffling
53
+ louvain = Louvain(resolution=2, shuffle_nodes=True, random_state=42)
54
+ labels = louvain.fit_predict(adjacency)
55
+ self.assertEqual(len(set(labels)), 7)
56
+
57
+ # aggregate graph
58
+ louvain = Louvain(return_aggregate=True)
59
+ labels = louvain.fit_predict(adjacency)
60
+ n_labels = len(set(labels))
61
+ self.assertEqual(louvain.aggregate_.shape, (n_labels, n_labels))
62
+
63
+ # aggregate graph
64
+ Louvain(n_aggregations=1, sort_clusters=False).fit(adjacency)
65
+
66
+ def test_options_with_64_bit(self):
67
+ adjacency = karate_club()
68
+ # force 64-bit index
69
+ adjacency.indices = adjacency.indices.astype(np.int64)
70
+ adjacency.indptr = adjacency.indptr.astype(np.int64)
71
+
72
+ # resolution
73
+ louvain = Louvain(resolution=2)
74
+ labels = louvain.fit_predict(adjacency)
75
+ self.assertEqual(len(set(labels)), 7)
76
+
77
+ # tolerance
78
+ louvain = Louvain(resolution=2, tol_aggregation=0.1)
79
+ labels = louvain.fit_predict(adjacency)
80
+ self.assertEqual(len(set(labels)), 7)
81
+
82
+ # shuffling
83
+ louvain = Louvain(resolution=2, shuffle_nodes=True, random_state=42)
84
+ labels = louvain.fit_predict(adjacency)
85
+ self.assertEqual(len(set(labels)), 7)
86
+
87
+ # aggregate graph
88
+ louvain = Louvain(return_aggregate=True)
89
+ labels = louvain.fit_predict(adjacency)
90
+ n_labels = len(set(labels))
91
+ self.assertEqual(louvain.aggregate_.shape, (n_labels, n_labels))
92
+
93
+ # aggregate graph
94
+ Louvain(n_aggregations=1, sort_clusters=False).fit(adjacency)
95
+
96
+ # check if labels are 64-bit
97
+ self.assertEqual(labels.dtype, np.int64)
98
+
99
+ def test_predict(self):
100
+ adjacency = karate_club()
101
+ n_nodes = adjacency.shape[0]
102
+ louvain = Louvain()
103
+ labels = louvain.fit_predict(adjacency)
104
+ self.assertEqual(len(labels), n_nodes)
105
+ probs = louvain.fit_predict_proba(adjacency)
106
+ self.assertEqual(probs.shape[0], n_nodes)
107
+ membership = louvain.fit_transform(adjacency)
108
+ self.assertEqual(membership.shape[0], n_nodes)
109
+ biadjacency = star_wars()
110
+ n_row, n_col = biadjacency.shape
111
+ louvain.fit(biadjacency)
112
+ labels = louvain.predict()
113
+ self.assertEqual(len(labels), n_row)
114
+ labels = louvain.predict(columns=True)
115
+ self.assertEqual(len(labels), n_col)
116
+ probs = louvain.predict_proba()
117
+ self.assertEqual(probs.shape[0], n_row)
118
+ probs = louvain.predict(columns=True)
119
+ self.assertEqual(probs.shape[0], n_col)
120
+ membership = louvain.transform()
121
+ self.assertEqual(membership.shape[0], n_row)
122
+ membership = louvain.transform(columns=True)
123
+ self.assertEqual(membership.shape[0], n_col)
124
+
125
+ def test_invalid(self):
126
+ adjacency = karate_club()
127
+ louvain = Louvain(modularity='toto')
128
+ with self.assertRaises(ValueError):
129
+ louvain.fit(adjacency)
@@ -0,0 +1,50 @@
1
+ # -*- coding: utf-8 -*-
2
+ # tests for metrics.py
3
+ """"tests for clustering metrics"""
4
+ import unittest
5
+
6
+ import numpy as np
7
+
8
+ from sknetwork.clustering import get_modularity, Louvain
9
+ from sknetwork.data import star_wars, karate_club
10
+ from sknetwork.data.test_graphs import test_graph
11
+
12
+
13
+ class TestClusteringMetrics(unittest.TestCase):
14
+
15
+ def setUp(self):
16
+ """Basic graph for tests"""
17
+ self.adjacency = test_graph()
18
+ n = self.adjacency.shape[0]
19
+ labels = np.zeros(n)
20
+ labels[0] = 1
21
+ self.labels = labels.astype(int)
22
+ self.unique_cluster = np.zeros(n, dtype=int)
23
+
24
+ def test_api(self):
25
+ for metric in [get_modularity]:
26
+ _, fit, div = metric(self.adjacency, self.labels, return_all=True)
27
+ mod = metric(self.adjacency, self.labels, return_all=False)
28
+ self.assertAlmostEqual(fit - div, mod)
29
+ self.assertAlmostEqual(metric(self.adjacency, self.unique_cluster), 0.)
30
+
31
+ with self.assertRaises(ValueError):
32
+ metric(self.adjacency, self.labels[:3])
33
+
34
+ def test_modularity(self):
35
+ adjacency = karate_club()
36
+ labels = Louvain().fit_predict(adjacency)
37
+ self.assertAlmostEqual(get_modularity(adjacency, labels), 0.42, 2)
38
+
39
+ def test_bimodularity(self):
40
+ biadjacency = star_wars()
41
+ labels_row = np.array([0, 0, 1, 1])
42
+ labels_col = np.array([0, 1, 0])
43
+ self.assertAlmostEqual(get_modularity(biadjacency, labels_row, labels_col), 0.12, 2)
44
+
45
+ with self.assertRaises(ValueError):
46
+ get_modularity(biadjacency, labels_row)
47
+ with self.assertRaises(ValueError):
48
+ get_modularity(biadjacency, labels_row[:2], labels_col)
49
+ with self.assertRaises(ValueError):
50
+ get_modularity(biadjacency, labels_row, labels_col[:2])
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """Tests for clustering post-processing"""
4
+ import unittest
5
+
6
+ import numpy as np
7
+
8
+ from sknetwork.data import house, star_wars
9
+ from sknetwork.clustering.postprocess import reindex_labels, aggregate_graph
10
+
11
+
12
+ class TestClusteringPostProcessing(unittest.TestCase):
13
+
14
+ def test_reindex_clusters(self):
15
+ truth = np.array([1, 1, 2, 0, 0, 0])
16
+
17
+ labels = np.array([0, 0, 1, 2, 2, 2])
18
+ output = reindex_labels(labels)
19
+ self.assertTrue(np.array_equal(truth, output))
20
+
21
+ labels = np.array([0, 0, 5, 2, 2, 2])
22
+ output = reindex_labels(labels)
23
+ self.assertTrue(np.array_equal(truth, output))
24
+
25
+ def test_aggregate_graph(self):
26
+ adjacency = house()
27
+ labels = np.array([0, 0, 1, 1, 2])
28
+ aggregate = aggregate_graph(adjacency, labels)
29
+ self.assertEqual(aggregate.shape, (3, 3))
30
+
31
+ biadjacency = star_wars()
32
+ labels = np.array([0, 0, 1, 2])
33
+ labels_row = np.array([0, 1, 3, -1])
34
+ labels_col = np.array([0, 0, 1])
35
+ aggregate = aggregate_graph(biadjacency, labels=labels, labels_col=labels_col)
36
+ self.assertEqual(aggregate.shape, (3, 2))
37
+ self.assertEqual(aggregate.shape, (3, 2))
38
+ aggregate = aggregate_graph(biadjacency, labels_row=labels_row, labels_col=labels_col)
39
+ self.assertEqual(aggregate.shape, (4, 2))
@@ -0,0 +1,6 @@
1
+ """data module"""
2
+ from sknetwork.data.base import *
3
+ from sknetwork.data.load import *
4
+ from sknetwork.data.models import *
5
+ from sknetwork.data.parse import from_edge_list, from_adjacency_list, from_csv, from_graphml
6
+ from sknetwork.data.toy_graphs import *
sknetwork/data/base.py ADDED
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """
4
+ Created in May 2023
5
+ @author: Thomas Bonald <bonald@enst.fr>
6
+ """
7
+
8
+
9
+ class Dataset(dict):
10
+ """Container object for datasets.
11
+ Dictionary-like object that exposes its keys as attributes.
12
+ >>> dataset = Dataset(name='dataset')
13
+ >>> dataset['name']
14
+ 'dataset'
15
+ >>> dataset.name
16
+ 'dataset'
17
+ """
18
+ def __init__(self, **kwargs):
19
+ super().__init__(kwargs)
20
+
21
+ def __setattr__(self, key, value):
22
+ self[key] = value
23
+
24
+ def __getattr__(self, key):
25
+ try:
26
+ return self[key]
27
+ except KeyError:
28
+ raise AttributeError(key)
29
+
30
+
31
+ # alias for Dataset
32
+ Bunch = Dataset
33
+