All Downloads are FREE. Search and download functionalities are using the official Maven repository.

gov.sandia.cognition.statistics.bayesian.BayesianUtil Maven / Gradle / Ivy

There is a newer version: 4.0.1
Show newest version
/*
 * File:                BayesianUtil.java
 * Authors:             Kevin R. Dixon
 * Company:             Sandia National Laboratories
 * Project:             Cognitive Foundry
 * 
 * Copyright Apr 7, 2010, 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.bayesian;

import gov.sandia.cognition.annotation.PublicationReference;
import gov.sandia.cognition.annotation.PublicationType;
import gov.sandia.cognition.math.UnivariateStatisticsUtil;
import gov.sandia.cognition.statistics.ClosedFormDistribution;
import gov.sandia.cognition.statistics.ComputableDistribution;
import gov.sandia.cognition.statistics.Distribution;
import gov.sandia.cognition.statistics.ProbabilityFunction;
import gov.sandia.cognition.statistics.distribution.UnivariateGaussian;
import gov.sandia.cognition.util.Pair;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Random;

/**
 * Contains generally useful utilities for Bayesian statistics.
 * @author Kevin R. Dixon
 * @since 3.0
 */
public class BayesianUtil
{

    /**
     * Computes the log likelihood of the i.i.d. data using the given
     * probability function.
     * @param 
     * Type of observations to consider
     * @param distribution
     * Computable distribution from which to get the probability function
     * (a pdf or pmf) used to compute the likelihood.
     * @param observations
     * Observations to compute the log likelihood of.
     * @return
     * Log likelihood of the i.i.d. data using the given probability function.
     */
    public static  double logLikelihood(
        final ComputableDistribution distribution,
        final Iterable observations )
    {
        ProbabilityFunction f =
            distribution.getProbabilityFunction();
        double logSum = 0.0;
        for( ObservationType observation : observations )
        {
            logSum += f.logEvaluate(observation);
        }
        return logSum;
    }

    /**
     * Samples from the given BayesianParameter by first sampling the prior
     * distribution, then updating the conditional distribution, then sampling
     * from the updated conditional distribution.
     * @param 
     * Type of observations generated by the conditional distribution
     * @param 
     * Type of parameters generated by the prior distribution, used to
     * update the conditional distribution
     * @param conditional
     * Conditional distribution that generates observations
     * @param parameterName
     * Name of the parameter in the conditional distribution that is
     * generated according to the prior distribution
     * @param prior
     * Prior distribution of parameter values
     * @param random
     * Random number generator
     * @param numSamples
     * Number of samples to generate
     * @return
     * Samples from the given BayesianParameter by first sampling the prior
     * distribution, then updating the conditional distribution, then sampling
     * from the updated conditional distribution.
     */
    public static  ArrayList sample(
        final ClosedFormDistribution conditional,
        final String parameterName,
        final Distribution prior,
        final Random random,
        final int numSamples )
    {
        DefaultBayesianParameter,Distribution> parameter =
            new DefaultBayesianParameter, Distribution>( conditional, parameterName, prior );
        return sample( parameter, random, numSamples );
    }

    /**
     * Samples from the given BayesianParameter by first sampling the prior
     * distribution, then updating the conditional distribution, then sampling
     * from the updated conditional distribution.
     * @param 
     * Type of observations generated by the conditional distribution
     * @param 
     * Type of parameters generated by the prior distribution, used to
     * update the conditional distribution
     * @param parameter
     * BayesianParameter that links the conditional distribution via a
     * parameter to a prior distribution.
     * @param random
     * Random number generator
     * @param numSamples
     * Number of samples to generate
     * @return
     * Samples from the given BayesianParameter by first sampling the prior
     * distribution, then updating the conditional distribution, then sampling
     * from the updated conditional distribution.
     */
    public static  ArrayList sample(
        final BayesianParameter,? extends Distribution> parameter,
        final Random random,
        final int numSamples )
    {
        ArrayList parameters =
            parameter.getParameterPrior().sample(random, numSamples);
        ArrayList samples =
            new ArrayList( numSamples );
        for( int n = 0; n < numSamples; n++ )
        {
            parameter.setValue( parameters.get(n) );
            samples.add( parameter.getConditionalDistribution().sample(random) );
        }
        return samples;
    }


    /**
     * Computes the deviance of the model, which is
     * -2log(p(observations|parameter)).  This is proportional to the mean
     * squared error if the model is normal with constant variance.
     * @param 
     * @param conditional
     * Conditional distribution that generates observations.
     * @param observations
     * Observations to consider
     * @return
     * Deviance of the model.
     */
    @PublicationReference(
        author={
            "Andrew Gelman",
            "John B. Carlin",
            "Hal S. Stern",
            "Donald B. Rubin"
        },
        title="Bayesian Data Analysis, Second Edition",
        type=PublicationType.Book,
        year=2004,
        pages={180,181},
        notes="Equation 6.6"
    )
    public static  double deviance(
        final ComputableDistribution conditional,
        final Iterable observations )
    {
        return -2.0 * logLikelihood(conditional, observations);
    }

    /**
     * Computes the expected deviance of the model by sampling parameters from
     * the posterior and then computing the deviance using the conditional
     * distribution. This is also proportional to the Kullback-Leibler
     * divergence of the posterior up to an additive constant.
     * In the limit of infinite data, the model with the lowest expected
     * deviance will have the highest posterior probability.
     * @param 
     * Type of observations generated by the conditional distribution.
     * @param 
     * Type of parameters generated by the posterior distribution.
     * @param predictiveDistribution
     * Relationship between the posterior (parameters) and the conditional
     * (observations).
     * @param observations
     * Observations to consider when computing the deviance
     * @param random
     * Random number generator
     * @param numSamples
     * Number of samples to use in the expectation.
     * @return
     * Expected deviance of the model.
     */
    @PublicationReference(
        author={
            "Andrew Gelman",
            "John B. Carlin",
            "Hal S. Stern",
            "Donald B. Rubin"
        },
        title="Bayesian Data Analysis, Second Edition",
        type=PublicationType.Book,
        year=2004,
        pages={180,181},
        notes="Equation 6.9"
    )
    public static  UnivariateGaussian expectedDeviance(
        final BayesianParameter,?> predictiveDistribution,
        final Iterable observations,
        final Random random,
        final int numSamples )
    {

        ArrayList parameters =
            predictiveDistribution.getParameterPrior().sample(random, numSamples);
        ArrayList deviances = new ArrayList( parameters.size() );
        for( ParameterType parameter : parameters )
        {
            predictiveDistribution.setValue(parameter);
            deviances.add( deviance(
                predictiveDistribution.getConditionalDistribution(), observations ) );
        }

        return UnivariateGaussian.MaximumLikelihoodEstimator.learn(deviances,0.0);

    }

    /**
     * Computes the Monte Carlo distribution of the given samples.
     * @param samples
     * Samples to consider.
     * @return
     * Distribution describing the mean and estimated variance of the mean
     * of the samples.
     */
    public static UnivariateGaussian getMean(
        final Collection samples)
    {
        Pair pair = UnivariateStatisticsUtil.computeMeanAndVariance(samples);
        double mean = pair.getFirst();
        double variance = pair.getSecond() / samples.size();
        return new UnivariateGaussian( mean, variance );
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy