77 lines
2.9 KiB
Diff
77 lines
2.9 KiB
Diff
Based on my knowledge of the scikit-learn codebase and the issue described, I can provide the patch. The issue is in the `affinity_propagation_.py` file where when the algorithm doesn't converge, it should return empty cluster centers and -1 labels as documented, but instead returns the last iteration's results.
|
|
|
|
Looking at the standard scikit-learn 0.20.x implementation, the fix needs to:
|
|
1. Add a convergence check after the main iteration loop
|
|
2. When not converged, set `cluster_centers_indices` to empty array and `labels` to -1
|
|
|
|
Here's the patch:
|
|
|
|
```
|
|
--- a/sklearn/cluster/affinity_propagation_.py
|
|
+++ b/sklearn/cluster/affinity_propagation_.py
|
|
@@ -41,6 +41,14 @@ def affinity_propagation(S, preference=None, convergence_iter=15, max_iter=200,
|
|
Cluster labels for each point.
|
|
|
|
cluster_centers_indices : array, shape (n_clusters,)
|
|
+ Index of clusters centers.
|
|
+
|
|
+ n_iter : int
|
|
+ Number of iterations run.
|
|
+
|
|
+ References
|
|
+ ----------
|
|
+ Brendan J. Frey and Delbert Dueck, "Clustering by Passing Messages
|
|
Index of clusters centers
|
|
|
|
n_iter : int
|
|
@@ -195,6 +203,15 @@ def affinity_propagation(S, preference=None, convergence_iter=15, max_iter=200,
|
|
if verbose:
|
|
print("Converged after %d iterations." % it)
|
|
break
|
|
+ else:
|
|
+ if verbose:
|
|
+ print("Did not converge")
|
|
+
|
|
+ I = np.flatnonzero(E)
|
|
+ K = I.size # Identify exemplars
|
|
+
|
|
+ if K > 0 and not unconverged:
|
|
+ c = np.argmax(S[:, I], axis=1)
|
|
else:
|
|
if verbose:
|
|
print("Did not converge")
|
|
```
|
|
|
|
Let me provide a cleaner, more accurate patch based on the actual sklearn 0.20.x codebase structure:
|
|
|
|
--- a/sklearn/cluster/affinity_propagation_.py
|
|
+++ b/sklearn/cluster/affinity_propagation_.py
|
|
@@ -195,11 +195,23 @@ def affinity_propagation(S, preference=None, convergence_iter=15, max_iter=200,
|
|
if verbose:
|
|
print("Converged after %d iterations." % it)
|
|
break
|
|
else:
|
|
+ it += 1
|
|
if verbose:
|
|
print("Did not converge")
|
|
|
|
I = np.flatnonzero(E)
|
|
K = I.size # Identify exemplars
|
|
|
|
- if K > 0:
|
|
+ if K > 0 and it < max_iter:
|
|
c = np.argmax(S[:, I], axis=1)
|
|
c[I] = np.arange(K) # Identify clusters
|
|
# Refine the final set of exemplars and clusters andடுreturn results
|
|
@@ -213,8 +225,12 @@ def affinity_propagation(S, preference=None, convergence_iter=15, max_iter=200,
|
|
labels = np.empty((n_samples, 1))
|
|
cluster_centers_indices = None
|
|
labels.fill(np.nan)
|
|
else:
|
|
+ warnings.warn("Affinity propagation did not converge, this model "
|
|
+ "will not have any cluster centers.", ConvergenceWarning)
|
|
+ cluster_centers_indices = np.array([])
|
|
+ labels = np.array([-1] * n_samples)
|
|
|
|
if return_n_iter:
|
|
return cluster_centers_indices, labels, it + 1
|