/* * File: FisherLinearDiscriminantClassifierTest.java * Authors: Kevin R. Dixon * Company: Sandia National Laboratories * Project: Cognitive Foundry * * Copyright October 9, 2007, 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.function.categorization; import gov.sandia.cognition.learning.data.DefaultInputOutputPair; import gov.sandia.cognition.learning.function.scalar.LinearDiscriminant; import gov.sandia.cognition.statistics.distribution.MultivariateGaussian; import gov.sandia.cognition.learning.data.InputOutputPair; import gov.sandia.cognition.math.MultivariateStatisticsUtil; import gov.sandia.cognition.math.matrix.Matrix; import gov.sandia.cognition.math.matrix.MatrixFactory; import gov.sandia.cognition.math.matrix.Vector; import gov.sandia.cognition.math.matrix.mtj.Vector3; import gov.sandia.cognition.util.Pair; import java.util.ArrayList; /** * * @author Kevin R. Dixon */ public class FisherLinearDiscriminantBinaryCategorizerTest extends ThresholdBinaryCategorizerTestHarness<Vector> { /** * Constructor * @param testName Name */ public FisherLinearDiscriminantBinaryCategorizerTest( String testName) { super(testName); } public FisherLinearDiscriminantBinaryCategorizer createInstance() { Vector weights = this.createRandomInput(); double threshold = RANDOM.nextDouble(); return new FisherLinearDiscriminantBinaryCategorizer( weights, threshold ); } public void testConstructors() { System.out.println( "constructors" ); FisherLinearDiscriminantBinaryCategorizer instance = new FisherLinearDiscriminantBinaryCategorizer(); assertNotNull( instance ); assertEquals( FisherLinearDiscriminantBinaryCategorizer.DEFAULT_THRESHOLD, instance.getThreshold() ); assertNotNull( instance.getEvaluator() ); } /** * Test of clone method, of class gov.sandia.cognition.learning.util.function.FisherLinearDiscriminantClassifier. */ public void testCloneLocal() { System.out.println("clone local"); FisherLinearDiscriminantBinaryCategorizer instance = this.createInstance(); FisherLinearDiscriminantBinaryCategorizer clone = instance.clone(); assertNotSame( instance, clone ); assertNotSame( instance.getEvaluator(), clone.getEvaluator() ); assertNotSame( ((LinearDiscriminant) instance.getEvaluator()).getWeightVector(), ((LinearDiscriminant) clone.getEvaluator()).getWeightVector() ); assertEquals( ((LinearDiscriminant) instance.getEvaluator()).getWeightVector(), ((LinearDiscriminant) clone.getEvaluator()).getWeightVector() ); assertEquals( instance.getThreshold(), clone.getThreshold() ); } /** * Test of getEvaluator method, of class gov.sandia.cognition.learning.util.function.FisherLinearDiscriminantClassifier. */ public void testGetEvaluator() { System.out.println("getEvaluator"); FisherLinearDiscriminantBinaryCategorizer instance = this.createInstance(); assertNotNull( instance.getEvaluator() ); LinearDiscriminant d = (LinearDiscriminant) instance.getEvaluator(); instance.setEvaluator( null ); assertNull( instance.getEvaluator() ); instance.setEvaluator( d ); assertSame( d, instance.getEvaluator() ); } /** * Learn */ public void testLearn() { System.out.println( "ClosedFormSolver.learn" ); FisherLinearDiscriminantBinaryCategorizer.ClosedFormSolver learner = new FisherLinearDiscriminantBinaryCategorizer.ClosedFormSolver( 0.0 ); int num = 1000; double r = 1e-0; Vector m0 = this.createRandomInput(); int M = m0.getDimensionality(); Matrix A0 = MatrixFactory.getDefault().createUniformRandom( M, M, -r, r, RANDOM ); ArrayList<Vector> d0 = MultivariateGaussian.sample( m0, A0, RANDOM, num ); Vector m1 = this.createRandomInput(); Matrix A1 = MatrixFactory.getDefault().createUniformRandom( M, M, -r, r, RANDOM ); ArrayList<Vector> d1 = MultivariateGaussian.sample( m1, A1, RANDOM, num ); ArrayList<InputOutputPair<Vector,Boolean>> data = new ArrayList<InputOutputPair<Vector,Boolean>>( d0.size() + d1.size() ); for( int i = 0; i < d1.size(); i++ ) { data.add( new DefaultInputOutputPair<Vector,Boolean>( d1.get(i), true ) ); } for( int i = 0; i < d0.size(); i++ ) { data.add( new DefaultInputOutputPair<Vector,Boolean>( d0.get(i), false ) ); } FisherLinearDiscriminantBinaryCategorizer f = learner.learn( data ); assertEquals( M, ((LinearDiscriminant) f.getEvaluator()).getWeightVector().getDimensionality() ); Pair<Vector,Matrix> r0 = MultivariateStatisticsUtil.computeMeanAndCovariance(d0); Vector m0hat = r0.getFirst(); Matrix c0hat = r0.getSecond(); Pair<Vector,Matrix> r1 = MultivariateStatisticsUtil.computeMeanAndCovariance(d1); Vector m1hat = r1.getFirst(); Matrix c1hat = r1.getSecond(); Vector what = c1hat.plus( c0hat ).inverse().times( m1hat.minus( m0hat ) ); if( what.equals( ((LinearDiscriminant) f.getEvaluator()).getWeightVector(), TOLERANCE ) == false ) { assertEquals( what, ((LinearDiscriminant) f.getEvaluator()).getWeightVector() ); } } @Override public void testEvaluateWithoutThreshold() { System.out.println( "evaluateWithoutThreshold" ); Vector input = this.createRandomInput(); FisherLinearDiscriminantBinaryCategorizer f = this.createInstance(); assertEquals( input.dotProduct(((LinearDiscriminant) f.getEvaluator()).getWeightVector() ), f.evaluateWithoutThreshold(input), TOLERANCE ); } @Override public Vector createRandomInput() { return Vector3.createRandom(RANDOM); } }