public static Forward ( |
||
model | ||
observations | double | |
scaling | double | |
리턴 | ].double[ |
/// <summary> /// Computes Forward probabilities for a given hidden Markov model and a set of observations. /// </summary> public static double[,] Forward <TDistribution>(HiddenMarkovModel <TDistribution> model, double[][] observations, out double logLikelihood) where TDistribution : IDistribution { int T = observations.Length; double[] coefficients = new double[T]; double[,] fwd = new double[T, model.States]; ForwardBackwardAlgorithm.Forward <TDistribution>(model, observations, coefficients, fwd); logLikelihood = 0; for (int i = 0; i < coefficients.Length; i++) { logLikelihood += Math.Log(coefficients[i]); } return(fwd); }
/// <summary> /// Calculates the probability that this model has generated the given sequence. /// </summary> /// <remarks> /// Evaluation problem. Given the HMM M = (A, B, pi) and the observation /// sequence O = {o1, o2, ..., oK}, calculate the probability that model /// M has generated sequence O. This can be computed efficiently using the /// either the Viterbi or the Forward algorithms. /// </remarks> /// <param name="observations"> /// A sequence of observations. /// </param> /// <param name="logarithm"> /// True to return the log-likelihood, false to return /// the likelihood. Default is false. /// </param> /// <returns> /// The probability that the given sequence has been generated by this model. /// </returns> public double Evaluate(int[] observations, bool logarithm) { if (observations == null) { throw new ArgumentNullException("observations"); } if (observations.Length == 0) { return(0.0); } // Forward algorithm double logLikelihood; // Compute forward probabilities ForwardBackwardAlgorithm.Forward(this, observations, out logLikelihood); // Return the sequence probability return(logarithm ? logLikelihood : System.Math.Exp(logLikelihood)); }
/// <summary> /// Predicts the next observation occurring after a given observation sequence. /// </summary> /// private double[][] predict(double[][] observations, int next, out double probability, out double[][] future) { int states = States; int T = next; double[,] A = Transitions; double logLikelihood; double[][] prediction = new double[next][]; double[][] expectation = new double[states][]; // Compute expectations for each state for (int i = 0; i < states; i++) { expectation[i] = getMode(B[i]); } // Compute forward probabilities for the given observation sequence. double[,] fw0 = ForwardBackwardAlgorithm.Forward(this, observations, out logLikelihood); // Create a matrix to store the future probabilities for the prediction // sequence and copy the latest forward probabilities on its first row. double[][] fwd = new double[T + 1][]; for (int i = 0; i < fwd.Length; i++) { fwd[i] = new double[States]; } // 1. Initialization for (int i = 0; i < States; i++) { fwd[0][i] = fw0[observations.Length - 1, i]; } // 2. Induction for (int t = 0; t < T; t++) { double[] weights = fwd[t + 1]; double scale = 0; for (int i = 0; i < weights.Length; i++) { double sum = 0.0; for (int j = 0; j < states; j++) { sum += fwd[t][j] * A[j, i]; } scale += weights[i] = sum * B[i].ProbabilityFunction(expectation[i]); } scale /= Math.Exp(logLikelihood); if (scale != 0) // Scaling { for (int i = 0; i < weights.Length; i++) { weights[i] /= scale; } } // Select most probable value double maxWeight = weights[0]; double sumWeight = maxWeight; prediction[t] = expectation[0]; for (int i = 1; i < states; i++) { if (weights[i] > maxWeight) { maxWeight = weights[i]; prediction[t] = expectation[i]; } } // Recompute log-likelihood logLikelihood = Math.Log(maxWeight); } // Returns the sequence probability as an out parameter probability = Math.Exp(logLikelihood); // Returns the future-forward probabilities future = fwd; return(prediction); }
/// <summary> /// Predicts the next observations occurring after a given observation sequence. /// </summary> public int[] Predict(int[] observations, int next, bool logarithm, out double probability, out double[][] probabilities) { int states = States; int T = next; double[,] A = Transitions; double logLikelihood; var prediction = new int[next]; probabilities = new double[next][]; // Compute forward probabilities for the given observation sequence. double[,] fw0 = ForwardBackwardAlgorithm.Forward(this, observations, out logLikelihood); // Create a matrix to store the future probabilities for the prediction // sequence and copy the latest forward probabilities on its first row. var fwd = new double[T + 1, States]; // 1. Initialization for (int i = 0; i < States; i++) { fwd[0, i] = fw0[observations.Length - 1, i]; } // 2. Induction for (int t = 0; t < T; t++) { var weights = new double[Symbols]; for (int s = 0; s < Symbols; s++) { for (int i = 0; i < states; i++) { double sum = 0.0; for (int j = 0; j < states; j++) { sum += fwd[t, j] * A[j, i]; } fwd[t + 1, i] = sum * B[i, s]; weights[s] += fwd[t + 1, i]; } weights[s] /= System.Math.Exp(logLikelihood); if (weights[s] != 0) // Scaling { for (int i = 0; i < states; i++) { fwd[t + 1, i] /= weights[s]; } } } // Select most probable symbol double maxWeight = weights[0]; double sumWeight = maxWeight; for (int i = 1; i < weights.Length; i++) { if (weights[i] > maxWeight) { maxWeight = weights[i]; prediction[t] = i; } sumWeight += weights[i]; } // Compute and save symbol probabilities for (int i = 0; i < weights.Length; i++) { weights[i] /= sumWeight; } probabilities[t] = weights; // Recompute log-likelihood logLikelihood = System.Math.Log(maxWeight); } // Returns the sequence probability as an out parameter probability = logarithm ? logLikelihood : System.Math.Exp(logLikelihood); return(prediction); }