Exemplo n.º 1
0
        /// <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 : Math.Exp(logLikelihood));
        }
Exemplo n.º 2
0
        /// <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;

            int[] 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.
            double[,] 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++)
            {
                double[] 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] /= 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 = Math.Log(maxWeight);
            }

            // Returns the sequence probability as an out parameter
            probability = logarithm ? logLikelihood : Math.Exp(logLikelihood);

            return(prediction);
        }