/* * File: PartitionalClustererTest.java * Authors: Natasha Singh-Miller * Company: Sandia National Laboratories * Project: Cognitive Foundry * * Copyright February 25, 2011, Sandia Corporation. Under the terms of Contract * DE-AC04-94AL85000, there is a non-exclusive license for use of this work by * or on behalf of the U.S. Government. Export of this program may require a * license from the United States Government. See CopyrightHistory.txt for * complete details. * */ package gov.sandia.cognition.learning.algorithm.clustering; import gov.sandia.cognition.learning.algorithm.clustering.cluster.CentroidCluster; import junit.framework.TestCase; import gov.sandia.cognition.learning.algorithm.clustering.hierarchy.BinaryClusterHierarchyNode; import gov.sandia.cognition.learning.algorithm.clustering.cluster.NormalizedCentroidCluster; import gov.sandia.cognition.learning.algorithm.clustering.hierarchy.ClusterHierarchyNode; import gov.sandia.cognition.learning.algorithm.clustering.divergence.WithinClusterDivergence; import gov.sandia.cognition.learning.algorithm.clustering.divergence.WithinNormalizedCentroidClusterCosineDivergence; import gov.sandia.cognition.learning.algorithm.clustering.cluster.NormalizedCentroidClusterCreator; import gov.sandia.cognition.learning.algorithm.clustering.cluster.VectorMeanCentroidClusterCreator; import gov.sandia.cognition.learning.algorithm.clustering.divergence.CentroidClusterDivergenceFunction; import gov.sandia.cognition.learning.function.distance.CosineDistanceMetric; import gov.sandia.cognition.learning.function.distance.EuclideanDistanceMetric; import java.util.ArrayList; import gov.sandia.cognition.math.matrix.Vector; import gov.sandia.cognition.math.matrix.Vectorizable; import gov.sandia.cognition.math.matrix.mtj.Vector2; import java.util.Arrays; import java.util.Collection; import java.util.Random; /** * Unit tests for class PartitionalClusterer. * * @author Natasha Singh-Miller * @author Andrew Fisher * @since 3.1.1 */ public class PartitionalClustererTest extends TestCase { protected Random random = new Random(211); protected CosineDistanceMetric cosineDistanceMetric; protected VectorMeanCentroidClusterCreator creator; protected NormalizedCentroidClusterCreator norm_creator; protected CentroidClusterDivergenceFunction<Vector> clusterDivergenceFunction; protected WithinClusterDivergence<NormalizedCentroidCluster<Vectorizable>, Vectorizable> withinClusterDivergenceFunction; protected ArrayList<Vector> data; /** * Creates a new test. * * @param testName The name. */ public PartitionalClustererTest( String testName) { super(testName); this.cosineDistanceMetric = CosineDistanceMetric.INSTANCE; this.creator = VectorMeanCentroidClusterCreator.INSTANCE; this.norm_creator = new NormalizedCentroidClusterCreator(); this.clusterDivergenceFunction = new CentroidClusterDivergenceFunction<Vector>( this.cosineDistanceMetric); this.withinClusterDivergenceFunction = new WithinNormalizedCentroidClusterCosineDivergence<>(); Vector[] data1 = new Vector[] { new Vector2(-2.0, -2.0), new Vector2(-1.0, -1.01), new Vector2(-2.01, -2.02), new Vector2(-1.99, -1.98), new Vector2(-1.5, -1.54), new Vector2(-0.99, -0.98), new Vector2(-1.1, -1.0), }; Vector[] data2 = new Vector[] { new Vector2(2.0, 2.0), new Vector2(2.1, 2.2), new Vector2(1.0, 1.01), new Vector2(1.0, 0.99), new Vector2(0.3, 0.32), new Vector2(0.6, 0.59), new Vector2(1.7, 1.71) }; Vector[] data3 = new Vector[] { new Vector2(2.5, -2.51), new Vector2(3.2, -3.1), new Vector2(4.0, -4.04), new Vector2(1.3, -1.33), new Vector2(1.6, -1.59), new Vector2(2.0, -2.01), new Vector2(4.5, -4.4) }; ArrayList<Vector> data = new ArrayList<>(); data.addAll(Arrays.asList(data1)); data.addAll(Arrays.asList(data2)); data.addAll(Arrays.asList(data3)); this.data = data; } /** * Test of constants of class PartitionClusterer. */ public void testConstants() { assertEquals(1.0, PartitionalClusterer.DEFAULT_MAX_CRITERION_DECREASE); assertEquals(1, PartitionalClusterer.DEFAULT_MIN_CLUSTER_SIZE); assertEquals(Integer.MAX_VALUE, PartitionalClusterer.DEFAULT_MAX_ITERATIONS); } /** * Test of constructors of class PartitionClusterer. */ public void testWithinDivergenceConstructors() { PartitionalClusterer<Vectorizable, NormalizedCentroidCluster<Vectorizable>> instance = new PartitionalClusterer<>(99, this.withinClusterDivergenceFunction, this.norm_creator); assertSame(this.withinClusterDivergenceFunction, instance.getWithinClusterDivergenceFunction()); assertSame(this.norm_creator, instance.getCreator()); assertEquals(instance.getMaxCriterionDecrease(), PartitionalClusterer.DEFAULT_MAX_CRITERION_DECREASE); assertEquals(instance.getMinClusterSize(), PartitionalClusterer.DEFAULT_MIN_CLUSTER_SIZE); int minClusterSize = 4; double maxCriterionDecrease = 0.95; instance.setMinClusterSize(minClusterSize); instance.setMaxCriterionDecrease(maxCriterionDecrease); instance.setRandom(random); assertEquals(minClusterSize, instance.getMinClusterSize()); assertEquals(instance.getMaxCriterionDecrease(), maxCriterionDecrease); assertSame(random, instance.getRandom()); int numRequestedClusters = 99; assertEquals(numRequestedClusters, instance.getNumRequestedClusters()); } /** * Test of constructors of class PartitionClusterer. */ public void testDivergenceConstructors() { PartitionalClusterer<Vector, CentroidCluster<Vector>> instance = new PartitionalClusterer<>(99, this.clusterDivergenceFunction, this.creator); assertSame(this.clusterDivergenceFunction, instance.getDivergenceFunction()); assertSame(this.creator, instance.getCreator()); assertEquals(instance.getMaxCriterionDecrease(), PartitionalClusterer.DEFAULT_MAX_CRITERION_DECREASE); assertEquals(instance.getMinClusterSize(), PartitionalClusterer.DEFAULT_MIN_CLUSTER_SIZE); int minClusterSize = 4; double maxCriterionDecrease = 0.95; instance.setMinClusterSize(minClusterSize); instance.setMaxCriterionDecrease(maxCriterionDecrease); instance.setRandom(random); assertEquals(minClusterSize, instance.getMinClusterSize()); assertEquals(instance.getMaxCriterionDecrease(), maxCriterionDecrease); assertSame(random, instance.getRandom()); int numRequestedClusters = 99; assertEquals(numRequestedClusters, instance.getNumRequestedClusters()); } /** * Test of clone method, of class PartitionClusterer. */ public void testClone() { PartitionalClusterer<Vector, CentroidCluster<Vector>> instance = new PartitionalClusterer<>(99, this.clusterDivergenceFunction, this.creator); instance.setMinClusterSize(4); instance.setMaxCriterionDecrease(0.95); instance.setRandom(random); PartitionalClusterer<Vector, CentroidCluster<Vector>> clone = instance.clone(); assertNotNull(clone); assertNotSame(instance, clone); assertNotNull(clone.getDivergenceFunction()); assertNotSame(instance.getDivergenceFunction(), clone.getDivergenceFunction()); assertNotNull(clone.getCreator()); assertNotSame(instance.getCreator(), clone.getCreator()); assertNotNull(clone.getRandom()); PartitionalClusterer<Vectorizable, NormalizedCentroidCluster<Vectorizable>> norm_instance = new PartitionalClusterer<>(99, this.withinClusterDivergenceFunction, this.norm_creator); norm_instance.setMinClusterSize(4); norm_instance.setMaxCriterionDecrease(0.95); norm_instance.setRandom(random); PartitionalClusterer<Vectorizable, NormalizedCentroidCluster<Vectorizable>> norm_clone = norm_instance.clone(); assertNotNull(norm_clone); assertNotSame(norm_instance, norm_clone); assertNotNull(clone.getWithinClusterDivergenceFunction()); assertNotSame(instance.getWithinClusterDivergenceFunction(), clone.getWithinClusterDivergenceFunction()); assertNotNull(clone.getCreator()); assertNotSame(instance.getCreator(), clone.getCreator()); assertNotNull(clone.getRandom()); } /** * Test of cluster method, of class PartitionClusterer. */ public void testCluster() { PartitionalClusterer<Vector, CentroidCluster<Vector>> instance = PartitionalClusterer.create(Integer.MAX_VALUE); PartitionalClusterer<Vectorizable, NormalizedCentroidCluster<Vectorizable>> norm_instance = PartitionalClusterer.createSpherical(Integer.MAX_VALUE); instance.setNumRequestedClusters(2); Collection<CentroidCluster<Vector>> clusters = instance.learn(this.data); assertEquals(2, clusters.size()); assertEquals(3, instance.getClusterCount()); instance.setNumRequestedClusters(3); clusters = instance.learn(this.data); assertEquals(3, clusters.size()); assertEquals(5, instance.getClusterCount()); ClusterHierarchyNode<Vector, CentroidCluster<Vector>> root = instance.clusterHierarchically(this.data); assertNotNull(root); assertNotNull(root.getCluster()); assertEquals(2, root.getChildren().size()); assertTrue(root instanceof BinaryClusterHierarchyNode<?, ?>); assertEquals(21, root.getMembers().size()); norm_instance.setNumRequestedClusters(2); Collection<NormalizedCentroidCluster<Vectorizable>> norm_clusters = norm_instance.learn(this.data); assertEquals(2, norm_clusters.size()); assertEquals(3, norm_instance.getClusterCount()); norm_instance.setNumRequestedClusters(3); norm_clusters = norm_instance.learn(this.data); assertEquals(3, norm_clusters.size()); assertEquals(5, norm_instance.getClusterCount()); ClusterHierarchyNode<Vectorizable, NormalizedCentroidCluster<Vectorizable>> norm_root = norm_instance.clusterHierarchically(this.data); assertNotNull(norm_root); assertNotNull(norm_root.getCluster()); assertEquals(2, norm_root.getChildren().size()); assertTrue(norm_root instanceof BinaryClusterHierarchyNode<?, ?>); assertEquals(21, norm_root.getMembers().size()); } public void testLearnOnDemand() { PartitionalClusterer<Vectorizable, NormalizedCentroidCluster<Vectorizable>> norm_instance = PartitionalClusterer.createSpherical(Integer.MAX_VALUE); norm_instance.setNumRequestedClusters(2); Collection<NormalizedCentroidCluster<Vectorizable>> norm_clusters = norm_instance.learnUsingCachedClusters(this.data); assertEquals(2, norm_clusters.size()); assertEquals(3, norm_instance.getClusterCount()); norm_clusters = norm_instance.learnUsingCachedClusters(this.data); assertEquals(2, norm_clusters.size()); assertEquals(3, norm_instance.getClusterCount()); norm_instance.setNumRequestedClusters(3); norm_clusters = norm_instance.learnUsingCachedClusters(this.data); assertEquals(3, norm_clusters.size()); assertEquals(5, norm_instance.getClusterCount()); norm_instance.setNumRequestedClusters(2); norm_clusters = norm_instance.learnUsingCachedClusters(this.data); assertEquals(2, norm_clusters.size()); assertEquals(5, norm_instance.getClusterCount()); norm_instance.setNumRequestedClusters(1); norm_clusters = norm_instance.learnUsingCachedClusters(this.data); assertEquals(1, norm_clusters.size()); assertEquals(5, norm_instance.getClusterCount()); } /** * Test of getClusterCount method, of class PartitionClusterer. */ public void testGetClusterCount() { PartitionalClusterer<Vector, CentroidCluster<Vector>> instance = new PartitionalClusterer<>(0, clusterDivergenceFunction, creator); assertEquals(0, instance.getClusterCount()); PartitionalClusterer<Vectorizable, NormalizedCentroidCluster<Vectorizable>> norm_instance = new PartitionalClusterer<>(0, withinClusterDivergenceFunction, norm_creator); assertEquals(0, norm_instance.getClusterCount()); } /** * Test of getDivergenceFunction method, of class PartitionClusterer. */ public void testGetDivergenceFunction() { this.testSetDivergenceFunction(); } /** * Test of setDivergenceFunction method, of class PartitionClusterer. */ public void testSetDivergenceFunction() { CentroidClusterDivergenceFunction<Vector> newDivFct = new CentroidClusterDivergenceFunction<>( EuclideanDistanceMetric.INSTANCE); PartitionalClusterer<Vector, CentroidCluster<Vector>> instance = new PartitionalClusterer<>(0, newDivFct, creator); instance.setDivergenceFunction(this.clusterDivergenceFunction); assertNotSame(newDivFct, instance.getDivergenceFunction()); assertSame(this.clusterDivergenceFunction, instance.getDivergenceFunction()); boolean exceptionThrown = false; try { instance.setDivergenceFunction(null); } catch (IllegalArgumentException e) { exceptionThrown = true; } finally { assertTrue(exceptionThrown); } } /** * Test of setDivergenceFunction method, of class PartitionClusterer. */ public void testSetWithinDivergenceFunction() { WithinClusterDivergence<NormalizedCentroidCluster<Vectorizable>, Vectorizable> newDivFct = new WithinNormalizedCentroidClusterCosineDivergence<>(); PartitionalClusterer<Vectorizable, NormalizedCentroidCluster<Vectorizable>> instance = new PartitionalClusterer<>(0, newDivFct, norm_creator); instance.setWithinClusterDivergenceFunction( this.withinClusterDivergenceFunction); assertNotSame(newDivFct, instance.getDivergenceFunction()); assertSame(this.withinClusterDivergenceFunction, instance.getWithinClusterDivergenceFunction()); boolean exceptionThrown = false; try { instance.setWithinClusterDivergenceFunction(null); } catch (IllegalArgumentException e) { exceptionThrown = true; } finally { assertTrue(exceptionThrown); } } /** * Test of setCreator method, of class PartitionClusterer. */ public void testSetCreator() { PartitionalClusterer<Vector, CentroidCluster<Vector>> instance = new PartitionalClusterer<>(5, this.clusterDivergenceFunction, this.creator); VectorMeanCentroidClusterCreator creator2 = new VectorMeanCentroidClusterCreator(); assertNotNull(instance.getCreator()); instance.setCreator(creator2); assertNotSame(this.creator, instance.getCreator()); assertSame(creator2, instance.getCreator()); boolean exceptionThrown = false; try { instance.setCreator(null); } catch (IllegalArgumentException e) { exceptionThrown = true; } finally { assertTrue(exceptionThrown); } PartitionalClusterer<Vectorizable, NormalizedCentroidCluster<Vectorizable>> norm_instance = new PartitionalClusterer<>(5, this.withinClusterDivergenceFunction, this.norm_creator); NormalizedCentroidClusterCreator norm_creator2 = new NormalizedCentroidClusterCreator(); norm_instance.setCreator(norm_creator2); assertNotSame(this.norm_creator, norm_instance.getCreator()); assertSame(norm_creator2, norm_instance.getCreator()); exceptionThrown = false; try { instance.setCreator(null); } catch (IllegalArgumentException e) { exceptionThrown = true; } finally { assertTrue(exceptionThrown); } } /** * Test of getMinClusterSize method, of class PartitionClusterer. */ public void testGetMinClusterSizes() { this.testSetMinClusterSize(); } /** * Test of setMinNumClusters method, of class PartitionClusterer. */ public void testSetMinClusterSize() { PartitionalClusterer<Vector, CentroidCluster<Vector>> instance = new PartitionalClusterer<>(5, this.clusterDivergenceFunction, this.creator); assertEquals(PartitionalClusterer.DEFAULT_MIN_CLUSTER_SIZE, instance.getMinClusterSize()); int minClusterSize = 4; instance.setMinClusterSize(minClusterSize); assertEquals(minClusterSize, instance.getMinClusterSize()); boolean exceptionThrown = false; try { instance.setMinClusterSize(-3); } catch (IllegalArgumentException e) { exceptionThrown = true; } finally { assertTrue(exceptionThrown); } assertEquals(minClusterSize, instance.getMinClusterSize()); PartitionalClusterer<Vectorizable, NormalizedCentroidCluster<Vectorizable>> norm_instance = new PartitionalClusterer<>(5, this.withinClusterDivergenceFunction, this.norm_creator); assertEquals(PartitionalClusterer.DEFAULT_MIN_CLUSTER_SIZE, norm_instance.getMinClusterSize()); norm_instance.setMinClusterSize(minClusterSize); assertEquals(minClusterSize, norm_instance.getMinClusterSize()); try { norm_instance.setMinClusterSize(-3); } catch (IllegalArgumentException e) { exceptionThrown = true; } finally { assertTrue(exceptionThrown); } assertEquals(minClusterSize, norm_instance.getMinClusterSize()); } /** * Test of getMaxCriterionDecrease method, of class PartitionClusterer. */ public void testGetMaxCriterionDecrease() { this.testSetMaxCriterionDecrease(); } /** * Test of setMaxCriterionDecrease method, of class PartitionClusterer. */ public void testSetMaxCriterionDecrease() { PartitionalClusterer<Vector, CentroidCluster<Vector>> instance = new PartitionalClusterer<>(5, this.clusterDivergenceFunction, this.creator); assertEquals(PartitionalClusterer.DEFAULT_MAX_CRITERION_DECREASE, instance.getMaxCriterionDecrease()); double maxCriterionDecrease = this.random.nextDouble(); instance.setMaxCriterionDecrease(maxCriterionDecrease); assertEquals(maxCriterionDecrease, instance.getMaxCriterionDecrease()); boolean exceptionThrown = false; try { instance.setMaxCriterionDecrease(-this.random.nextDouble()); } catch (IllegalArgumentException e) { exceptionThrown = true; } finally { assertTrue(exceptionThrown); } assertEquals(maxCriterionDecrease, instance.getMaxCriterionDecrease()); PartitionalClusterer<Vectorizable, NormalizedCentroidCluster<Vectorizable>> norm_instance = new PartitionalClusterer<>(5, this.withinClusterDivergenceFunction, this.norm_creator); assertEquals(PartitionalClusterer.DEFAULT_MAX_CRITERION_DECREASE, norm_instance.getMaxCriterionDecrease()); norm_instance.setMaxCriterionDecrease(maxCriterionDecrease); assertEquals(maxCriterionDecrease, norm_instance.getMaxCriterionDecrease()); try { norm_instance.setMaxCriterionDecrease(-this.random.nextDouble()); } catch (IllegalArgumentException e) { exceptionThrown = true; } finally { assertTrue(exceptionThrown); } assertEquals(maxCriterionDecrease, norm_instance.getMaxCriterionDecrease()); } }