Improved the LinearDoubleClusterGroup

This commit is contained in:
Lennart Hensler committed 2016-10-22 14:16:37 +02:00
1 parent 03bcdb2ec6
commit 201c65cc37
2 files changed
+88 -47

No files matched your search

@@ -8,16 +8,16 @@ import org.junit.Before;
import org.junit.Test;
import com.sap.sse.datamining.data.Cluster;
import com.sap.sse.datamining.data.ClusterGroup;
import com.sap.sse.datamining.impl.data.ClusterWithLowerAndUpperBoundaries;
import com.sap.sse.datamining.impl.data.ClusterWithSingleBoundary;
import com.sap.sse.datamining.impl.data.ComparableClusterBoundary;
import com.sap.sse.datamining.impl.data.ComparisonStrategy;
// TODO Move to sse bundle, after 49er analysis
public class TestLinearDoubleClusterGroup {
private ClusterGroup<Double> hardPercentageClusterGroup;
private ClusterGroup<Double> softLinearClusterGroup;
private LinearDoubleClusterGroup hardPercentageClusterGroup;
private LinearDoubleClusterGroup softLinearClusterGroup;
@Before
public void initialize() {
@@ -34,49 +34,53 @@ public class TestLinearDoubleClusterGroup {
assertThat(cluster, nullValue());
cluster = softLinearClusterGroup.getClusterFor(-0.1);
Cluster<Double> expectedCluster = createCluster(0, 0, 10);
Cluster<Double> expectedCluster = createCluster(softLinearClusterGroup.getStepSize(), ComparisonStrategy.LOWER_THAN);
assertThat(cluster, is(expectedCluster));
cluster = softLinearClusterGroup.getClusterFor(100.1);
expectedCluster = createCluster(9, 0, 10);
expectedCluster = createCluster(softLinearClusterGroup.getUpperGroupBound() - softLinearClusterGroup.getStepSize(), ComparisonStrategy.GREATER_EQUALS_THAN);
assertThat(cluster, is(expectedCluster));
}
@Test
public void testGetClusterForBoundaryValues() {
Cluster<Double> cluster = hardPercentageClusterGroup.getClusterFor(0.0);
Cluster<Double> expectedCluster = createCluster(0, 0, 0.1);
Cluster<Double> expectedCluster = createCluster(hardPercentageClusterGroup.getLowerGroupBound(), ComparisonStrategy.GREATER_EQUALS_THAN,
hardPercentageClusterGroup.getLowerGroupBound() + hardPercentageClusterGroup.getStepSize(), ComparisonStrategy.LOWER_THAN);
assertThat(cluster, is(expectedCluster));
cluster = hardPercentageClusterGroup.getClusterFor(1.0);
expectedCluster = createCluster(9, 0, 0.1);
expectedCluster = createCluster(hardPercentageClusterGroup.getUpperGroupBound() - hardPercentageClusterGroup.getStepSize(), ComparisonStrategy.GREATER_EQUALS_THAN,
hardPercentageClusterGroup.getUpperGroupBound(), ComparisonStrategy.LOWER_EQUALS_THAN);
assertThat(cluster, is(expectedCluster));
cluster = softLinearClusterGroup.getClusterFor(0.0);
expectedCluster = createCluster(0, 0, 10);
expectedCluster = createCluster(softLinearClusterGroup.getStepSize(), ComparisonStrategy.LOWER_THAN);
assertThat(cluster, is(expectedCluster));
cluster = softLinearClusterGroup.getClusterFor(100.0);
expectedCluster = createCluster(9, 0, 10);
expectedCluster = createCluster(softLinearClusterGroup.getUpperGroupBound() - softLinearClusterGroup.getStepSize(), ComparisonStrategy.GREATER_EQUALS_THAN);
assertThat(cluster, is(expectedCluster));
}
@Test
public void testGetClusterFor() {
double value = -0.05;
double stepSize = 0.1;
for (int index = 0; index < 10; index++) {
value += stepSize;
Cluster<Double> cluster = hardPercentageClusterGroup.getClusterFor(value);
Cluster<Double> expectedCluster = createCluster(index, 0, stepSize);
assertThat(cluster, is(expectedCluster));
}
LinearDoubleClusterGroup clusterGroup = softLinearClusterGroup;
double value = (clusterGroup.getUpperGroupBound() + clusterGroup.getStepSize()) / 2;
Cluster<Double> cluster = clusterGroup.getClusterFor(value);
Cluster<Double> expectedCluster = createCluster(clusterGroup.getUpperGroupBound() / 2, ComparisonStrategy.GREATER_EQUALS_THAN,
(clusterGroup.getUpperGroupBound() / 2) + clusterGroup.getStepSize(), ComparisonStrategy.LOWER_THAN);
assertThat(cluster, is(expectedCluster));
}
private Cluster<Double> createCluster(int index, double lowerBoundValue, double stepSize) {
ComparableClusterBoundary<Double> lowerBound = new ComparableClusterBoundary<Double>(lowerBoundValue + stepSize * index, ComparisonStrategy.GREATER_EQUALS_THAN);
ComparableClusterBoundary<Double> upperBound = new ComparableClusterBoundary<Double>(lowerBoundValue + stepSize * (index + 1), ComparisonStrategy.LOWER_THAN);
private Cluster<Double> createCluster(double lowerBoundValue, ComparisonStrategy lowerComparisonStrategy, double upperBoundValue, ComparisonStrategy upperComparisonStrategy) {
ComparableClusterBoundary<Double> lowerBound = new ComparableClusterBoundary<>(lowerBoundValue, lowerComparisonStrategy);
ComparableClusterBoundary<Double> upperBound = new ComparableClusterBoundary<>(upperBoundValue, upperComparisonStrategy);
return new ClusterWithLowerAndUpperBoundaries<>(lowerBound, upperBound);
}
private Cluster<Double> createCluster(double boundValue, ComparisonStrategy comparisonStrategy) {
return new ClusterWithSingleBoundary<>(new ComparableClusterBoundary<>(boundValue, comparisonStrategy));
}
}
@@ -6,6 +6,7 @@ import java.util.Map;
import com.sap.sse.datamining.data.Cluster;
import com.sap.sse.datamining.data.ClusterGroup;
import com.sap.sse.datamining.impl.data.ClusterWithLowerAndUpperBoundaries;
import com.sap.sse.datamining.impl.data.ClusterWithSingleBoundary;
import com.sap.sse.datamining.impl.data.ComparableClusterBoundary;
import com.sap.sse.datamining.impl.data.ComparisonStrategy;
@@ -19,6 +20,7 @@ public class LinearDoubleClusterGroup implements ClusterGroup<Double> {
private final boolean hardBounds;
private final transient Map<Integer, Cluster<Double>> clusterCache;
private final int lastClusterIndex;
public LinearDoubleClusterGroup(double lowerBound, double upperBound, double stepSize, boolean hardBounds) {
this.lowerBound = lowerBound;
@@ -27,35 +29,10 @@ public class LinearDoubleClusterGroup implements ClusterGroup<Double> {
this.hardBounds = hardBounds;
clusterCache = new HashMap<>();
lastClusterIndex = calculateLastClusterIndex(this.upperBound, this.stepSize);
}
@Override
public Cluster<Double> getClusterFor(Double valueObject) {
double value = valueObject.doubleValue();
if (value < lowerBound) {
return hardBounds ? null : getCluster(0);
}
if (value > upperBound) {
return hardBounds ? null : getCluster(getLastClusterIndex());
}
if (Math.abs(upperBound - value) < 0.0001) {
return getCluster(getLastClusterIndex());
}
return getCluster((int) (value / stepSize));
}
private Cluster<Double> getCluster(int index) {
if (!clusterCache.containsKey(index)) {
ComparableClusterBoundary<Double> lowerBound = new ComparableClusterBoundary<Double>(this.lowerBound + stepSize * index, ComparisonStrategy.GREATER_EQUALS_THAN);
ComparableClusterBoundary<Double> upperBound = new ComparableClusterBoundary<Double>(this.lowerBound + stepSize * (index + 1), ComparisonStrategy.LOWER_THAN);
Cluster<Double> cluster = new ClusterWithLowerAndUpperBoundaries<>(lowerBound, upperBound);
clusterCache.put(index, cluster);
}
return clusterCache.get(index);
}
private int getLastClusterIndex() {
private static int calculateLastClusterIndex(double upperBound, double stepSize) {
double doubleIndex = upperBound / stepSize;
int index = (int) doubleIndex;
double fractionalPart = doubleIndex - index;
@@ -65,9 +42,69 @@ public class LinearDoubleClusterGroup implements ClusterGroup<Double> {
return index;
}
@Override
public Cluster<Double> getClusterFor(Double valueObject) {
double value = valueObject.doubleValue();
if (value < lowerBound) {
return hardBounds ? null : getCluster(0);
}
if (value > upperBound) {
return hardBounds ? null : getCluster(lastClusterIndex);
}
if (Math.abs(upperBound - value) < 0.0001) {
return getCluster(lastClusterIndex);
}
return getCluster((int) (value / stepSize));
}
private Cluster<Double> getCluster(int index) {
if (!clusterCache.containsKey(index)) {
clusterCache.put(index, createCluster(index));
}
return clusterCache.get(index);
}
private Cluster<Double> createCluster(int index) {
if (index == 0 && !hardBounds) {
return new ClusterWithSingleBoundary<>(createUpperBound(index, ComparisonStrategy.LOWER_THAN));
}
if (index == lastClusterIndex && !hardBounds) {
return new ClusterWithSingleBoundary<>(createLowerBound(index, ComparisonStrategy.GREATER_EQUALS_THAN));
}
ComparisonStrategy upperComparisonStrategy = index == lastClusterIndex ? ComparisonStrategy.LOWER_EQUALS_THAN : ComparisonStrategy.LOWER_THAN;
return new ClusterWithLowerAndUpperBoundaries<>(createLowerBound(index, ComparisonStrategy.GREATER_EQUALS_THAN),
createUpperBound(index, upperComparisonStrategy));
}
private ComparableClusterBoundary<Double> createLowerBound(int index, ComparisonStrategy comparisonStrategy) {
return new ComparableClusterBoundary<Double>(this.lowerBound + stepSize * index, comparisonStrategy);
}
private ComparableClusterBoundary<Double> createUpperBound(int index, ComparisonStrategy comparisonStrategy) {
return new ComparableClusterBoundary<Double>(this.lowerBound + stepSize * (index + 1.0), comparisonStrategy);
}
@Override
public Class<Double> getClusterElementsType() {
return Double.class;
}
public double getLowerGroupBound() {
return lowerBound;
}
public double getUpperGroupBound() {
return upperBound;
}
public double getStepSize() {
return stepSize;
}
public boolean isHardBounds() {
return hardBounds;
}
}