This is an automated email from the ASF dual-hosted git repository.

erans pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-math.git


The following commit(s) were added to refs/heads/master by this push:
     new baf8d0a  MATH-1525: Make "EmptyClusterStrategy" and related logic in 
"KMeansPlusPlusClusterer" reusable.
     new 22373ae  Merge branch 'MATH-1525__ChenTao'
baf8d0a is described below

commit baf8d0a40468fc844db7aab4b20fd5b3f3e225a4
Author: CT <chen...@qq.com>
AuthorDate: Sat Mar 21 21:11:17 2020 +0800

    MATH-1525: Make "EmptyClusterStrategy" and related logic in 
"KMeansPlusPlusClusterer" reusable.
---
 .../ml/clustering/KMeansPlusPlusClusterer.java     | 67 ++++++++++++++--------
 1 file changed, 42 insertions(+), 25 deletions(-)

diff --git 
a/src/main/java/org/apache/commons/math4/ml/clustering/KMeansPlusPlusClusterer.java
 
b/src/main/java/org/apache/commons/math4/ml/clustering/KMeansPlusPlusClusterer.java
index bf656ae..41d316f 100644
--- 
a/src/main/java/org/apache/commons/math4/ml/clustering/KMeansPlusPlusClusterer.java
+++ 
b/src/main/java/org/apache/commons/math4/ml/clustering/KMeansPlusPlusClusterer.java
@@ -189,6 +189,14 @@ public class KMeansPlusPlusClusterer<T extends 
Clusterable> extends Clusterer<T>
     }
 
     /**
+     * Return the CentroidInitializer used by this instance.
+     * @return the CentroidInitializer
+     */
+    CentroidInitializer getCentroidInitializer() {
+        return centroidInitializer;
+    }
+
+    /**
      * Runs the K-means++ clustering algorithm.
      *
      * @param points the points to cluster
@@ -219,36 +227,14 @@ public class KMeansPlusPlusClusterer<T extends 
Clusterable> extends Clusterer<T>
         // iterate through updating the centers until we're done
         final int max = (maxIterations < 0) ? Integer.MAX_VALUE : 
maxIterations;
         for (int count = 0; count < max; count++) {
-            boolean emptyCluster = false;
-            List<CentroidCluster<T>> newClusters = new ArrayList<>();
-            for (final CentroidCluster<T> cluster : clusters) {
-                final Clusterable newCenter;
-                if (cluster.getPoints().isEmpty()) {
-                    switch (emptyStrategy) {
-                        case LARGEST_VARIANCE :
-                            newCenter = 
getPointFromLargestVarianceCluster(clusters);
-                            break;
-                        case LARGEST_POINTS_NUMBER :
-                            newCenter = 
getPointFromLargestNumberCluster(clusters);
-                            break;
-                        case FARTHEST_POINT :
-                            newCenter = getFarthestPoint(clusters);
-                            break;
-                        default :
-                            throw new 
ConvergenceException(LocalizedFormats.EMPTY_CLUSTER_IN_K_MEANS);
-                    }
-                    emptyCluster = true;
-                } else {
-                    newCenter = cluster.centroid();
-                }
-                newClusters.add(new CentroidCluster<T>(newCenter));
-            }
+            boolean hasEmptyCluster = 
clusters.stream().anyMatch(cluster->cluster.getPoints().isEmpty());
+            List<CentroidCluster<T>> newClusters = 
adjustClustersCenters(clusters);
             int changes = assignPointsToClusters(newClusters, points, 
assignments);
             clusters = newClusters;
 
             // if there were no more changes in the point-to-cluster assignment
             // and there are no empty clusters left, return the current 
clusters
-            if (changes == 0 && !emptyCluster) {
+            if (changes == 0 && !hasEmptyCluster) {
                 return clusters;
             }
         }
@@ -256,6 +242,37 @@ public class KMeansPlusPlusClusterer<T extends 
Clusterable> extends Clusterer<T>
     }
 
     /**
+     * Adjust the clusters's centers with means of points
+     * @param clusters the origin clusters
+     * @return adjusted clusters with center points
+     */
+    List<CentroidCluster<T>> adjustClustersCenters(List<CentroidCluster<T>> 
clusters) {
+        List<CentroidCluster<T>> newClusters = new ArrayList<>();
+        for (final CentroidCluster<T> cluster : clusters) {
+            final Clusterable newCenter;
+            if (cluster.getPoints().isEmpty()) {
+                switch (emptyStrategy) {
+                    case LARGEST_VARIANCE :
+                        newCenter = 
getPointFromLargestVarianceCluster(clusters);
+                        break;
+                    case LARGEST_POINTS_NUMBER :
+                        newCenter = getPointFromLargestNumberCluster(clusters);
+                        break;
+                    case FARTHEST_POINT :
+                        newCenter = getFarthestPoint(clusters);
+                        break;
+                    default :
+                        throw new 
ConvergenceException(LocalizedFormats.EMPTY_CLUSTER_IN_K_MEANS);
+                }
+            } else {
+                newCenter = cluster.centroid();
+            }
+            newClusters.add(new CentroidCluster<>(newCenter));
+        }
+        return newClusters;
+    }
+
+    /**
      * Adds the given points to the closest {@link Cluster}.
      *
      * @param clusters the {@link Cluster}s to add the points to

Reply via email to