Package aima.core.probability.bayes.approx

Source Code of aima.core.probability.bayes.approx.LikelihoodWeighting

package aima.core.probability.bayes.approx;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Random;

import aima.core.probability.CategoricalDistribution;
import aima.core.probability.RandomVariable;
import aima.core.probability.bayes.BayesianNetwork;
import aima.core.probability.proposition.AssignmentProposition;
import aima.core.probability.util.ProbUtil;
import aima.core.probability.util.ProbabilityTable;
import aima.core.util.JavaRandomizer;
import aima.core.util.Randomizer;
import aima.core.util.datastructure.Pair;

/**
* Artificial Intelligence A Modern Approach (3rd Edition): page 534.<br>
* <br>
*
* <pre>
* function LIKELIHOOD-WEIGHTING(X, e, bn, N) returns an estimate of <b>P</b>(X|e)
*   inputs: X, the query variable
*           e, observed values for variables E
*           bn, a Bayesian network specifying joint distribution <b>P</b>(X<sub>1</sub>,...,X<sub>n</sub>)
*           N, the total number of samples to be generated
*   local variables: W, a vector of weighted counts for each value of X, initially zero
*  
*   for j = 1 to N do
*       <b>x</b>,w <- WEIGHTED-SAMPLE(bn,e)
*       W[x] <- W[x] + w where x is the value of X in <b>x</b>
*   return NORMALIZE(W)
* --------------------------------------------------------------------------------------
* function WEIGHTED-SAMPLE(bn, e) returns an event and a weight
*  
*    w <- 1; <b>x</b> <- an event with n elements initialized from e
*    foreach variable X<sub>i</sub> in X<sub>1</sub>,...,X<sub>n</sub> do
*        if X<sub>i</sub> is an evidence variable with value x<sub>i</sub> in e
*            then w <- w * P(X<sub>i</sub> = x<sub>i</sub> | parents(X<sub>i</sub>))
*            else <b>x</b>[i] <- a random sample from <b>P</b>(X<sub>i</sub> | parents(X<sub>i</sub>))
*    return <b>x</b>, w
* </pre>
*
* Figure 14.15 The likelihood-weighting algorithm for inference in Bayesian
* networks. In WEIGHTED-SAMPLE, each nonevidence variable is sampled according
* to the conditional distribution given the values already sampled for the
* variable's parents, while a weight is accumulated based on the likelihood for
* each evidence variable.<br>
* <br>
* <b>Note:</b> The implementation has been extended to handle queries with
* multiple variables. <br>
*
* @author Ciaran O'Reilly
* @author Ravi Mohan
*/
public class LikelihoodWeighting implements BayesSampleInference {
  private Randomizer randomizer = null;

  public LikelihoodWeighting() {
    this(new JavaRandomizer(new Random()));
  }

  public LikelihoodWeighting(Randomizer r) {
    this.randomizer = r;
  }

  // function LIKELIHOOD-WEIGHTING(X, e, bn, N) returns an estimate of
  // <b>P</b>(X|e)
  /**
   * The LIKELIHOOD-WEIGHTING algorithm in Figure 14.15. For answering queries
   * given evidence in a Bayesian Network.
   *
   * @param X
   *            the query variables
   * @param e
   *            observed values for variables E
   * @param bn
   *            a Bayesian network specifying joint distribution
   *            <b>P</b>(X<sub>1</sub>,...,X<sub>n</sub>)
   * @param N
   *            the total number of samples to be generated
   * @return an estimate of <b>P</b>(X|e)
   */
  public CategoricalDistribution likelihoodWeighting(RandomVariable[] X,
      AssignmentProposition[] e, BayesianNetwork bn, int N) {
    // local variables: W, a vector of weighted counts for each value of X,
    // initially zero
    double[] W = new double[ProbUtil
        .expectedSizeOfCategoricalDistribution(X)];

    // for j = 1 to N do
    for (int j = 0; j < N; j++) {
      // <b>x</b>,w <- WEIGHTED-SAMPLE(bn,e)
      Pair<Map<RandomVariable, Object>, Double> x_w = weightedSample(bn,
          e);
      // W[x] <- W[x] + w where x is the value of X in <b>x</b>
      W[ProbUtil.indexOf(X, x_w.getFirst())] += x_w.getSecond();
    }
    // return NORMALIZE(W)
    return new ProbabilityTable(W, X).normalize();
  }

  // function WEIGHTED-SAMPLE(bn, e) returns an event and a weight
  /**
   * The WEIGHTED-SAMPLE function in Figure 14.15.
   *
   * @param e
   *            observed values for variables E
   * @param bn
   *            a Bayesian network specifying joint distribution
   *            <b>P</b>(X<sub>1</sub>,...,X<sub>n</sub>)
   * @return return <b>x</b>, w - an event with its associated weight.
   */
  public Pair<Map<RandomVariable, Object>, Double> weightedSample(
      BayesianNetwork bn, AssignmentProposition[] e) {
    // w <- 1;
    double w = 1.0;
    // <b>x</b> <- an event with n elements initialized from e
    Map<RandomVariable, Object> x = new LinkedHashMap<RandomVariable, Object>();
    for (AssignmentProposition ap : e) {
      x.put(ap.getTermVariable(), ap.getValue());
    }

    // foreach variable X<sub>i</sub> in X<sub>1</sub>,...,X<sub>n</sub> do
    for (RandomVariable Xi : bn.getVariablesInTopologicalOrder()) {
      // if X<sub>i</sub> is an evidence variable with value x<sub>i</sub>
      // in e
      if (x.containsKey(Xi)) {
        // then w <- w * P(X<sub>i</sub> = x<sub>i</sub> |
        // parents(X<sub>i</sub>))
        w *= bn.getNode(Xi)
            .getCPD()
            .getValue(
                ProbUtil.getEventValuesForXiGivenParents(
                    bn.getNode(Xi), x));
      } else {
        // else <b>x</b>[i] <- a random sample from
        // <b>P</b>(X<sub>i</sub> | parents(X<sub>i</sub>))
        x.put(Xi, ProbUtil.randomSample(bn.getNode(Xi), x, randomizer));
      }
    }
    // return <b>x</b>, w
    return new Pair<Map<RandomVariable, Object>, Double>(x, w);
  }

  //
  // START-BayesSampleInference
  @Override
  public CategoricalDistribution ask(final RandomVariable[] X,
      final AssignmentProposition[] observedEvidence,
      final BayesianNetwork bn, int N) {
    return likelihoodWeighting(X, observedEvidence, bn, N);
  }

  // END-BayesSampleInference
  //
}
TOP

Related Classes of aima.core.probability.bayes.approx.LikelihoodWeighting

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.