MATH-546
Wrong variable type ("int" instead of "double"). git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@1081744 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
35a0923edf
commit
b6bf8f418a
|
@ -172,7 +172,7 @@ public class KMeansPlusPlusClusterer<T extends Clusterable<T>> {
|
|||
while (resultSet.size() < k) {
|
||||
// For each data point x, compute D(x), the distance between x and
|
||||
// the nearest center that has already been chosen.
|
||||
int sum = 0;
|
||||
double sum = 0;
|
||||
for (int i = 0; i < pointSet.size(); i++) {
|
||||
final T p = pointSet.get(i);
|
||||
final Cluster<T> nearest = getNearestCluster(resultSet, p);
|
||||
|
|
|
@ -52,6 +52,9 @@ The <action> type attribute can be add,update,fix,remove.
|
|||
If the output is not quite correct, check for invisible trailing spaces!
|
||||
-->
|
||||
<release version="3.0" date="TBD" description="TBD">
|
||||
<action dev="erans" type="fix" issue="MATH-546" due-to="Nate Paymer">
|
||||
Fixed bug in "KMeansPlusPlusClusterer".
|
||||
</action>
|
||||
<action dev="erans" type="update" issue="MATH-542">
|
||||
All exceptions defined in Commons Math provide a context and a compound
|
||||
message list.
|
||||
|
|
|
@ -20,7 +20,9 @@ package org.apache.commons.math.stat.clustering;
|
|||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
|
@ -166,4 +168,84 @@ public class KMeansPlusPlusClustererTest {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* A helper class for testSmallDistances(). This class is similar to EuclideanIntegerPoint, but
|
||||
* it defines a different distanceFrom() method that tends to return distances less than 1.
|
||||
*/
|
||||
private class CloseIntegerPoint implements Clusterable<CloseIntegerPoint> {
|
||||
public CloseIntegerPoint(EuclideanIntegerPoint point) {
|
||||
euclideanPoint = point;
|
||||
}
|
||||
|
||||
public double distanceFrom(CloseIntegerPoint p) {
|
||||
return euclideanPoint.distanceFrom(p.euclideanPoint) * 0.001;
|
||||
}
|
||||
|
||||
public CloseIntegerPoint centroidOf(Collection<CloseIntegerPoint> p) {
|
||||
Collection<EuclideanIntegerPoint> euclideanPoints =
|
||||
new ArrayList<EuclideanIntegerPoint>();
|
||||
for (CloseIntegerPoint point : p) {
|
||||
euclideanPoints.add(point.euclideanPoint);
|
||||
}
|
||||
return new CloseIntegerPoint(euclideanPoint.centroidOf(euclideanPoints));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof CloseIntegerPoint)) {
|
||||
return false;
|
||||
}
|
||||
CloseIntegerPoint p = (CloseIntegerPoint) o;
|
||||
|
||||
return euclideanPoint.equals(p.euclideanPoint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return euclideanPoint.hashCode();
|
||||
}
|
||||
|
||||
private EuclideanIntegerPoint euclideanPoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test points that are very close together. See issue MATH-546.
|
||||
*/
|
||||
@Test
|
||||
public void testSmallDistances() {
|
||||
// Create a bunch of CloseIntegerPoints. Most are identical, but one is different by a
|
||||
// small distance.
|
||||
int[] repeatedArray = { 0 };
|
||||
int[] uniqueArray = { 1 };
|
||||
CloseIntegerPoint repeatedPoint =
|
||||
new CloseIntegerPoint(new EuclideanIntegerPoint(repeatedArray));
|
||||
CloseIntegerPoint uniquePoint =
|
||||
new CloseIntegerPoint(new EuclideanIntegerPoint(uniqueArray));
|
||||
|
||||
Collection<CloseIntegerPoint> points = new ArrayList<CloseIntegerPoint>();
|
||||
final int NUM_REPEATED_POINTS = 10 * 1000;
|
||||
for (int i = 0; i < NUM_REPEATED_POINTS; ++i) {
|
||||
points.add(repeatedPoint);
|
||||
}
|
||||
points.add(uniquePoint);
|
||||
|
||||
// Ask a KMeansPlusPlusClusterer to run zero iterations (i.e., to simply choose initial
|
||||
// cluster centers).
|
||||
final long RANDOM_SEED = 0;
|
||||
final int NUM_CLUSTERS = 2;
|
||||
final int NUM_ITERATIONS = 0;
|
||||
KMeansPlusPlusClusterer<CloseIntegerPoint> clusterer =
|
||||
new KMeansPlusPlusClusterer<CloseIntegerPoint>(new Random(RANDOM_SEED));
|
||||
List<Cluster<CloseIntegerPoint>> clusters =
|
||||
clusterer.cluster(points, NUM_CLUSTERS, NUM_ITERATIONS);
|
||||
|
||||
// Check that one of the chosen centers is the unique point.
|
||||
boolean uniquePointIsCenter = false;
|
||||
for (Cluster<CloseIntegerPoint> cluster : clusters) {
|
||||
if (cluster.getCenter().equals(uniquePoint)) {
|
||||
uniquePointIsCenter = true;
|
||||
}
|
||||
}
|
||||
assertTrue(uniquePointIsCenter);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue