Coverage for tests\clustering\test_affinity_propagation.py: 100.00%

52 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2023-11-17 13:31 +0100

1""" 

2* Name: interactive-clustering/tests/clustering/test_affinity_propagation.py 

3* Description: Unittests for the `clustering.affinity_propagation` module. 

4* Author: David NICOLAZO, Esther LENOTRE, Marc TRUTT 

5* Created: 02/11/2022 

6* Licence: CeCILL (https://cecill.info/licences.fr.html) 

7""" 

8 

9# ============================================================================== 

10# IMPORT PYTHON DEPENDENCIES 

11# ============================================================================== 

12 

13 

14import numpy as np 

15import pytest 

16from scipy.sparse import csr_matrix 

17 

18from cognitivefactory.interactive_clustering.clustering.affinity_propagation import ( 

19 AffinityPropagationConstrainedClustering, 

20) 

21from cognitivefactory.interactive_clustering.constraints.binary import BinaryConstraintsManager 

22 

23 

24# ============================================================================== 

25# test_AffinityPropagationConstrainedClustering_for_inconsistent_max_iteration 

26# ============================================================================== 

27def test_AffinityPropagationConstrainedClustering_for_inconsistent_max_iteration(): 

28 """ 

29 Test that the `clustering.affinity_propagation.AffinityPropagationConstrainedClustering` initialization raises an `ValueError` for inconsistent `max_iteration` parameter. 

30 """ 

31 

32 # Check `ValueError` for bad string value for `model`. 

33 with pytest.raises(ValueError, match="`max_iteration`"): 

34 AffinityPropagationConstrainedClustering( 

35 max_iteration=-1, 

36 ) 

37 

38 

39# ============================================================================== 

40# test_AffinityPropagationConstrainedClustering_for_inconsistent_convergence_iteration 

41# ============================================================================== 

42def test_AffinityPropagationConstrainedClustering_for_inconsistent_convergence_iteration(): 

43 """ 

44 Test that the `clustering.affinity_propagation.AffinityPropagationConstrainedClustering` initialization raises an `ValueError` for inconsistent `convergence_iteration` parameter. 

45 """ 

46 

47 # Check `ValueError` for bad string value for `model`. 

48 with pytest.raises(ValueError, match="`convergence_iteration`"): 

49 AffinityPropagationConstrainedClustering( 

50 convergence_iteration=-1, 

51 ) 

52 

53 

54# ============================================================================== 

55# test_AffinityPropagationConstrainedClustering_for_correct_settings 

56# ============================================================================== 

57def test_AffinityPropagationConstrainedClustering_for_correct_settings(): 

58 """ 

59 Test that the `clustering.affinity_propagation.AffinityPropagationConstrainedClustering` initialization runs correctly with the correct settings. 

60 """ 

61 

62 # Check a correct initialization. 

63 clustering_model = AffinityPropagationConstrainedClustering( 

64 max_iteration=100, 

65 convergence_iteration=5, 

66 ) 

67 assert clustering_model 

68 assert clustering_model.max_iteration == 100 

69 assert clustering_model.convergence_iteration == 5 

70 

71 

72# ============================================================================== 

73# test_AffinityPropagationConstrainedClustering_cluster_for_inconsistent_constraints_manager 

74# ============================================================================== 

75def test_AffinityPropagationConstrainedClustering_cluster_for_inconsistent_constraints_manager(): 

76 """ 

77 Test that the `clustering.affinity_propagation.AffinityPropagationConstrainedClustering` clustering raises an `ValueError` for inconsistent `constraints_manager` parameter. 

78 """ 

79 

80 # Initialize a `AffinityPropagationConstrainedClustering` instance. 

81 clustering_model = AffinityPropagationConstrainedClustering() 

82 

83 # Check `ValueError` for not matrix `vectors`. 

84 with pytest.raises(ValueError, match="`constraints_manager`"): 

85 clustering_model.cluster( 

86 constraints_manager=None, 

87 vectors=None, 

88 nb_clusters=2, 

89 ) 

90 

91 

92# ============================================================================== 

93# test_AffinityPropagationConstrainedClustering_cluster_for_inconsistent_vectors 

94# ============================================================================== 

95def test_AffinityPropagationConstrainedClustering_cluster_for_inconsistent_vectors(): 

96 """ 

97 Test that the `clustering.affinity_propagation.AffinityPropagationConstrainedClustering` clustering raises an `ValueError` for inconsistent `vectors` parameter. 

98 """ 

99 

100 # Initialize a `AffinityPropagationConstrainedClustering` instance. 

101 clustering_model = AffinityPropagationConstrainedClustering() 

102 

103 # Check `ValueError` for not matrix `vectors`. 

104 with pytest.raises(ValueError, match="`vectors`"): 

105 clustering_model.cluster( 

106 constraints_manager=BinaryConstraintsManager(list_of_data_IDs=["first", "second", "third"]), 

107 vectors=None, 

108 nb_clusters=2, 

109 ) 

110 

111 

112# ============================================================================== 

113# test_AffinityPropagationConstrainedClustering_cluster_for_inconsistent_nb_clusters 

114# ============================================================================== 

115def test_AffinityPropagationConstrainedClustering_cluster_for_inconsistent_nb_clusters_1(): 

116 """ 

117 Test that the `clustering.affinity_propagation.AffinityPropagationConstrainedClustering` clustering raises an `ValueError` for inconsistent `nb_clusters` parameter. 

118 """ 

119 

120 # Initialize a `AffinityPropagationConstrainedClustering` instance. 

121 clustering_model = AffinityPropagationConstrainedClustering() 

122 

123 # Check `ValueError` for too small `nb_clusters`. 

124 with pytest.raises(ValueError, match="`nb_clusters`"): 

125 clustering_model.cluster( 

126 constraints_manager=BinaryConstraintsManager(list_of_data_IDs=["first", "second", "third"]), 

127 vectors={"first": np.array([1, 2, 3]), "second": np.array([[4, 5, 6]]), "third": csr_matrix([7, 8, 9])}, 

128 nb_clusters=2, 

129 ) 

130 

131 

132# ============================================================================== 

133# test_AffinityPropagationConstrainedClustering_cluster_with_no_constraints_1 

134# ============================================================================== 

135def test_AffinityPropagationConstrainedClustering_cluster_with_no_constraints_1(): 

136 """ 

137 Test that the `clustering.affinity_propagation.AffinityPropagationConstrainedClustering` clustering works with no `constraints`. 

138 """ 

139 

140 # Define `vectors` and `constraints_manager` 

141 vectors = { 

142 "0": csr_matrix([1.00, 0.00, 0.00, 0.00]), 

143 "1": csr_matrix([0.00, 0.43, 0.00, 0.00]), 

144 "2": csr_matrix([0.00, 0.00, 0.29, 0.00]), 

145 "3": csr_matrix([0.00, 0.00, 0.50, 0.00]), 

146 "4": csr_matrix([0.00, 0.00, 0.00, 0.98]), 

147 "5": csr_matrix([0.00, 0.00, 0.33, 0.00]), 

148 "6": csr_matrix([0.00, 0.00, 0.00, 1.40]), 

149 "7": csr_matrix([0.80, 0.00, 0.00, 0.00]), 

150 "8": csr_matrix([0.00, 0.54, 0.00, 0.00]), 

151 "9": csr_matrix([0.00, 0.00, 0.00, 1.10]), 

152 "10": csr_matrix([1.10, 0.00, 0.00, 0.00]), 

153 "11": csr_matrix([0.00, 0.49, 0.00, 0.00]), 

154 } 

155 

156 constraints_manager = BinaryConstraintsManager(list_of_data_IDs=list(vectors.keys())) 

157 

158 # Initialize a `AffinityPropagationConstrainedClustering` instance. 

159 clustering_model = AffinityPropagationConstrainedClustering() 

160 

161 # Run clustering 2 clusters and no constraints. 

162 dict_of_predicted_clusters = clustering_model.cluster( 

163 constraints_manager=constraints_manager, 

164 vectors=vectors, 

165 ) 

166 

167 assert clustering_model.dict_of_predicted_clusters 

168 assert dict_of_predicted_clusters == { 

169 "0": 0, 

170 "1": 1, 

171 "2": 2, 

172 "3": 2, 

173 "4": 3, 

174 "5": 2, 

175 "6": 3, 

176 "7": 0, 

177 "8": 1, 

178 "9": 3, 

179 "10": 0, 

180 "11": 1, 

181 } 

182 

183 

184# ============================================================================== 

185# test_AffinityPropagationConstrainedClustering_cluster_with_no_constraints_2 

186# ============================================================================== 

187def test_AffinityPropagationConstrainedClustering_cluster_with_no_constraints_2(): 

188 """ 

189 Test that the `clustering.affinity_propagation.AffinityPropagationConstrainedClustering` clustering works with no `constraints`. 

190 """ 

191 # Define `vectors` and `constraints_manager` 

192 vectors = { 

193 "0": csr_matrix([2.00, 0.00, 0.00, 0.00]), 

194 "1": csr_matrix([0.00, 0.43, 0.00, 0.00]), 

195 "2": csr_matrix([0.00, 0.00, 0.29, 0.00]), 

196 "3": csr_matrix([0.00, 0.00, 0.50, 0.00]), 

197 "4": csr_matrix([0.00, 0.00, 0.00, 0.98]), 

198 "5": csr_matrix([0.00, 0.00, 0.33, 0.00]), 

199 "6": csr_matrix([0.00, 0.00, 0.00, 1.40]), 

200 "7": csr_matrix([0.80, 0.00, 0.00, 0.00]), 

201 "8": csr_matrix([0.00, 0.54, 0.00, 0.00]), 

202 "9": csr_matrix([0.00, 0.00, 0.00, 1.10]), 

203 "10": csr_matrix([1.10, 0.00, 0.00, 0.00]), 

204 "11": csr_matrix([0.00, 0.49, 0.00, 0.00]), 

205 } 

206 

207 constraints_manager = BinaryConstraintsManager(list_of_data_IDs=list(vectors.keys())) 

208 

209 # Initialize a `AffinityPropagationConstrainedClustering` instance. 

210 clustering_model = AffinityPropagationConstrainedClustering() 

211 

212 # Run clustering with no constraints. 

213 dict_of_predicted_clusters = clustering_model.cluster( 

214 constraints_manager=constraints_manager, 

215 vectors=vectors, 

216 ) 

217 

218 assert clustering_model.dict_of_predicted_clusters 

219 

220 """ 

221 Here, '0' is too far from other points so it is noise 

222 Furthermore, '7' and '10' are in the same neighbourhood, but no other point. 

223 They are not numerous enough to create a cluster 

224 """ 

225 

226 assert dict_of_predicted_clusters == { 

227 "0": 0, 

228 "1": 1, 

229 "2": 2, 

230 "3": 2, 

231 "4": 3, 

232 "5": 2, 

233 "6": 3, 

234 "7": 0, 

235 "8": 1, 

236 "9": 3, 

237 "10": 0, 

238 "11": 1, 

239 } 

240 

241 

242# ============================================================================== 

243# test_AffinityPropagationConstrainedClustering_cluster_with_some_constraints 

244# ============================================================================== 

245def test_AffinityPropagationConstrainedClustering_cluster_with_some_constraints(): 

246 """ 

247 Test that the `clustering.affinity_propagation.AffinityPropagationConstrainedClustering` clustering works with some `constraints`. 

248 """ 

249 

250 # Define `vectors` and `constraints_manager` 

251 vectors = { 

252 "0": csr_matrix([2.00, 0.00, 0.00, 0.00]), 

253 "1": csr_matrix([0.00, 0.43, 0.00, 0.00]), 

254 "2": csr_matrix([0.00, 0.00, 0.29, 0.00]), 

255 "3": csr_matrix([0.00, 0.00, 0.50, 0.00]), 

256 "4": csr_matrix([0.00, 0.00, 0.00, 0.98]), 

257 "5": csr_matrix([0.00, 0.00, 0.33, 0.00]), 

258 "6": csr_matrix([0.00, 0.00, 0.00, 1.40]), 

259 "7": csr_matrix([0.80, 0.00, 0.00, 0.00]), 

260 "8": csr_matrix([0.00, 0.54, 0.00, 0.00]), 

261 "9": csr_matrix([0.00, 0.00, 0.00, 1.10]), 

262 "10": csr_matrix([1.10, 0.00, 0.00, 0.00]), 

263 "11": csr_matrix([0.00, 0.49, 0.00, 0.00]), 

264 } 

265 

266 constraints_manager = BinaryConstraintsManager(list_of_data_IDs=list(vectors.keys())) 

267 constraints_manager.add_constraint(data_ID1="0", data_ID2="7", constraint_type="MUST_LINK") 

268 constraints_manager.add_constraint(data_ID1="0", data_ID2="10", constraint_type="MUST_LINK") 

269 constraints_manager.add_constraint(data_ID1="0", data_ID2="4", constraint_type="CANNOT_LINK") 

270 

271 # Initialize a `AffinityPropagationConstrainedClustering` instance. 

272 clustering_model = AffinityPropagationConstrainedClustering() 

273 

274 # Run clustering with some constraints. 

275 dict_of_predicted_clusters = clustering_model.cluster( 

276 constraints_manager=constraints_manager, 

277 vectors=vectors, 

278 ) 

279 

280 assert clustering_model.dict_of_predicted_clusters 

281 assert dict_of_predicted_clusters == { 

282 "0": 0, 

283 "1": 1, 

284 "2": 0, # TODO: 2, 

285 "3": 0, # TODO: 2, 

286 "4": 2, # TODO: 3, 

287 "5": 0, # TODO: 2, 

288 "6": 2, # TODO: 3, 

289 "7": 0, 

290 "8": 1, 

291 "9": 2, # TODO: 3, 

292 "10": 0, 

293 "11": 1, 

294 }