/// <summary> /// Computes Forward probabilities for a given hidden Markov model and a set of observations. /// </summary> /// public static void LogForward <TObservation>(FactorPotential <TObservation> function, TObservation[] observations, int output, double[,] lnFwd) { int states = function.States; int T = observations.Length; // Ensures minimum requirements Accord.Diagnostics.Debug.Assert(lnFwd.GetLength(0) >= T); Accord.Diagnostics.Debug.Assert(lnFwd.GetLength(1) == states); Array.Clear(lnFwd, 0, lnFwd.Length); // 1. Initialization for (int i = 0; i < states; i++) { lnFwd[0, i] = function.Compute(-1, i, observations, 0, output); } // 2. Induction for (int t = 1; t < T; t++) { for (int i = 0; i < states; i++) { double sum = Double.NegativeInfinity; for (int j = 0; j < states; j++) { sum = Special.LogSum(sum, lnFwd[t - 1, j] + function.Compute(j, i, observations, t, output)); } lnFwd[t, i] = sum; } } }
/// <summary> /// Computes Forward probabilities for a given potential function and a set of observations. /// </summary> /// public static double[,] Forward <TObservation>(FactorPotential <TObservation> function, TObservation[] observations, int output = 0) { int states = function.States; int T = observations.Length; double[,] fwd = new double[T, states]; // 1. Initialization for (int i = 0; i < states; i++) { fwd[0, i] = Math.Exp(function.Compute(-1, i, observations, 0, output)); } // 2. Induction for (int t = 1; t < T; t++) { for (int i = 0; i < states; i++) { double sum = 0.0; for (int j = 0; j < states; j++) { sum += fwd[t - 1, j] * Math.Exp(function.Compute(j, i, observations, t, output)); } fwd[t, i] = sum; } } return(fwd); }
/// <summary> /// Computes Forward probabilities for a given hidden Markov model and a set of observations. /// </summary> /// public static void Forward <TObservation>(FactorPotential <TObservation> function, TObservation[] observations, int output, double[] scaling, double[,] fwd) { int states = function.States; int T = observations.Length; double s = 0; // Ensures minimum requirements Accord.Diagnostics.Debug.Assert(fwd.GetLength(0) >= T); Accord.Diagnostics.Debug.Assert(fwd.GetLength(1) == states); Accord.Diagnostics.Debug.Assert(scaling.Length >= T); Array.Clear(fwd, 0, fwd.Length); // 1. Initialization for (int i = 0; i < states; i++) { s += fwd[0, i] = Math.Exp(function.Compute(-1, i, observations, 0, output)); } scaling[0] = s; if (s != 0) // Scaling { for (int i = 0; i < states; i++) { fwd[0, i] /= s; } } // 2. Induction for (int t = 1; t < T; t++) { s = 0; for (int i = 0; i < states; i++) { double sum = 0.0; for (int j = 0; j < states; j++) { sum += fwd[t - 1, j] * Math.Exp(function.Compute(j, i, observations, t, output)); } fwd[t, i] = sum; s += fwd[t, i]; // scaling coefficient } scaling[t] = s; if (s != 0) // Scaling { for (int i = 0; i < states; i++) { fwd[t, i] /= s; } } } }
/// <summary> /// Computes Backward probabilities for a given potential function and a set of observations. /// </summary> /// public static double[,] Backward <TObservation>(FactorPotential <TObservation> function, TObservation[] observations, int output = 0) { int states = function.States; int T = observations.Length; double[,] bwd = new double[T, states]; // 1. Initialization for (int i = 0; i < states; i++) { bwd[T - 1, i] = 1.0; } // 2. Induction for (int t = T - 2; t >= 0; t--) { for (int i = 0; i < states; i++) { double sum = 0; for (int j = 0; j < states; j++) { sum += bwd[t + 1, j] * Math.Exp(function.Compute(i, j, observations, t + 1, output)); } bwd[t, i] += sum; } } return(bwd); }
/// <summary> /// Computes Backward probabilities for a given potential function and a set of observations. /// </summary> /// public static void Backward <TObservation>(FactorPotential <TObservation> function, TObservation[] observations, int output, double[] scaling, double[,] bwd) { int states = function.States; int T = observations.Length; // Ensures minimum requirements Accord.Diagnostics.Debug.Assert(bwd.GetLength(0) >= T); Accord.Diagnostics.Debug.Assert(bwd.GetLength(1) == states); Array.Clear(bwd, 0, bwd.Length); // For backward variables, we use the same scale factors // for each time t as were used for forward variables. // 1. Initialization for (int i = 0; i < states; i++) { bwd[T - 1, i] = 1.0 / scaling[T - 1]; } // 2. Induction for (int t = T - 2; t >= 0; t--) { for (int i = 0; i < states; i++) { double sum = 0; for (int j = 0; j < states; j++) { sum += bwd[t + 1, j] * Math.Exp(function.Compute(i, j, observations, t + 1, output)); } bwd[t, i] += sum / scaling[t]; } } }
/// <summary> /// Computes Backward probabilities for a given potential function and a set of observations. /// </summary> /// public static void LogBackward <TObservation>(FactorPotential <TObservation> function, TObservation[] observations, int output, double[,] lnBwd) { int states = function.States; int T = observations.Length; // Ensures minimum requirements System.Diagnostics.Debug.Assert(lnBwd.GetLength(0) >= T); System.Diagnostics.Debug.Assert(lnBwd.GetLength(1) == states); Array.Clear(lnBwd, 0, lnBwd.Length); // 1. Initialization for (int i = 0; i < states; i++) { lnBwd[T - 1, i] = 0; } // 2. Induction for (int t = T - 2; t >= 0; t--) { for (int i = 0; i < states; i++) { double sum = Double.NegativeInfinity; for (int j = 0; j < states; j++) { sum = Special.LogSum(sum, lnBwd[t + 1, j] + function.Compute(i, j, observations, t + 1, output)); } lnBwd[t, i] += sum; } } }
/// <summary> /// Computes Backward probabilities for a given potential function and a set of observations(no scaling). /// </summary> public static double[,] LogBackward <TObservation>(FactorPotential <TObservation> function, TObservation[] observations, int output, out double logLikelihood) { int states = function.States; var lnBwd = LogBackward(function, observations, output); logLikelihood = double.NegativeInfinity; for (int i = 0; i < states; i++) { logLikelihood = Special.LogSum(logLikelihood, lnBwd[0, i] + function.Compute(-1, i, observations, 0, output)); } return(lnBwd); }
/// <summary> /// Computes Backward probabilities for a given potential function and a set of observations(no scaling). /// </summary> public static double[,] Backward <TObservation>(FactorPotential <TObservation> function, TObservation[] observations, int output, out double logLikelihood) { int states = function.States; var bwd = Backward(function, observations, output); double likelihood = 0; for (int i = 0; i < states; i++) { likelihood += bwd[0, i] * Math.Exp(function.Compute(-1, i, observations, 0, output)); } logLikelihood = Math.Log(likelihood); return(bwd); }
/// <summary> /// Computes the probability of occurance of this /// feature given a sequence of observations. /// </summary> /// /// <param name="fwd">The matrix of forward state probabilities.</param> /// <param name="bwd">The matrix of backward state probabilties.</param> /// <param name="x">The observation sequence.</param> /// <param name="y">The output class label for the sequence.</param> /// /// <returns>The probability of occurance of this feature.</returns> /// public override double Marginal(double[,] fwd, double[,] bwd, T[] x, int y) { // Assume the simplifying structure that each // factor is responsible for single output y. if (y != OwnerFactorIndex) { return(0); } FactorPotential <T> owner = Owner.Factors[OwnerFactorIndex]; double marginal = 0; for (int t = 0; t < x.Length - 1; t++) { marginal += fwd[t, previous] * bwd[t + 1, current] * Math.Exp(owner.Compute(previous, current, x, t + 1, y)); } return(marginal); }
/// <summary> /// Computes the log-probability of occurance of this /// feature given a sequence of observations. /// </summary> /// /// <param name="lnFwd">The matrix of forward state log-probabilities.</param> /// <param name="lnBwd">The matrix of backward state log-probabilties.</param> /// <param name="x">The observation sequence.</param> /// <param name="y">The output class label for the sequence.</param> /// /// <returns>The probability of occurance of this feature.</returns> /// public override double LogMarginal(double[,] lnFwd, double[,] lnBwd, T[] x, int y) { // Assume the simplifying structure that each // factor is responsible for single output y. if (y != OwnerFactorIndex) { return(Double.NegativeInfinity); } FactorPotential <T> owner = Owner.Factors[OwnerFactorIndex]; double marginal = double.NegativeInfinity; for (int t = 0; t < x.Length - 1; t++) { marginal = Special.LogSum(marginal, lnFwd[t, previous] + lnBwd[t + 1, current] + owner.Compute(previous, current, x, t + 1, y)); } return(marginal); }