/*
* File: MixtureOfGaussiansTest.java
* Authors: Kevin R. Dixon
* Company: Sandia National Laboratories
* Project: Cognitive Foundry
*
* Copyright August 1, 2006, 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.statistics.distribution;
import gov.sandia.cognition.learning.algorithm.clustering.KMeansClusterer;
import gov.sandia.cognition.learning.algorithm.clustering.cluster.GaussianCluster;
import gov.sandia.cognition.learning.algorithm.clustering.cluster.GaussianClusterCreator;
import gov.sandia.cognition.learning.algorithm.clustering.divergence.GaussianClusterDivergenceFunction;
import gov.sandia.cognition.learning.algorithm.clustering.initializer.NeighborhoodGaussianClusterInitializer;
import gov.sandia.cognition.math.matrix.VectorFactory;
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.statistics.method.KolmogorovSmirnovConfidence;
import gov.sandia.cognition.util.NamedValue;
import java.util.Random;
import java.util.ArrayList;
import java.util.Arrays;
/**
* Test for class MixtureOfGaussians
* @author krdixon
*/
public class MixtureOfGaussiansTest
extends MultivariateMixtureDensityModelTest
{
public MixtureOfGaussiansTest(
String testName)
{
super(testName);
}
@Override
public MixtureOfGaussians.PDF createInstance()
{
return createMixture(3, 2, RANDOM);
}
/**
* Tests the Learner
*/
public void testLearner()
{
System.out.println( "Learner" );
int N = 2;
double r = 2.0;
double rC = 0.5;
Matrix s1 = MatrixFactory.getDefault().createUniformRandom( N, N, -rC, rC, RANDOM );
Matrix C1 = s1.transpose().times( s1 );
Vector m1 = VectorFactory.getDefault().createUniformRandom(N, -r, r, RANDOM );
Matrix s2 = MatrixFactory.getDefault().createUniformRandom( N, N, -rC, rC, RANDOM );
Matrix C2 = s2.transpose().times( s2 );
Vector m2 = VectorFactory.getDefault().createUniformRandom(N, -r, r, RANDOM );
double p1 = RANDOM.nextDouble();
double[] p = new double[]{ p1, 1.0-p1 };
ArrayList<MultivariateGaussian.PDF> gs = new ArrayList<MultivariateGaussian.PDF>(
Arrays.asList( new MultivariateGaussian.PDF( m1, C1 ),
new MultivariateGaussian.PDF( m2, C2 ) ) );
MixtureOfGaussians.PDF mog = new MixtureOfGaussians.PDF( gs, p );
ArrayList<Vector> samples = mog.sample(RANDOM, 10*NUM_SAMPLES);
System.out.println( "MOG: " + mog );
int k = 2;
KMeansClusterer<Vector,GaussianCluster> kmeans =
new KMeansClusterer<Vector,GaussianCluster>( k, 100,
new NeighborhoodGaussianClusterInitializer(RANDOM),
GaussianClusterDivergenceFunction.INSTANCE,
new GaussianClusterCreator() );
MixtureOfGaussians.Learner learner =
new MixtureOfGaussians.Learner( kmeans );
learner.learn(samples);
MixtureOfGaussians.PDF moghat = learner.getResult();
System.out.println( "moghat: " + moghat );
assertEquals( 2, moghat.getDistributionCount() );
// This is kludgey, but I can't think of a better way to get the
// automated test that I'm looking for...
// -- krdixon, 2009-03-04
// Vector phat = moghat.getPriorProbabilities();
// System.out.println( "Delta: " + p.minus(phat) );
// assertTrue( p.equals( phat, 1e-2 ) );
// Vector m1hat = moghat.getRandomVariables().get(0).getMean();
// assertTrue( m1.equals( m1hat, 1e-2 ) );
//
// Vector m2hat = moghat.getRandomVariables().get(1).getMean();
// assertTrue( m2.equals( m2hat, 1e-2 ) );
NamedValue<? extends Number> value = learner.getPerformance();
assertNotNull( value );
System.out.println( "Value: " + value.getName() + " = " + value.getValue() );
MixtureOfGaussians.Learner l2 = new MixtureOfGaussians.Learner(null);
try
{
l2.getResult();
fail( "Null pointer exception" );
}
catch (Exception e)
{
System.out.println( "Good: " + e );
}
}
public void testComputeWeightedZ()
{
System.out.println( "computeWeightedZ" );
int numGaussians = 2;
int numDimensions = 2;
MixtureOfGaussians.PDF mog = createMixture(numGaussians, numDimensions, RANDOM);
ArrayList<Vector> samples = mog.sample(RANDOM, NUM_SAMPLES);
ArrayList<Double> zs = new ArrayList<Double>( samples.size() );
for( Vector input : samples )
{
double z = mog.computeWeightedZSquared(input);
zs.add( z );
}
ChiSquareDistribution.CDF chi = new ChiSquareDistribution.CDF(numDimensions);
KolmogorovSmirnovConfidence.Statistic kstest =
KolmogorovSmirnovConfidence.evaluateNullHypothesis(zs, chi);
System.out.println( "K-S test: " + kstest );
final double confidence = 0.95;
assertEquals( 1.0, kstest.getNullHypothesisProbability(), confidence );
}
/**
* Test of fitSingleGaussian method, of class gov.sandia.isrc.math.MultivariateGaussian.
*/
public void testFitSingleGaussian()
{
System.out.println( "fitSingleGaussian" );
int num = (int) (this.RANDOM.nextDouble() * 5) + 2;
int dim = 2;
MixtureOfGaussians.PDF mixture = MixtureOfGaussiansTest.createMixture( num, dim, RANDOM );
ArrayList<Vector> draws = mixture.sample( RANDOM, NUM_SAMPLES );
MultivariateGaussian sample =
MultivariateGaussian.MaximumLikelihoodEstimator.learn( draws, 0.0 );
MultivariateGaussian result = mixture.fitSingleGaussian();
double tolerance = 10 * dim * dim / (2 * Math.log( NUM_SAMPLES ));
double EPSILON = 1e-5;
System.out.println( "Tolerance = " + tolerance );
System.out.println( "Mean: Mixture: " + mixture.getMean() + " Result: " + result.getMean() + " Sample: " + sample.getMean() );
assertTrue( mixture.getMean().equals( result.getMean(), EPSILON ) );
assertTrue( sample.getMean().equals( result.getMean(), tolerance ) );
System.out.println( "Covariance:\nResult:\n" + result.getCovariance() + "\nSample:\n" + sample.getCovariance() );
System.out.println( "Tolerance: " + tolerance + " Residual:\n" + result.getCovariance().minus( sample.getCovariance() ) );
assertTrue( sample.getCovariance().equals( result.getCovariance(), tolerance ) );
}
@Override
public void testConstructors()
{
System.out.println( "Constructors" );
MultivariateGaussian g1 = new MultivariateGaussian();
MixtureOfGaussians.PDF instance =
new MixtureOfGaussians.PDF ( g1 );
assertEquals( 1, instance.getDistributionCount() );
assertSame( g1, instance.getDistributions().get(0) );
assertEquals( 1.0, instance.getPriorWeights()[0] );
MultivariateGaussian g2 = new MultivariateGaussian();
MixtureOfGaussians.PDF i2 =
new MixtureOfGaussians.PDF( g1, g2 );
instance = new MixtureOfGaussians.PDF( i2 );
assertEquals( i2.getDistributionCount(), instance.getDistributionCount() );
assertNotSame( i2.getDistributions(), instance.getDistributions() );
assertNotSame( i2.getPriorWeights(), instance.getPriorWeights() );
assertEquals( i2.getPriorWeightSum(), instance.getPriorWeightSum() );
}
@Override
public void testProbabilityFunctionConstructors()
{
System.out.println( "PDF Constructors" );
MultivariateGaussian g1 = new MultivariateGaussian();
MultivariateMixtureDensityModel.PDF<MultivariateGaussian> instance =
new MultivariateMixtureDensityModel.PDF<MultivariateGaussian>( Arrays.asList(g1) );
assertEquals( 1, instance.getDistributionCount() );
assertSame( g1, instance.getDistributions().get(0) );
assertEquals( 1.0, instance.getPriorWeights()[0] );
MultivariateGaussian g2 = new MultivariateGaussian();
MultivariateMixtureDensityModel.PDF<MultivariateGaussian> i2 =
new MultivariateMixtureDensityModel.PDF<MultivariateGaussian>( Arrays.asList(g1, g2) );
instance = new MultivariateMixtureDensityModel.PDF<MultivariateGaussian>( i2 );
assertEquals( i2.getDistributionCount(), instance.getDistributionCount() );
assertNotSame( i2.getDistributions(), instance.getDistributions() );
assertNotSame( i2.getPriorWeights(), instance.getPriorWeights() );
assertEquals( i2.getPriorWeightSum(), instance.getPriorWeightSum() );
}
/**
* EMLearner 2 Gaussians
*/
public void testEMLearner2Gaussians()
{
System.out.println( "EMLearner 2 Gaussians" );
ArrayList<MultivariateGaussian.PDF> gs = new ArrayList<MultivariateGaussian.PDF>( 2 );
int dim = 2;
gs.add( new MultivariateGaussian.PDF( VectorFactory.getDefault().createVector(dim, -1.0),
MatrixFactory.getDefault().createIdentity(dim, dim) ) );
gs.add( new MultivariateGaussian.PDF( VectorFactory.getDefault().createVector(dim, 1.0),
MatrixFactory.getDefault().createIdentity(dim, dim) ) );
MixtureOfGaussians.PDF target = new MixtureOfGaussians.PDF( gs );
ArrayList<Vector> samples = target.sample(RANDOM, NUM_SAMPLES);
MixtureOfGaussians.EMLearner learner =
new MixtureOfGaussians.EMLearner( 2, RANDOM );
MixtureOfGaussians.PDF estimate = learner.learn(samples);
}
}