public override double[][][] EstimateXi(IMLDataSet sequence,
                ForwardBackwardCalculator fbc, HiddenMarkovModel hmm)
        {
            if (sequence.Count <= 1)
            {
                throw new EncogError(
                        "Must have more than one observation");
            }

            double[][][] xi = EngineArray.AllocDouble3D((int)sequence.Count - 1, hmm
                    .StateCount, hmm.StateCount);

            for (int t = 0; t < (sequence.Count - 1); t++)
            {
                IMLDataPair observation = sequence[t+1];

                for (int i = 0; i < hmm.StateCount; i++)
                {
                    for (int j = 0; j < hmm.StateCount; j++)
                    {
                        xi[t][i][j] = fbc.AlphaElement(t, i)
                                * hmm.TransitionProbability[i][j]
                                * hmm.StateDistributions[j].Probability(
                                        observation) * fbc.BetaElement(t + 1, j);
                    }
                }
            }

            return xi;
        }
Example #2
0
 public FixedLagSmoothing(HiddenMarkovModel hmm, int timelag)
 {
     this.hmm = hmm;
     this.timelag = timelag;
     this.evidenceFromSmoothedStepToPresent = new List<String>();
     this.time = 1;
     this.forwardMessage = hmm.prior();
     this.B = hmm.transitionModel().unitMatrix();
 }
 /// <summary>
 /// Construct a KMeans trainer. 
 /// </summary>
 /// <param name="method">The HMM.</param>
 /// <param name="sequences">The training data.</param>
 public TrainKMeans(HiddenMarkovModel method,
                    IMLSequenceSet sequences)
 {
     _method = method;
     _modelHmm = method;
     _states = method.StateCount;
     _training = sequences;
     _clusters = new Clusters(_states, sequences);
     _done = false;
 }
        public void setUp()
        {
            rainman = HMMFactory.createRainmanHMM();
            robot = HMMFactory.createRobotHMM();

            randomizer = new MockRandomizer(new double[] { 0.1, 0.9 });
            particleSet = new ParticleSet(rainman);
            particleSet.add(new Particle(HmmConstants.RAINING));
            particleSet.add(new Particle(HmmConstants.RAINING));
            particleSet.add(new Particle(HmmConstants.RAINING));
            particleSet.add(new Particle(HmmConstants.NOT_RAINING));
        }
        public ViterbiCalculator(IMLDataSet oseq, HiddenMarkovModel hmm)
        {
            if (oseq.Count < 1)
            {
                throw new EncogError("Must not have empty sequence");
            }

            this.delta = EngineArray.AllocateDouble2D((int)oseq.Count, hmm.StateCount);
            this.psy = EngineArray.AllocateInt2D((int)oseq.Count, hmm.StateCount);
            this._stateSequence = new int[oseq.Count];

            for (int i = 0; i < hmm.StateCount; i++)
            {
                this.delta[0][i] = -Math.Log(hmm.GetPi(i))
                        - Math.Log(hmm.StateDistributions[i].Probability(
                                oseq[0]));
                this.psy[0][i] = 0;
            }

            int t = 1;
            for (int index = 1; index < oseq.Count; index++)
            {
                IMLDataPair observation = oseq[index];

                for (int i = 0; i < hmm.StateCount; i++)
                {
                    ComputeStep(hmm, observation, t, i);
                }

                t++;
            }

            this.lnProbability = Double.PositiveInfinity;
            for (int i = 0; i < hmm.StateCount; i++)
            {
                double thisProbability = this.delta[oseq.Count - 1][i];

                if (this.lnProbability > thisProbability)
                {
                    this.lnProbability = thisProbability;
                    _stateSequence[oseq.Count - 1] = i;
                }
            }
            this.lnProbability = -this.lnProbability;

            for (int t2 = (int)(oseq.Count - 2); t2 >= 0; t2--)
            {
                _stateSequence[t2] = this.psy[t2 + 1][_stateSequence[t2 + 1]];
            }
        }
        public double Distance(HiddenMarkovModel hmm1,
                               HiddenMarkovModel hmm2)
        {
            double distance = 0.0;

            for (int i = 0; i < SequenceCount; i++)
            {
                IMLDataSet oseq = new MarkovGenerator(hmm1)
                    .ObservationSequence(Len);

                distance += (new ForwardBackwardScaledCalculator(oseq, hmm1)
                                 .LnProbability() - new ForwardBackwardScaledCalculator(
                                                        oseq, hmm2).LnProbability())
                            /Len;
            }

            return distance/SequenceCount;
        }
        /// <summary>
        /// Construct the object. 
        /// </summary>
        /// <param name="oseq">The sequence.</param>
        /// <param name="hmm">The hidden markov model to use.</param>
        /// <param name="doAlpha">Do alpha?</param>
        /// <param name="doBeta">Do beta?</param>
        public ForwardBackwardCalculator(IMLDataSet oseq,
                                         HiddenMarkovModel hmm, bool doAlpha, bool doBeta)
        {
            if (oseq.Count < 1)
            {
                throw new EncogError("Empty sequence");
            }

            if (doAlpha)
            {
                ComputeAlpha(hmm, oseq);
            }

            if (doBeta)
            {
                ComputeBeta(hmm, oseq);
            }

            ComputeProbability(oseq, hmm, doAlpha, doBeta);
        }
        /// <summary>
        /// Construct the calculator.
        /// </summary>
        /// <param name="seq">The sequence.</param>
        /// <param name="hmm">The HMM.</param>
        /// <param name="doAlpha">Should alpha be calculated.</param>
        /// <param name="doBeta">Should beta be calculated.</param>
        public ForwardBackwardScaledCalculator(
            IMLDataSet seq, HiddenMarkovModel hmm,
            bool doAlpha, bool doBeta)
        {
            if (seq.Count < 1)
            {
                throw new EncogError("Count cannot be less than one.");
            }

            _ctFactors = new double[seq.Count];
            EngineArray.Fill(_ctFactors, 0.0);

            ComputeAlpha(hmm, seq);

            if (doBeta)
            {
                ComputeBeta(hmm, seq);
            }

            ComputeProbability(seq, hmm, doAlpha, doBeta);
        }
        /// <summary>
        /// Learn the distribution. 
        /// </summary>
        /// <param name="hmm">The HMM.</param>
        private void LearnOpdf(HiddenMarkovModel hmm)
        {
            for (int i = 0; i < hmm.StateCount; i++)
            {
                ICollection<IMLDataPair> clusterObservations = _clusters
                    .Cluster(i);

                if (clusterObservations.Count < 1)
                {
                    IStateDistribution o = _modelHmm.CreateNewDistribution();
                    hmm.StateDistributions[i] = o;
                }
                else
                {
                    var temp = new BasicMLDataSet();
                    foreach (IMLDataPair pair in clusterObservations)
                    {
                        temp.Add(pair);
                    }
                    hmm.StateDistributions[i].Fit(temp);
                }
            }
        }
Example #10
0
    /*
     * this method passes all the possible directions
     * that can create a horizontal line to the HMM library
     * as observations. A and B are the state and
     * observation probabilities for the model
     * pi is the intial state of the model
     * the function returns true if the input matches any
     * of the observations used to train the model
    */
    bool horizontalEvalution(int [] input)
    {
        if(input.Length != 1){
            return false;
        }

        int[][] sequences = new int[][]
        {
            new int[]{ EAST },
            new int[] { WEST }
        };

        double [,] A = new double[8,8]
        {
            {0, 0, 0, 0, 0, 0, 0, 0},
            {0, 0, 0, 0, 0, 0, 0, 0},
            {0, 0, 0, 0, 0, 0, 0, 0},
            {0, 0, 0, 0, 0, 0, 0, 0},
            {0, 0, 0, 0, 0, 0, 0, 0},
            {0, 0, 0, 0, 0, 0, 0, 0},
            {0, 0, 0, 0, 0, 0, 0, 0},
            {0, 0, 0, 0, 0, 0, 0, 0}
        };

        double [,] B = new double[8,8]
        {
            {1, 0, 0, 0, 0, 0, 0, 0},
            {0, 1, 0, 0, 0, 0, 0, 0},
            {0, 0, 1, 0, 0, 0, 0, 0},
            {0, 0, 0, 1, 0, 0, 0, 0},
            {0, 0, 0, 0, 1, 0, 0, 0},
            {0, 0, 0, 0, 0, 1, 0, 0},
            {0, 0, 0, 0, 0, 0, 1, 0},
            {0, 0, 0, 0, 0, 0, 0, 1}
        };

        double [] pi = new double [] {0, 0, 0.5, 0.5, 0, 0, 0, 0};

        HiddenMarkovModel model = new HiddenMarkovModel(A, B, pi);
        model.Learn(sequences, 0.0001);

        if(model.Evaluate(input) >= 0.5){
            return true;
        }else{
            return false;
        }
    }
Example #11
0
        public void issue_154()
        {
            int[][] sequences = new int[][]
            {
                new int[] { 0, 1, 1, 1, 1, 0, 1, 1, 1, 1 },
                new int[] { 0, 1, 1, 1, 0, 1, 1, 1, 1, 1 },
                new int[] { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
                new int[] { 0, 1, 1, 1, 1, 1 },
                new int[] { 0, 1, 1, 1, 1, 1, 1 },
                new int[] { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
                new int[] { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
            };

            var hmm0 = new HiddenMarkovModel(states: 3, symbols: 2);
            var hmm1 = hmm0.Clone() as HiddenMarkovModel;
            var hmm2 = hmm0.Clone() as HiddenMarkovModel;
            var hmm3 = hmm0.Clone() as HiddenMarkovModel;
            var hmm4 = hmm0.Clone() as HiddenMarkovModel;

            {
                Accord.Math.Random.Generator.Seed = 0;
                var teacher = new BaumWelchLearning(hmm1)
                {
                    Tolerance = 0.0001, Iterations = 1
                };
                Assert.AreEqual(0, teacher.CurrentIteration);
                teacher.Learn(sequences);
                Assert.AreEqual(1, teacher.CurrentIteration);
                teacher = new BaumWelchLearning(hmm1)
                {
                    Tolerance = 0.0001, Iterations = 1
                };
                Assert.AreEqual(0, teacher.CurrentIteration);
                teacher.Learn(sequences);
                Assert.AreEqual(1, teacher.CurrentIteration);
                teacher = new BaumWelchLearning(hmm1)
                {
                    Tolerance = 0.0001, Iterations = 1
                };
                Assert.AreEqual(0, teacher.CurrentIteration);
                teacher.Learn(sequences);
                Assert.AreEqual(1, teacher.CurrentIteration);
                teacher = new BaumWelchLearning(hmm1)
                {
                    Tolerance = 0.0001, Iterations = 1
                };
                Assert.AreEqual(0, teacher.CurrentIteration);
                teacher.Learn(sequences);
                Assert.AreEqual(1, teacher.CurrentIteration);
            }
            {
                Accord.Math.Random.Generator.Seed = 0;
                var teacher = new BaumWelchLearning(hmm2)
                {
                    Tolerance = 0.0001, Iterations = 2
                };
                Assert.AreEqual(0, teacher.CurrentIteration);
                teacher.Learn(sequences);
                Assert.AreEqual(2, teacher.CurrentIteration);
                teacher.MaxIterations = 4;
                teacher.Learn(sequences);
                Assert.AreEqual(4, teacher.CurrentIteration);
            }
            {
                Accord.Math.Random.Generator.Seed = 0;
                var teacher = new BaumWelchLearning(hmm3)
                {
                    Tolerance = 0.0001, Iterations = 3
                };
                teacher.Learn(sequences);
                Assert.AreEqual(3, teacher.CurrentIteration);
                teacher = new BaumWelchLearning(hmm3)
                {
                    Tolerance = 0.0001, Iterations = 1
                };
                Assert.AreEqual(0, teacher.CurrentIteration);
                teacher.Learn(sequences);
                Assert.AreEqual(1, teacher.CurrentIteration);
            }
            {
                Accord.Math.Random.Generator.Seed = 0;
                var teacher = new BaumWelchLearning(hmm4)
                {
                    Tolerance = 0.0001, Iterations = 4
                };
                Assert.AreEqual(0, teacher.CurrentIteration);
                teacher.Learn(sequences);
                Assert.AreEqual(4, teacher.CurrentIteration);
            }

            {
                var teacher = new BaumWelchLearning(hmm0)
                {
                    Tolerance = 0.0001, Iterations = 0
                };
                teacher.Learn(sequences);
                Assert.AreEqual(13, teacher.CurrentIteration);
            }

            compare(hmm1, hmm2);
            compare(hmm1, hmm3);
            compare(hmm1, hmm4);
        }
 public TrainBaumWelchScaled(HiddenMarkovModel hmm,
      IMLSequenceSet training)
     : base(hmm, training)
 {
 }
Example #13
0
 /// <summary>
 /// Construct the calculator.
 /// </summary>
 /// <param name="seq">The sequences.</param>
 /// <param name="hmm">The Hidden Markov Model.</param>
 public ForwardBackwardScaledCalculator(IMLDataSet seq,
                                        HiddenMarkovModel hmm)
     : this(seq, hmm, true, false)
 {
 }
        /// <summary>
        /// Compute beta.
        /// </summary>
        /// <param name="hmm">The HMM.</param>
        /// <param name="oseq">The sequence.</param>
        protected new void ComputeBeta(HiddenMarkovModel hmm, IMLDataSet oseq)
        {
            Beta = EngineArray.AllocateDouble2D((int) oseq.Count, hmm.StateCount);

            for (int i = 0; i < hmm.StateCount; i++)
            {
                Beta[oseq.Count - 1][i] = 1.0/_ctFactors[oseq.Count - 1];
            }

            for (var t = (int) (oseq.Count - 2); t >= 0; t--)
            {
                for (int i = 0; i < hmm.StateCount; i++)
                {
                    ComputeBetaStep(hmm, oseq[t + 1], t, i);
                    Beta[t][i] /= _ctFactors[t];
                }
            }
        }
 public ViterbiLearning(HiddenMarkovModel hmm)
 {
     mModel = hmm;
     mMaximumLikelihoodLearner = new MaximumLikelihoodLearning(hmm);
 }
        /// <summary>
        ///   Computes Forward probabilities for a given hidden Markov model and a set of observations.
        /// </summary>
        ///
        public static void Forward(HiddenMarkovModel model, int[] observations, double[] scaling, double[,] fwd)
        {
            int states = model.States;
            var A      = Matrix.Exp(model.Transitions);
            var B      = Matrix.Exp(model.Emissions);
            var pi     = Matrix.Exp(model.Probabilities);

            int    T = observations.Length;
            double s = 0;

            // Ensures minimum requirements
            System.Diagnostics.Debug.Assert(fwd.GetLength(0) >= T);
            System.Diagnostics.Debug.Assert(fwd.GetLength(1) == states);
            System.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] = pi[i] * B[i, observations[0]];
            }
            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++)
            {
                int obs = observations[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] * A[j, i];
                    }
                    fwd[t, i] = sum * B[i, obs];

                    s += fwd[t, i]; // scaling coefficient
                }

                scaling[t] = s;

                if (s != 0) // Scaling
                {
                    for (int i = 0; i < states; i++)
                    {
                        fwd[t, i] /= s;
                    }
                }
            }

            System.Diagnostics.Debug.Assert(!fwd.HasNaN());
        }
 /// <summary>
 ///   Creates a new instance of the Baum-Welch learning algorithm.
 /// </summary>
 ///
 /// <param name="attempts">The number of inner models to be learned.</param>
 /// <param name="model">The template model used to create all subsequent inner models.</param>
 /// <param name="topology">The topology to be used by the inner models. To be useful,
 ///   this needs to be a topology configured to create random initialization matrices.</param>
 ///
 public MultipleBaumWelchLearning(HiddenMarkovModel model, ITopology topology, int attempts)
 {
     this.template = model;
     this.topology = topology;
     this.Trials   = attempts;
 }
Example #18
0
 /// <summary>
 ///   Initializes a new instance of the <see cref="HiddenMarkovDistribution"/> class.
 /// </summary>
 ///
 /// <param name="model">The model.</param>
 ///
 public HiddenMarkovDistribution(HiddenMarkovModel model)
     : base(0)
 {
     this.model = model;
 }
        /// <summary>
        ///   Constructs a new potential function modeling Hidden Markov Models.
        /// </summary>
        ///
        /// <param name="model">A normal density hidden Markov.</param>
        ///
        public MarkovMultivariateFunction(
            HiddenMarkovModel <MultivariateNormalDistribution> model)
        {
            this.Dimensions = model.Dimension;

            var factorParams   = new List <double>();
            var factorFeatures = new List <IFeature <double[]> >();


            var stateParams   = new List <double>();
            var stateFeatures = new List <IFeature <double[]> >();

            var edgeParams   = new List <double>();
            var edgeFeatures = new List <IFeature <double[]> >();



            // Create features for initial state probabilities
            for (int i = 0; i < model.States; i++)
            {
                edgeParams.Add(model.Probabilities[i]);
                edgeFeatures.Add(new InitialFeature <double[]>(this, 0, i));
            }

            // Create features for state transition probabilities
            for (int i = 0; i < model.States; i++)
            {
                for (int j = 0; j < model.States; j++)
                {
                    edgeParams.Add(model.Transitions[i, j]);
                    edgeFeatures.Add(new TransitionFeature <double[]>(this, 0, i, j));
                }
            }

            // Create features emission probabilities
            for (int i = 0; i < model.States; i++)
            {
                for (int d = 0; d < model.Dimension; d++)
                {
                    double mean = model.Emissions[i].Mean[d];
                    double var  = model.Emissions[i].Variance[d];

                    // Occupancy
                    stateParams.Add(-0.5 * (Math.Log(2.0 * Math.PI * var) + (mean * mean) / var));
                    stateFeatures.Add(new OccupancyFeature <double[]>(this, 0, i));

                    // 1st Moment (x)
                    stateParams.Add(mean / var);
                    stateFeatures.Add(new MultivariateFirstMomentFeature(this, 0, i, d));

                    // 2nd Moment (x²)
                    stateParams.Add(-1.0 / (2.0 * var));
                    stateFeatures.Add(new MultivariateSecondMomentFeature(this, 0, i, d));
                }
            }


            // 1. edges
            factorFeatures.AddRange(edgeFeatures);
            factorParams.AddRange(edgeParams);

            // 2. states
            factorFeatures.AddRange(stateFeatures);
            factorParams.AddRange(stateParams);

            this.Weights  = factorParams.ToArray();
            this.Features = factorFeatures.ToArray();



            Factors = new[] // First features and parameters are always belonging to edges
            {
                new MarkovMultivariateNormalFactor(this, model.States, 0, Dimensions,
                                                   edgeIndex: 0, edgeCount: edgeParams.Count,                   // 1. edges
                                                   stateIndex: edgeParams.Count, stateCount: stateParams.Count) // 2. states
            };
        }
 /// <summary>
 ///   Creates a new instance of the Baum-Welch learning algorithm.
 /// </summary>
 public BaumWelchLearning(HiddenMarkovModel model)
     : base(model)
 {
     this.model = model;
 }
        public void BackwardTest()
        {
            HiddenMarkovModel hmm = Accord.Tests.Statistics.Models.Markov.
                                    ForwardBackwardAlgorithmTest.CreateModel2();

            var function = new MarkovDiscreteFunction(hmm);


            //                     A  B  B  A
            int[] observations = { 0, 1, 1, 0 };

            double logLikelihood;

            double[,] actual = Accord.Statistics.Models.Fields.
                               ForwardBackwardAlgorithm.Backward(function.Factors[0], observations, 0, out logLikelihood);

            var A = Matrix.Exp(hmm.Transitions);
            var B = Matrix.Exp(hmm.Emissions);
            var P = Matrix.Exp(hmm.Probabilities);

            double a30 = 1;
            double a31 = 1;

            double a20 = A[0, 0] * B[0, 0] * a30 + A[0, 1] * B[1, 0] * a31;
            double a21 = A[1, 0] * B[0, 0] * a30 + A[1, 1] * B[1, 0] * a31;

            double a10 = A[0, 0] * B[0, 1] * a20 + A[0, 1] * B[1, 1] * a21;
            double a11 = A[1, 0] * B[0, 1] * a20 + A[1, 1] * B[1, 1] * a21;

            double a00 = A[0, 0] * B[0, 1] * a10 + A[0, 1] * B[1, 1] * a11;
            double a01 = A[1, 0] * B[0, 1] * a10 + A[1, 1] * B[1, 1] * a11;


            Assert.AreEqual(actual[0, 0], a00, 1e-10);
            Assert.AreEqual(actual[0, 1], a01, 1e-10);

            Assert.AreEqual(actual[1, 0], a10, 1e-10);
            Assert.AreEqual(actual[1, 1], a11, 1e-10);

            Assert.AreEqual(actual[2, 0], a20, 1e-10);
            Assert.AreEqual(actual[2, 1], a21, 1e-10);

            Assert.AreEqual(actual[3, 0], a30, 1e-10);
            Assert.AreEqual(actual[3, 1], a31, 1e-10);

            foreach (double e in actual)
            {
                Assert.IsFalse(double.IsNaN(e));
            }

            double p = 0;

            for (int i = 0; i < hmm.States; i++)
            {
                p += actual[0, i] * P[i] * B[i, observations[0]];
            }

            Assert.AreEqual(0.054814695, p, 1e-8);
            Assert.IsFalse(double.IsNaN(p));

            p = System.Math.Exp(logLikelihood);
            Assert.AreEqual(0.054814695, p, 1e-8);
            Assert.IsFalse(double.IsNaN(p));
        }
        public void ForwardScalingTest()
        {
            HiddenMarkovModel hmm = Accord.Tests.Statistics.Models.Markov.
                                    ForwardBackwardAlgorithmTest.CreateModel1();

            MarkovDiscreteFunction function = new MarkovDiscreteFunction(hmm);


            //                     G  G  C  A
            int[] observations = { 2, 2, 1, 0 };

            double[] scaling;
            double   logLikelihood;

            double[,] actual = Accord.Statistics.Models.Fields.
                               ForwardBackwardAlgorithm.Forward(function.Factors[0], observations, 0, out scaling, out logLikelihood);

            double[] P = Matrix.Exp(hmm.Probabilities);
            double[,] B = Matrix.Exp(hmm.Emissions);
            double[,] A = Matrix.Exp(hmm.Transitions);

            double a00 = P[0] * B[0, 2];
            double a01 = P[1] * B[1, 2];
            double t0  = a00 + a01;

            a00 /= t0;
            a01 /= t0;

            double a10 = (a00 * A[0, 0] + a01 * A[1, 0]) * B[0, 2];
            double a11 = (a01 * A[1, 1] + a00 * A[0, 1]) * B[1, 2];
            double t1  = a10 + a11;

            a10 /= t1;
            a11 /= t1;

            double a20 = (a10 * A[0, 0] + a11 * A[1, 0]) * B[0, 1];
            double a21 = (a11 * A[1, 1] + a10 * A[0, 1]) * B[1, 1];
            double t2  = a20 + a21;

            a20 /= t2;
            a21 /= t2;

            double a30 = (a20 * A[0, 0] + a21 * A[1, 0]) * B[0, 0];
            double a31 = (a21 * A[1, 1] + a20 * A[0, 1]) * B[1, 0];
            double t3  = a30 + a31;

            a30 /= t3;
            a31 /= t3;

            Assert.AreEqual(a00, actual[0, 0], 1e-10);
            Assert.AreEqual(a01, actual[0, 1], 1e-10);

            Assert.AreEqual(a10, actual[1, 0], 1e-10);
            Assert.AreEqual(a11, actual[1, 1], 1e-10);

            Assert.AreEqual(a20, actual[2, 0], 1e-10);
            Assert.AreEqual(a21, actual[2, 1], 1e-10);

            Assert.AreEqual(a30, actual[3, 0], 1e-10);
            Assert.AreEqual(a31, actual[3, 1], 1e-10);

            foreach (double e in actual)
            {
                Assert.IsFalse(double.IsNaN(e));
            }


            double p = System.Math.Exp(logLikelihood);

            Assert.AreEqual(0.00384315, p, 1e-8);
            Assert.IsFalse(double.IsNaN(p));
        }
        /// <summary>
        /// Learn the state transitions. 
        /// </summary>
        /// <param name="hmm">The HMM.</param>
        private void LearnTransition(HiddenMarkovModel hmm)
        {
            for (int i = 0; i < hmm.StateCount; i++)
            {
                for (int j = 0; j < hmm.StateCount; j++)
                {
                    hmm.TransitionProbability[i][j] = 0.0;
                }
            }

            foreach (IMLDataSet obsSeq in _training.Sequences)
            {
                if (obsSeq.Count < 2)
                {
                    continue;
                }

                int secondState = _clusters.Cluster(obsSeq[0]);
                for (int i = 1; i < obsSeq.Count; i++)
                {
                    int firstState = secondState;
                    secondState = _clusters.Cluster(obsSeq[i]);

                    hmm.TransitionProbability[firstState][secondState] =
                        hmm.TransitionProbability[firstState][secondState] + 1.0;
                }
            }

            /* Normalize Aij array */
            for (int i = 0; i < hmm.StateCount; i++)
            {
                double sum = 0;

                for (int j = 0; j < hmm.StateCount; j++)
                {
                    sum += hmm.TransitionProbability[i][j];
                }

                if (sum == 0.0)
                {
                    for (int j = 0; j < hmm.StateCount; j++)
                    {
                        hmm.TransitionProbability[i][j] = 1.0/hmm.StateCount;
                    }
                }
                else
                {
                    for (int j = 0; j < hmm.StateCount; j++)
                    {
                        hmm.TransitionProbability[i][j] /= sum;
                    }
                }
            }
        }
        public void LearnTest2()
        {
            // Declare some testing data
            int[][] inputs = new int[][]
            {
                new int[] { 0, 0, 1, 2 },     // Class 0
                new int[] { 0, 1, 1, 2 },     // Class 0
                new int[] { 0, 0, 0, 1, 2 },  // Class 0
                new int[] { 0, 1, 2, 2, 2 },  // Class 0

                new int[] { 2, 2, 1, 0 },     // Class 1
                new int[] { 2, 2, 2, 1, 0 },  // Class 1
                new int[] { 2, 2, 2, 1, 0 },  // Class 1
                new int[] { 2, 2, 2, 2, 1 },  // Class 1
            };

            int[] outputs = new int[]
            {
                0, 0, 0, 0, // First four sequences are of class 0
                1, 1, 1, 1, // Last four sequences are of class 1
            };


            // We are trying to predict two different classes
            int classes = 2;

            // Each sequence may have up to 3 symbols (0,1,2)
            int symbols = 3;

            // Nested models will have 3 states each
            int[] states = new int[] { 3, 3 };

            // Creates a new Hidden Markov Model Classifier with the given parameters
            HiddenMarkovClassifier classifier = new HiddenMarkovClassifier(classes, states, symbols);


            // Create a new learning algorithm to train the sequence classifier
            var teacher = new HiddenMarkovClassifierLearning(classifier,

                                                             // Train each model until the log-likelihood changes less than 0.001
                                                             modelIndex => new BaumWelchLearning(classifier.Models[modelIndex])
            {
                Tolerance  = 0.001,
                Iterations = 0
            }
                                                             );

            // Enable support for sequence rejection
            teacher.Rejection = true;

            // Train the sequence classifier using the algorithm
            double likelihood = teacher.Run(inputs, outputs);

            HiddenMarkovModel threshold = classifier.Threshold;

            Assert.AreEqual(6, threshold.States);

            Assert.AreEqual(classifier.Models[0].Transitions[0, 0], threshold.Transitions[0, 0], 1e-10);
            Assert.AreEqual(classifier.Models[0].Transitions[1, 1], threshold.Transitions[1, 1], 1e-10);
            Assert.AreEqual(classifier.Models[0].Transitions[2, 2], threshold.Transitions[2, 2], 1e-10);

            Assert.AreEqual(classifier.Models[1].Transitions[0, 0], threshold.Transitions[3, 3], 1e-10);
            Assert.AreEqual(classifier.Models[1].Transitions[1, 1], threshold.Transitions[4, 4], 1e-10);
            Assert.AreEqual(classifier.Models[1].Transitions[2, 2], threshold.Transitions[5, 5], 1e-10);

            for (int i = 0; i < 3; i++)
            {
                for (int j = 3; j < 6; j++)
                {
                    Assert.AreEqual(Double.NegativeInfinity, threshold.Transitions[i, j]);
                }
            }

            for (int i = 3; i < 6; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    Assert.AreEqual(Double.NegativeInfinity, threshold.Transitions[i, j]);
                }
            }

            Assert.IsFalse(Matrix.HasNaN(threshold.Transitions));

            classifier.Sensitivity = 0.5;

            // Will assert the models have learned the sequences correctly.
            for (int i = 0; i < inputs.Length; i++)
            {
                int expected = outputs[i];
                int actual   = classifier.Compute(inputs[i], out likelihood);
                Assert.AreEqual(expected, actual);
            }


            int[] r0 = new int[] { 1, 1, 0, 0, 2 };


            double logRejection;
            int    c = classifier.Compute(r0, out logRejection);

            Assert.AreEqual(-1, c);
            Assert.AreEqual(0.99906957195279988, logRejection);
            Assert.IsFalse(double.IsNaN(logRejection));

            logRejection = threshold.Evaluate(r0);
            Assert.AreEqual(-4.5653702970734793, logRejection, 1e-10);
            Assert.IsFalse(double.IsNaN(logRejection));

            threshold.Decode(r0, out logRejection);
            Assert.AreEqual(-8.21169955167614, logRejection, 1e-10);
            Assert.IsFalse(double.IsNaN(logRejection));

            foreach (var model in classifier.Models)
            {
                double[,] A = model.Transitions;

                for (int i = 0; i < A.GetLength(0); i++)
                {
                    double[] row = A.Exp().GetRow(i);
                    double   sum = row.Sum();
                    Assert.AreEqual(1, sum, 1e-10);
                }
            }
            {
                double[,] A = classifier.Threshold.Transitions;

                for (int i = 0; i < A.GetLength(0); i++)
                {
                    double[] row = A.GetRow(i);
                    double   sum = row.Exp().Sum();
                    Assert.AreEqual(1, sum, 1e-6);
                }
            }
        }
Example #25
0
        public void PosteriorTest1()
        {
            // Example from http://ai.stanford.edu/~serafim/CS262_2007/notes/lecture5.pdf


            double[,] A =
            {
                { 0.95, 0.05 }, // fair dice state
                { 0.05, 0.95 }, // loaded dice state
            };

            double[,] B =
            {
                {  1 / 6.0,  1 / 6.0,  1 / 6.0,  1 / 6.0,  1 / 6.0, 1 / 6.0 }, // fair dice probabilities
                { 1 / 10.0, 1 / 10.0, 1 / 10.0, 1 / 10.0, 1 / 10.0, 1 / 2.0 }, // loaded probabilities
            };

            double[] pi = { 0.5, 0.5 };

            HiddenMarkovModel hmm = new HiddenMarkovModel(A, B, pi);

            int[]  x = new int[] { 1, 2, 1, 5, 6, 2, 1, 5, 2, 4 }.Subtract(1);
            int[]  y  = new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
            double py = Math.Exp(hmm.Evaluate(x, y));

            Assert.AreEqual(0.00000000521158647211, py, 1e-16);

            x  = new int[] { 1, 2, 1, 5, 6, 2, 1, 5, 2, 4 }.Subtract(1);
            y  = new int[] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
            py = Math.Exp(hmm.Evaluate(x, y));

            Assert.AreEqual(0.00000000015756235243, py, 1e-16);


            Accord.Math.Tools.SetupGenerator(0);
            var u = new UniformDiscreteDistribution(0, 6);

            int[] sequence = u.Generate(1000);
            int   start    = 120;
            int   end      = 150;

            for (int i = start; i < end; i += 2)
            {
                sequence[i] = 5;
            }


            // Predict the next observation in sequence
            int[]      path;
            double[][] p = hmm.Posterior(sequence, out path);

            for (int i = 0; i < path.Length; i++)
            {
                Assert.AreEqual(1, p[i][0] + p[i][1], 1e-10);
            }


            int loaded = 0;

            for (int i = 0; i < start; i++)
            {
                if (p[i][1] > 0.95)
                {
                    loaded++;
                }
            }

            Assert.AreEqual(0, loaded);

            loaded = 0;
            for (int i = start; i < end; i++)
            {
                if (p[i][1] > 0.95)
                {
                    loaded++;
                }
            }

            Assert.IsTrue(loaded > 15);

            loaded = 0;
            for (int i = end; i < p.Length; i++)
            {
                if (p[i][1] > 0.95)
                {
                    loaded++;
                }
            }

            Assert.AreEqual(0, loaded);
        }
 public BaumWelchLearning(HiddenMarkovModel hmm)
 {
     mModel = hmm;
 }
 /// <summary>
 /// Construct the calculator.
 /// </summary>
 /// <param name="seq">The sequences.</param>
 /// <param name="hmm">The Hidden Markov Model.</param>
 public ForwardBackwardScaledCalculator(IMLDataSet seq,
                                        HiddenMarkovModel hmm)
     : this(seq, hmm, true, false)
 {
 }
        /// <summary>
        ///   Constructs a new potential function modeling Hidden Markov Models.
        /// </summary>
        ///
        /// <param name="model">The hidden Markov model.</param>
        ///
        public MarkovDiscreteFunction(HiddenMarkovModel model)
        {
            int states = model.States;

            this.Symbols = model.Symbols;

            var factorParams   = new List <double>();
            var factorFeatures = new List <IFeature <int> >();

            var stateParams   = new List <double>();
            var stateFeatures = new List <IFeature <int> >();

            var edgeParams   = new List <double>();
            var edgeFeatures = new List <IFeature <int> >();


            // Create features for initial state probabilities
            for (int i = 0; i < states; i++)
            {
                edgeParams.Add(model.Probabilities[i]);
                edgeFeatures.Add(new InitialFeature <int>(this, 0, i));
            }

            // Create features for state transition probabilities
            for (int i = 0; i < states; i++)
            {
                for (int j = 0; j < states; j++)
                {
                    edgeParams.Add(model.Transitions[i, j]);
                    edgeFeatures.Add(new TransitionFeature <int>(this, 0, i, j));
                }
            }

            // Create features for symbol emission probabilities
            for (int i = 0; i < states; i++)
            {
                for (int k = 0; k < Symbols; k++)
                {
                    stateParams.Add(model.Emissions[i, k]);
                    stateFeatures.Add(new EmissionFeature(this, 0, i, k));
                }
            }


            // 1. edges
            factorFeatures.AddRange(edgeFeatures);
            factorParams.AddRange(edgeParams);

            // 2. states
            factorFeatures.AddRange(stateFeatures);
            factorParams.AddRange(stateParams);

            this.Features = factorFeatures.ToArray();
            this.Weights  = factorParams.ToArray();


            this.Factors = new[]
            {
                new MarkovDiscreteFactor(this, states, 0, Symbols,
                                         edgeIndex: 0, edgeCount: edgeParams.Count,                   // 1. edges
                                         stateIndex: edgeParams.Count, stateCount: stateParams.Count) // 2. states
            };
        }
 public MarkovGenerator(HiddenMarkovModel hmm)
 {
     this._hmm = hmm;
     NewSequence();
 }
Example #30
0
 /// <summary>
 ///   Creates a new instance of the Viterbi learning algorithm.
 /// </summary>
 ///
 public ViterbiLearning(HiddenMarkovModel <TDistribution> model)
 {
     this.mle = new MaximumLikelihoodLearning <TDistribution>(model);
 }
        public void LearnTest9()
        {
            Accord.Math.Tools.SetupGenerator(0);

            var observations = new double[][][]
            {
                #region example
                new double[][]
                {
                    new double[] { 2.58825719356537, -6.10018078957452, -3.51826652951428, },
                    new double[] { 1.5637531876564, -8.92844874836103, -9.09330631370717, },
                    new double[] { 2.12242007255554, -14.8117769726059, -9.04211363915664, },
                    new double[] { 0.39045587182045, -10.3548189544216, -7.69608701297759, },
                    new double[] { -0.553155690431595, -34.9185135663671, 14.6941023804174, },
                    new double[] { -0.923129916191101, -6.06337512248124, 8.28106954197084, },
                    new double[] { 0.478342920541763, -4.93066650122859, 3.1120912556361, },
                },
                new double[][]
                {
                    new double[] { 1.89824998378754, -8.21581113387553, -7.88790716806936, },
                    new double[] { 2.24453508853912, -10.281886698766, -9.67846789539227, },
                    new double[] { 0.946296751499176, -22.0276392511088, -6.52238763834787, },
                    new double[] { -0.251136720180511, -13.3010653290676, 8.47499524273859, },
                    new double[] { -2.35625505447388, -18.1542111199742, 6.25564428645639, },
                    new double[] { 0.200483202934265, -5.48215328147925, 5.88811639894938, },
                },
                new double[][]
                {
                    new double[] { 2.7240589261055, -3.71720542338046, -3.75092324997593, },
                    new double[] { 2.19917744398117, -7.18434871865373, -4.92539999824263, },
                    new double[] { 1.40723958611488, -11.5545592998714, -5.14780194932221, },
                    new double[] { 1.61909088492393, -12.5262932665595, -6.34366687651826, },
                    new double[] { -2.54745036363602, -8.64924529565274, 4.15127988308386, },
                    new double[] { 0.815489888191223, -33.8531051237431, 4.3954106953589, },
                    new double[] { -2.2090271115303, -7.17818258102413, 8.9117419130814, },
                    new double[] { -1.9000232219696, -2.4331659041997, 6.91224717766923, },
                },
                new double[][]
                {
                    new double[] { 4.88746017217636, -4.36384651224969, -5.45526891285354, },
                    new double[] { 1.07786506414413, -12.9399071692788, -5.88248026843442, },
                    new double[] { 2.28888094425201, -15.4017823367163, -9.36490649113217, },
                    new double[] { -1.16468518972397, -35.4200913138333, 5.44735305966353, },
                    new double[] { -1.1483296751976, -13.5454911068913, 7.83577905727326, },
                    new double[] { -2.58188247680664, -1.10149600205281, 10.5928750605715, },
                    new double[] { -0.277529656887054, -6.96828661824016, 4.59381106840823, },
                },
                new double[][]
                {
                    new double[] { 3.39118540287018, -2.9173207268871, -5.66795398530988, },
                    new double[] { 1.44856870174408, -9.21319243840922, -5.74986260778932, },
                    new double[] { 1.45215392112732, -10.3989582187704, -7.06932768129103, },
                    new double[] { 0.640938431024551, -15.319525165245, -7.68866476960221, },
                    new double[] { -0.77500119805336, -20.8335910793105, -1.56702420087282, },
                    new double[] { -3.48337143659592, -18.0461677940976, 12.3393172987974, },
                    new double[] { -1.17014795541763, -5.59624373275155, 6.09176828712909, },
                },
                new double[][]
                {
                    new double[] { -3.984335064888, -6.2406475893692, -8.13815178201645, },
                    new double[] { -2.12110131978989, -5.60649378910647, -7.69551693188544, },
                    new double[] { -1.62762850522995, -24.1160212319193, -14.9683354815265, },
                    new double[] { -1.15231424570084, -17.1336790735458, -5.70731951079186, },
                    new double[] { 0.00514835119247437, -35.4256585588532, 11.0357975880744, },
                    new double[] { 0.247226655483246, -4.87705331087666, 8.47028869639136, },
                    new double[] { -1.28729045391083, -4.4684855254196, 4.45432778840328, },
                },
                new double[][]
                {
                    new double[] { -5.14926165342331, -14.4168633009146, -14.4808205022332, },
                    new double[] { -3.93681302666664, -13.6040611430423, -9.52852874304709, },
                    new double[] { -4.0200162678957, -17.9772444010218, -10.9145425003168, },
                    new double[] { 2.99205146729946, -11.3995995445577, 10.0112700536762, },
                    new double[] { -1.80960297584534, -25.9626088707583, 3.84153700324761, },
                    new double[] { -0.47445073723793, -3.15995343875038, 3.81288679772555, },
                },
                new double[][]
                {
                    new double[] { -3.10730338096619, -4.90623566171983, -7.71155001801384, },
                    new double[] { -2.58265435695648, -12.8249488039327, -7.81701695282102, },
                    new double[] { -3.70455086231232, -10.9642675851383, -10.3474496036822, },
                    new double[] { 2.34457105398178, -22.575668228196, -4.00681935468317, },
                    new double[] { -0.137023627758026, -22.8846781066673, 6.49448229892285, },
                    new double[] { -1.04487389326096, -10.8106353197974, 6.89123118904132, },
                    new double[] { -0.807777792215347, -6.72485967042486, 6.44026679233423, },
                    new double[] { -0.0864192843437195, -1.82784244477527, 5.21446167464657, },
                },
                new double[][]
                {
                    new double[] { -3.68375554680824, -8.91158395500054, -9.35894038244743, },
                    new double[] { -3.42774018645287, -8.90966793048099, -12.0502934183779, },
                    new double[] { -2.21796408295631, -20.1283824753482, -9.3404551995806, },
                    new double[] { 0.275979936122894, -24.8898254667703, -1.95441472953041, },
                    new double[] { 2.8757631778717, -25.5929744730134, 15.9213204397452, },
                    new double[] { -0.0532664358615875, -5.41014381829368, 7.0702071664098, },
                    new double[] { -0.523447245359421, -2.21351362388411, 5.47910029515575, },
                },
                new double[][]
                {
                    new double[] { -2.87790596485138, -4.67335526533981, -5.23215633615683, },
                    new double[] { -2.4156779050827, -3.99829080603495, -4.85576151355235, },
                    new double[] { -2.6987336575985, -7.76589206730162, -5.81054787011341, },
                    new double[] { -2.65482440590858, -10.5628263066491, -5.60468502395908, },
                    new double[] { -2.54620611667633, -13.0387387107748, -5.36223367466908, },
                    new double[] { -0.349991768598557, -6.54244110985515, -4.35843018634009, },
                    new double[] { 1.43021196126938, -14.1423935327282, 11.3171592025544, },
                    new double[] { -0.248833745718002, -25.6880129237476, 3.6943247495434, },
                    new double[] { -0.191526114940643, -7.40986142342928, 5.01053017361167, },
                    new double[] { 0.0262223184108734, -2.32355649224634, 5.02960958030255, },
                },
                new double[][]
                {
                    new double[] { -0.491838902235031, -6.14010393559236, 0.827477332024586, },
                    new double[] { -0.806065648794174, -7.15029676810841, -1.19623376104369, },
                    new double[] { -0.376655906438828, -8.79062775480082, -1.90518908829517, },
                    new double[] { 0.0747844576835632, -8.78933441325732, -1.96265207353993, },
                    new double[] { -0.375023484230042, 3.89681155173501, 9.01643231817069, },
                    new double[] { -2.8106614947319, -11.460008093918, 2.27801912994775, },
                    new double[] { 8.87353122234344, -36.8569805718597, 6.36432395690119, },
                    new double[] { 2.17160433530808, -6.57312981892095, 6.99683358454453, },
                },
                new double[][]
                {
                    new double[] { -2.59969010949135, -3.67992698430228, 1.09594294144671, },
                    new double[] { -1.09673067927361, -5.84256216502719, -0.576662929456575, },
                    new double[] { -1.31642892956734, -7.75851355520771, -2.38379618379558, },
                    new double[] { -0.119869410991669, -8.5749576027529, -1.84393133510667, },
                    new double[] { 1.6157403588295, -8.50491836461337, 1.75083250596366, },
                    new double[] { 1.66225507855415, -26.4882911957686, 1.98153904369032, },
                    new double[] { 2.55657434463501, -10.5098938623168, 11.632377227365, },
                    new double[] { 1.91832333803177, -9.98753621777953, 7.38483383044985, },
                    new double[] { 2.16058492660522, -2.7784029746222, 7.8378896386686, },
                },
                #endregion
            };

            var density = new MultivariateNormalDistribution(3);
            var model   = new HiddenMarkovModel <MultivariateNormalDistribution>(new Forward(5), density);

            var learning = new ViterbiLearning <MultivariateNormalDistribution>(model)
            {
                Tolerance      = 0.0001,
                Iterations     = 0,
                FittingOptions = new NormalOptions()
                {
                    Regularization = 0.0001
                }
            };

            double logLikelihood = learning.Run(observations);

            Assert.IsFalse(Double.IsNaN(logLikelihood));

            foreach (double value in model.Transitions)
            {
                Assert.IsFalse(Double.IsNaN(value));
            }

            foreach (double value in model.Probabilities)
            {
                Assert.IsFalse(Double.IsNaN(value));
            }
        }
Example #32
0
        public void RunTest()
        {
            // Example from
            // http://www.cs.columbia.edu/4761/notes07/chapter4.3-HMM.pdf



            double[][] observations =
            {
                new double[] { 0, 0, 0, 1, 0, 0 },
                new double[] { 1, 0, 0, 1, 0, 0 },
                new double[] { 0, 0, 1, 0, 0, 0 },
                new double[] { 0, 0, 0, 0, 1, 0 },
                new double[] { 1, 0, 0, 0, 1, 0 },
                new double[] { 0, 0, 0, 1, 1, 0 },
                new double[] { 1, 0, 0, 0, 0, 0 },
                new double[] { 1, 0, 1, 0, 0, 0 },
            };

            int[][] paths =
            {
                new int[] { 0, 0, 1, 0, 1, 0 },
                new int[] { 1, 0, 1, 0, 1, 0 },
                new int[] { 1, 0, 0, 1, 1, 0 },
                new int[] { 1, 0, 1, 1, 1, 0 },
                new int[] { 1, 0, 0, 1, 0, 1 },
                new int[] { 0, 0, 1, 0, 0, 1 },
                new int[] { 0, 0, 1, 1, 0, 1 },
                new int[] { 0, 1, 1, 1, 0, 0 },
            };


            GeneralDiscreteDistribution initial = new GeneralDiscreteDistribution(symbols: 2);

            var model = new HiddenMarkovModel <GeneralDiscreteDistribution>(states: 2, emissions: initial);

            var target = new MaximumLikelihoodLearning <GeneralDiscreteDistribution>(model);

            target.UseLaplaceRule = false;

            double logLikelihood = target.Run(observations, paths);

            var pi = Matrix.Exp(model.Probabilities);
            var A  = Matrix.Exp(model.Transitions);
            var B  = model.Emissions;

            Assert.AreEqual(0.5, pi[0]);
            Assert.AreEqual(0.5, pi[1]);

            Assert.AreEqual(7 / 20.0, A[0, 0], 1e-5);
            Assert.AreEqual(13 / 20.0, A[0, 1], 1e-5);
            Assert.AreEqual(14 / 20.0, A[1, 0], 1e-5);
            Assert.AreEqual(6 / 20.0, A[1, 1], 1e-5);

            Assert.AreEqual(17 / 25.0, B[0].ProbabilityMassFunction(0));
            Assert.AreEqual(8 / 25.0, B[0].ProbabilityMassFunction(1));
            Assert.AreEqual(19 / 23.0, B[1].ProbabilityMassFunction(0));
            Assert.AreEqual(4 / 23.0, B[1].ProbabilityMassFunction(1));

            Assert.AreEqual(-1.1472359046136624, logLikelihood);
        }
Example #33
0
    /*
     * this method passes all the possible directions
     * that can create a square to the HMM library
     * as observations. A and B are the state and
     * observation probabilities for the model
     * pi is the intial state of the model
     * the function returns true if the input matches any
     * of the observations used to train the model
    */
    bool squareEvalution(int [] input)
    {
        if(input.Length != 4){
            return false;
        }

        int[][] sequences = new int[][]
        {
            new int[]{ NORTH, EAST, SOUTH, WEST},
            new int[] { EAST, SOUTH, WEST, NORTH},
            new int[] { SOUTH, WEST, NORTH, EAST},
            new int[] { WEST, NORTH, EAST, SOUTH}
        };

        double [,] A = new double[8,8]
        {
            {0, 0, 1, 0, 0, 0, 0, 0},
            {0, 0, 0, 1, 0, 0, 0, 0},
            {0, 1, 0, 0, 0, 0, 0, 0},
            {1, 0, 0, 0, 0, 0, 0, 0},
            {0, 0, 0, 0, 0, 0, 0, 0},
            {0, 0, 0, 0, 0, 0, 0, 0},
            {0, 0, 0, 0, 0, 0, 0, 0},
            {0, 0, 0, 0, 0, 0, 0, 0}
        };

        double [,] B = new double[8,8]
        {
            {1, 0, 0, 0, 0, 0, 0, 0},
            {0, 1, 0, 0, 0, 0, 0, 0},
            {0, 0, 1, 0, 0, 0, 0, 0},
            {0, 0, 0, 1, 0, 0, 0, 0},
            {0, 0, 0, 0, 1, 0, 0, 0},
            {0, 0, 0, 0, 0, 1, 0, 0},
            {0, 0, 0, 0, 0, 0, 1, 0},
            {0, 0, 0, 0, 0, 0, 0, 1}
        };

        double [] pi = new double [] {0.25,0.25,0.25,0.25, 0, 0, 0, 0};

        HiddenMarkovModel model = new HiddenMarkovModel(A, B, pi);
        model.Learn(sequences, 0.0001);

        if(model.Evaluate(input) >= 0.25){
            return true;
        }else{
            return false;
        }
    }
Example #34
0
        public void LearnTest()
        {
            HiddenMarkovModel hmm = new HiddenMarkovModel(2, 3);

            int[] observation = new int[]
            {
                0, 1, 1, 2, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 1, 1, 1, 2, 0, 0,
                0, 0, 0, 0, 1, 2, 1, 1, 1, 0, 2, 0, 1, 0, 2, 2, 2, 0, 0, 2, 0, 1, 2, 2, 0, 1,
                1, 2, 2, 2, 0, 0, 1, 1, 2, 2, 0, 0, 2, 2, 0, 0, 1, 0, 1, 2, 0, 0, 0, 0, 2, 0,
                2, 0, 1, 1, 0, 1, 0, 0, 0, 1, 2, 1, 1, 2, 0, 2, 0, 2, 2, 0, 0, 1
            };

            int[] observation2 = new int[]
            {
                0, 1, 0, 0, 2, 1, 1, 0, 0, 2, 1, 0, 1, 1, 2, 0, 1, 1, 1, 0, 0, 2, 0, 0, 2, 1,
                1, 1, 2, 0, 2, 2, 1, 0, 1, 2, 0, 2, 1, 0, 2, 1, 1, 2, 0, 1, 0, 1, 1, 0, 1, 2,
                1, 0, 2, 0, 1, 0, 1, 2, 0, 0, 2, 0, 2, 0, 0, 1, 0, 0, 0, 0, 1, 1, 2, 2, 1, 2,
                0, 1, 1, 1, 2, 2, 1, 1, 1, 2, 2, 0, 2, 1, 1, 2, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0,
                0, 1, 0, 1, 0, 1, 0, 0, 2, 0, 1, 0, 2, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 2, 0,
                2, 2, 1, 2, 1, 2, 1, 0, 2, 1, 1, 2, 1, 2, 1, 0, 0, 2, 0, 0, 2, 2, 2, 0, 0, 1,
                0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0,
                0, 0, 1, 0, 2, 2, 2, 2, 2, 1, 2, 0, 1, 0, 1, 2, 2, 1, 0, 1, 1, 2, 1, 1, 1, 2,
                2, 2, 0, 1, 1, 1, 1, 2, 1, 0, 1, 0, 1, 1, 0, 2, 2, 2, 1, 1, 1, 1, 0, 2, 1, 0,
                2, 1, 1, 1, 2, 0, 0, 1, 1, 1, 1, 2, 1, 1, 2, 0, 0, 0, 0, 0, 2, 2, 2, 0, 1, 1,
                1, 0, 1, 0, 0, 0, 0, 2, 2, 2, 2, 0, 1, 1, 0, 1, 2, 1, 2, 1, 1, 0, 0, 0, 0, 2,
                2, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 2, 1, 2, 2, 0, 0, 0, 0, 0,
                0, 2, 0, 0, 2, 0, 0, 0, 2, 0, 1, 1, 2, 2, 1, 2, 1, 2, 0, 0, 0, 0, 2, 0, 2, 0,
                1, 0, 0, 2, 2, 1, 2, 1, 2, 2, 0, 1, 1, 1, 0, 0, 1, 1, 1, 2, 1, 0, 0, 2, 0, 0,
                0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 0, 2, 1, 1, 1, 1, 1, 2, 2, 0, 0, 1, 1, 1, 0, 0,
                2, 0, 1, 1, 0, 2, 2, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 1, 1, 0, 2, 0, 0, 0, 1, 1,
                1, 2, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 2, 2, 2, 0, 2, 0, 2, 1,
                2, 1, 0, 2, 1, 2, 1, 0, 0, 2, 1, 1, 1, 1, 0, 0, 0, 1, 2, 0, 2, 2, 1, 2, 1, 1,
                1, 0, 1, 0, 0, 0, 0, 2, 0, 1, 1, 1, 0, 2, 0, 1, 0, 2, 1, 2, 2, 0, 2, 1, 0, 0,
                2, 1, 2, 2, 0, 2, 1, 2, 1, 2, 0, 0, 0, 1, 2, 1, 2, 2, 1, 0, 0, 0, 1, 1, 2, 0,
                2, 1, 0, 0, 0, 1, 0, 0, 1, 2, 0, 0, 1, 2, 2, 2, 0, 1, 2, 0, 1, 0, 1, 0, 2, 2,
                0, 2, 0, 1, 1, 0, 1, 1, 1, 2, 2, 0, 0, 0, 0, 0, 1, 1, 0, 0, 2, 0, 0, 1, 0, 0,
                1, 0, 2, 1, 1, 1, 1, 1, 2, 0, 0, 2, 0, 1, 2, 0, 1, 1, 1, 2, 0, 0, 0, 1, 2, 0,
                0, 0, 2, 2, 1, 1, 1, 0, 1, 1, 0, 2, 2, 0, 1, 2, 2, 1, 1, 1, 2, 1, 0, 2, 0, 0,
                1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 0, 1, 0, 2, 2, 0, 1, 2, 1, 1, 2, 1, 0, 1, 2, 1
            };


            var teacher = new BaumWelchLearning(hmm)
            {
                Iterations = 650,
                Tolerance  = 0
            };

            double ll = teacher.Run(observation);


            double[] pi = { 1.0, 0.0 };

            double[,] A =
            {
                { 0.7, 0.3 },
                { 0.5, 0.5 }
            };

            double[,] B =
            {
                { 0.6, 0.1, 0.3 },
                { 0.1, 0.7, 0.2 }
            };


            var hmmA = Matrix.Exp(hmm.Transitions);
            var hmmB = Matrix.Exp(hmm.Emissions);
            var hmmP = Matrix.Exp(hmm.Probabilities);


            Assert.IsTrue(Matrix.IsEqual(A, hmmA, 0.1));
            Assert.IsTrue(Matrix.IsEqual(B, hmmB, 0.1));
            Assert.IsTrue(Matrix.IsEqual(pi, hmmP));
        }
        private void ComputeStep(HiddenMarkovModel hmm, IMLDataPair o,
                int t, int j)
        {
            double minDelta = Double.PositiveInfinity;
            int min_psy = 0;

            for (int i = 0; i < hmm.StateCount; i++)
            {
                double thisDelta = this.delta[t - 1][i]
                        - Math.Log(hmm.TransitionProbability[i][j]);

                if (minDelta > thisDelta)
                {
                    minDelta = thisDelta;
                    min_psy = i;
                }
            }

            this.delta[t][j] = minDelta
                    - Math.Log(hmm.StateDistributions[j].Probability(o));
            this.psy[t][j] = min_psy;
        }
Example #36
0
        public void LearnTest3()
        {
            // We will try to create a Hidden Markov Model which
            //  can detect if a given sequence starts with a zero
            //  and has any number of ones after that.
            int[][] sequences = new int[][]
            {
                new int[] { 0, 1, 1, 1, 1, 0, 1, 1, 1, 1 },
                new int[] { 0, 1, 1, 1, 0, 1, 1, 1, 1, 1 },
                new int[] { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
                new int[] { 0, 1, 1, 1, 1, 1 },
                new int[] { 0, 1, 1, 1, 1, 1, 1 },
                new int[] { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
                new int[] { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
            };

            // Creates a new Hidden Markov Model with 3 states for
            //  an output alphabet of two characters (zero and one)
            HiddenMarkovModel hmm = new HiddenMarkovModel(3, 2);

            // Try to fit the model to the data until the difference in
            //  the average log-likelihood changes only by as little as 0.0001
            var teacher = new BaumWelchLearning(hmm)
            {
                Tolerance = 0.0001, Iterations = 0
            };
            double ll = teacher.Run(sequences);

            // Calculate the probability that the given
            //  sequences originated from the model
            double l1; hmm.Decode(new int[] { 0, 1 }, out l1);       // 0.4999
            double l2; hmm.Decode(new int[] { 0, 1, 1, 1 }, out l2); // 0.1145

            // Sequences which do not start with zero have much lesser probability.
            double l3; hmm.Decode(new int[] { 1, 1 }, out l3);       // 0.0000
            double l4; hmm.Decode(new int[] { 1, 0, 0, 0 }, out l4); // 0.0000

            // Sequences which contains few errors have higher probability
            //  than the ones which do not start with zero. This shows some
            //  of the temporal elasticity and error tolerance of the HMMs.
            double l5; hmm.Decode(new int[] { 0, 1, 0, 1, 1, 1, 1, 1, 1 }, out l5); // 0.0002
            double l6; hmm.Decode(new int[] { 0, 1, 1, 1, 1, 1, 1, 0, 1 }, out l6); // 0.0002

            ll = System.Math.Exp(ll);
            l1 = System.Math.Exp(l1);
            l2 = System.Math.Exp(l2);
            l3 = System.Math.Exp(l3);
            l4 = System.Math.Exp(l4);
            l5 = System.Math.Exp(l5);
            l6 = System.Math.Exp(l6);

            Assert.AreEqual(0.95151126952069587, ll, 1e-4);
            Assert.AreEqual(0.4999419764097881, l1, 1e-4);
            Assert.AreEqual(0.1145702973735144, l2, 1e-4);
            Assert.AreEqual(0.0000529972606821, l3, 1e-4);
            Assert.AreEqual(0.0000000000000001, l4, 1e-4);
            Assert.AreEqual(0.0002674509390361, l5, 1e-4);
            Assert.AreEqual(0.0002674509390361, l6, 1e-4);

            Assert.IsTrue(l1 > l3 && l1 > l4);
            Assert.IsTrue(l2 > l3 && l2 > l4);
        }
        /// <inheritdoc/>
        public void Iteration()
        {
            HiddenMarkovModel hmm = _modelHmm.CloneStructure();

            LearnPi(hmm);
            LearnTransition(hmm);
            LearnOpdf(hmm);

            _done = OptimizeCluster(hmm);

            _method = hmm;
        }
Example #38
0
        public void LearnTest6()
        {
            // We will try to create a Hidden Markov Model which
            //  can detect if a given sequence starts with a zero
            //  and has any number of ones after that.
            int[][] sequences = new int[][]
            {
                new int[] { 0, 1, 1, 1, 1, 0, 1, 1, 1, 1 },
                new int[] { 0, 1, 1, 1, 0, 1, 1, 1, 1, 1 },
                new int[] { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
                new int[] { 0, 1, 1, 1, 1, 1 },
                new int[] { 0, 1, 1, 1, 1, 1, 1 },
                new int[] { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
                new int[] { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
            };

            // Creates a new Hidden Markov Model with 3 states for
            //  an output alphabet of two characters (zero and one)
            HiddenMarkovModel hmm = new HiddenMarkovModel(3, 2);

            // Try to fit the model to the data until the difference in
            //  the average log-likelihood changes only by as little as 0.0001
            var teacher = new BaumWelchLearning(hmm)
            {
                Tolerance = 0.0001, Iterations = 0
            };
            double ll = teacher.Run(sequences);

            // Calculate the probability that the given
            //  sequences originated from the model
            double l1 = hmm.Evaluate(new int[] { 0, 1 });       // 0.999
            double l2 = hmm.Evaluate(new int[] { 0, 1, 1, 1 }); // 0.916

            // Sequences which do not start with zero have much lesser probability.
            double l3 = hmm.Evaluate(new int[] { 1, 1 });       // 0.000
            double l4 = hmm.Evaluate(new int[] { 1, 0, 0, 0 }); // 0.000

            // Sequences which contains few errors have higher probability
            //  than the ones which do not start with zero. This shows some
            //  of the temporal elasticity and error tolerance of the HMMs.
            double l5 = hmm.Evaluate(new int[] { 0, 1, 0, 1, 1, 1, 1, 1, 1 }); // 0.034
            double l6 = hmm.Evaluate(new int[] { 0, 1, 1, 1, 1, 1, 1, 0, 1 }); // 0.034

            double pl = System.Math.Exp(ll);
            double p1 = System.Math.Exp(l1);
            double p2 = System.Math.Exp(l2);
            double p3 = System.Math.Exp(l3);
            double p4 = System.Math.Exp(l4);
            double p5 = System.Math.Exp(l5);
            double p6 = System.Math.Exp(l6);

            Assert.AreEqual(0.95151126952069587, pl, 1e-6);
            Assert.AreEqual(0.99996863060890995, p1, 1e-6);
            Assert.AreEqual(0.91667240076011669, p2, 1e-6);
            Assert.AreEqual(0.00002335133758386, p3, 1e-6);
            Assert.AreEqual(0.00000000000000012, p4, 1e-6);
            Assert.AreEqual(0.034237231443226858, p5, 1e-6);
            Assert.AreEqual(0.034237195920532461, p6, 1e-6);

            Assert.IsTrue(l1 > l3 && l1 > l4);
            Assert.IsTrue(l2 > l3 && l2 > l4);
        }
        /// <summary>
        /// Learn Pi, the starting probabilities. 
        /// </summary>
        /// <param name="hmm">The HMM.</param>
        private void LearnPi(HiddenMarkovModel hmm)
        {
            var pi = new double[_states];

            for (int i = 0; i < _states; i++)
            {
                pi[i] = 0.0;
            }

            foreach (IMLDataSet sequence in _training.Sequences)
            {
                pi[_clusters.Cluster(sequence[0])]++;
            }

            for (int i = 0; i < _states; i++)
            {
                hmm.Pi[i] = pi[i]/(int) _training.Count;
            }
        }
Example #40
0
 /// <summary>
 ///   Creates a new instance of the Baum-Welch learning algorithm.
 /// </summary>
 public BaumWelchLearning(HiddenMarkovModel model)
     : base(model)
 {
     this.model = model;
 }
        /// <summary>
        /// Optimize the clusters. 
        /// </summary>
        /// <param name="hmm">The HMM.</param>
        /// <returns>True if the cluster was not modified.</returns>
        private bool OptimizeCluster(HiddenMarkovModel hmm)
        {
            bool result = false;

            foreach (IMLDataSet obsSeq in _training.Sequences)
            {
                var vc = new ViterbiCalculator(obsSeq, hmm);
                int[] states = vc.CopyStateSequence();

                for (int i = 0; i < states.Length; i++)
                {
                    IMLDataPair o = obsSeq[i];

                    if (_clusters.Cluster(o) != states[i])
                    {
                        result = true;
                        _clusters.Remove(o, _clusters.Cluster(o));
                        _clusters.Put(o, states[i]);
                    }
                }
            }

            return !result;
        }
 public abstract double[][][] EstimateXi(IMLDataSet sequence,
                                         ForwardBackwardCalculator fbc, HiddenMarkovModel hmm);
        /// <summary>
        /// Compute alpha.
        /// </summary>
        /// <param name="hmm">The HMM.</param>
        /// <param name="seq">The sequence.</param>
        protected void ComputeAlpha(HiddenMarkovModel hmm,
                                    IMLDataSet seq)
        {
            Alpha = EngineArray.AllocateDouble2D((int) seq.Count, hmm.StateCount);

            for (int i = 0; i < hmm.StateCount; i++)
            {
                ComputeAlphaInit(hmm, seq[0], i);
            }
            Scale(_ctFactors, Alpha, 0);

            IEnumerator<IMLDataPair> seqIterator = seq.GetEnumerator();
            if (seqIterator.MoveNext())
            {
                for (int t = 1; t < seq.Count; t++)
                {
                    seqIterator.MoveNext();
                    IMLDataPair observation = seqIterator.Current;

                    for (int i = 0; i < hmm.StateCount; i++)
                    {
                        ComputeAlphaStep(hmm, observation, t, i);
                    }
                    Scale(_ctFactors, Alpha, t);
                }
            }
        }
 protected BaseBaumWelch(HiddenMarkovModel hmm,
                      IMLSequenceSet training)
 {
     _method = hmm;
     _training = training;
 }
        /// <summary>
        /// Compute the probability.
        /// </summary>
        /// <param name="seq">The sequence.</param>
        /// <param name="hmm">The HMM.</param>
        /// <param name="doAlha">The alpha.</param>
        /// <param name="doBeta">The beta.</param>
        private void ComputeProbability(IMLDataSet seq,
                                        HiddenMarkovModel hmm, bool doAlha, bool doBeta)
        {
            _lnProbability = 0.0;

            for (int t = 0; t < seq.Count; t++)
            {
                _lnProbability += Math.Log(_ctFactors[t]);
            }

            probability = Math.Exp(_lnProbability);
        }
Example #46
0
 private static void compare(HiddenMarkovModel hmm1, HiddenMarkovModel hmm2)
 {
     Assert.IsTrue(hmm1.LogInitial.IsEqual(hmm2.LogInitial));
     Assert.IsTrue(hmm1.LogEmissions.IsEqual(hmm2.LogEmissions));
     Assert.IsTrue(hmm1.LogTransitions.IsEqual(hmm2.LogTransitions));
 }
Example #47
0
        public void PredictTest()
        {
            int[][] sequences = new int[][]
            {
                new int[] { 0, 3, 1, 2 },
            };


            HiddenMarkovModel hmm = new HiddenMarkovModel(new Forward(4), 4);

            var teacher = new BaumWelchLearning(hmm)
            {
                Tolerance = 1e-10, Iterations = 0
            };
            double ll = teacher.Run(sequences);

            double l11, l12, l13, l14;

            int p1 = hmm.Predict(new int[] { 0 }, 1, out l11)[0];
            int p2 = hmm.Predict(new int[] { 0, 3 }, 1, out l12)[0];
            int p3 = hmm.Predict(new int[] { 0, 3, 1 }, 1, out l13)[0];
            int p4 = hmm.Predict(new int[] { 0, 3, 1, 2 }, 1, out l14)[0];

            Assert.AreEqual(3, p1);
            Assert.AreEqual(1, p2);
            Assert.AreEqual(2, p3);
            Assert.AreEqual(2, p4);

            double l21 = hmm.Evaluate(new int[] { 0, 3 });
            double l22 = hmm.Evaluate(new int[] { 0, 3, 1 });
            double l23 = hmm.Evaluate(new int[] { 0, 3, 1, 2 });
            double l24 = hmm.Evaluate(new int[] { 0, 3, 1, 2, 2 });

            Assert.AreEqual(l11, l21, 1e-10);
            Assert.AreEqual(l12, l22, 1e-10);
            Assert.AreEqual(l13, l23, 1e-10);
            Assert.AreEqual(l14, l24, 1e-10);

            Assert.IsFalse(double.IsNaN(l11));
            Assert.IsFalse(double.IsNaN(l12));
            Assert.IsFalse(double.IsNaN(l13));
            Assert.IsFalse(double.IsNaN(l14));

            Assert.IsFalse(double.IsNaN(l21));
            Assert.IsFalse(double.IsNaN(l22));
            Assert.IsFalse(double.IsNaN(l23));
            Assert.IsFalse(double.IsNaN(l24));

            double ln1;

            int[] pn = hmm.Predict(new int[] { 0 }, 4, out ln1);

            Assert.AreEqual(4, pn.Length);
            Assert.AreEqual(3, pn[0]);
            Assert.AreEqual(1, pn[1]);
            Assert.AreEqual(2, pn[2]);
            Assert.AreEqual(2, pn[3]);

            double ln2 = hmm.Evaluate(new int[] { 0, 3, 1, 2, 2 });

            Assert.AreEqual(ln1, ln2, 1e-10);
        }
Example #48
0
        static void Main(string[] args)
        {
            //// Create a model with given probabilities
            //HiddenMarkovModel hmm = new HiddenMarkovModel(
            //transitions: new[,] // matrix A
            //{
            //    { 0.25, 0.25, 0.00 },
            //    { 0.33, 0.33, 0.33 },
            //    { 0.90, 0.10, 0.00 },
            //},
            //emissions: new[,] // matrix B
            //{
            //    { 0.1, 0.1, 0.8 },
            //    { 0.6, 0.2, 0.2 },
            //    { 0.9, 0.1, 0.0 },
            //},
            //initial: new[]  // vector pi
            //{
            //    0.25, 0.25, 0.0
            //});

            //// Create an observation sequence of up to 2 symbols (0 or 1)
            //int[] observationSequence = new[] { 0, 1, 1, 0};

            //// Decode the sequence: the path will be 1-1-1-1-2-0-1-1
            //int[] stateSequence = hmm.Decode(observationSequence);
            //foreach (int a in stateSequence)
            //{
            //    System.Console.Write(a + " ");
            //}
            //////////////////////////////////////////////////////////////////////////////
            // Create the transation matrix A
            double[,] transition =
            {
                { 0.3, 0.2, 0.2 },
                { 0.4, 0.3, 0.1 },
                { 0.4, 0.3, 0.1 }
            };

            // emission probability by kmean algo.
            double[,] emission =
            {
                {  0.55, 0.075, 0.275, 0, 0.1 },   //Dance 1
                {  0.52,  0.22,  0.16, 0, 0.1 },   //Dance 2
                { 0.357, 0.357, 0.186, 0, 0.1 }    //Dance 3
            };

            // Create the initial probabilities pi
            double[] initial =
            {
                0.4, 0.2, 0.4
            };

            // Create a new hidden Markov model
            HiddenMarkovModel hmm = new HiddenMarkovModel(transition, emission, initial);

            // After that, one could, for example, query the probability
            // of a sequence ocurring. We will consider the sequence
            int[] sequence = new int[] { 0, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 1, 2, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 };

            // And now we will evaluate its likelihood
            double logLikelihood = hmm.Evaluate(sequence);

            // At this point, the log-likelihood of the sequence
            // ocurring within the model is -3.3928721329161653.

            // We can also get the Viterbi path of the sequence
            int[] path = hmm.Decode(sequence, out logLikelihood);

            // At this point, the state path will be 1-0-0 and the
            // log-likelihood will be -4.3095199438871337


            foreach (int a in path)
            {
                System.Console.Write(a + " ");
            }
            System.Console.ReadKey();
        }
        public void Iteration()
        {
            HiddenMarkovModel nhmm;
            nhmm = _method.Clone();

            var allGamma = new double[_training.SequenceCount][][];
            double[][] aijNum = EngineArray.AllocateDouble2D(_method.StateCount, _method.StateCount);
            var aijDen = new double[_method.StateCount];

            EngineArray.Fill(aijDen, 0.0);
            for (int i = 0; i < _method.StateCount; i++)
            {
                EngineArray.Fill(aijNum[i], 0.0);
            }

            int g = 0;
            foreach (IMLDataSet obsSeq in _training.Sequences)
            {
                ForwardBackwardCalculator fbc = GenerateForwardBackwardCalculator(
                    obsSeq, _method);

                double[][][] xi = EstimateXi(obsSeq, fbc, _method);
                double[][] gamma = allGamma[g++] = EstimateGamma(xi, fbc);

                for (int i = 0; i < _method.StateCount; i++)
                {
                    for (int t = 0; t < (obsSeq.Count - 1); t++)
                    {
                        aijDen[i] += gamma[t][i];

                        for (int j = 0; j < _method.StateCount; j++)
                        {
                            aijNum[i][j] += xi[t][i][j];
                        }
                    }
                }
            }

            for (int i = 0; i < _method.StateCount; i++)
            {
                if (aijDen[i] == 0.0)
                {
                    for (int j = 0; j < _method.StateCount; j++)
                    {
                        nhmm.TransitionProbability[i][j] =
                            _method.TransitionProbability[i][j];
                    }
                }
                else
                {
                    for (int j = 0; j < _method.StateCount; j++)
                    {
                        nhmm.TransitionProbability[i][j] = aijNum[i][j]
                                                           /aijDen[i];
                    }
                }
            }

            /* compute pi */
            for (int i = 0; i < _method.StateCount; i++)
            {
                nhmm.Pi[i] = 0.0;
            }

            for (int o = 0; o < _training.SequenceCount; o++)
            {
                for (int i = 0; i < _method.StateCount; i++)
                {
                    nhmm.Pi[i] += (allGamma[o][0][i]/_training
                                                         .SequenceCount);
                }
            }

            /* compute pdfs */
            for (int i = 0; i < _method.StateCount; i++)
            {
                var weights = new double[_training.Count];
                double sum = 0.0;
                int j = 0;

                int o = 0;
                foreach (IMLDataSet obsSeq in _training.Sequences)
                {
                    for (int t = 0; t < obsSeq.Count; t++, j++)
                    {
                        sum += weights[j] = allGamma[o][t][i];
                    }
                    o++;
                }

                for (j--; j >= 0; j--)
                {
                    weights[j] /= sum;
                }

                IStateDistribution opdf = nhmm.StateDistributions[i];
                opdf.Fit(_training, weights);
            }

            _method = nhmm;
            Iterations++;
        }
Example #50
0
        public void ConstructorTest()
        {
            HiddenMarkovModel hmm;

            double[,] A, B;
            double[] pi;

            // Create a HMM with 2 states and 4 symbols
            hmm = new HiddenMarkovModel(2, 4);

            A = new double[, ]
            {
                { 0.5, 0.5 },
                { 0.5, 0.5 }
            };

            B = new double[, ]
            {
                { 0.25, 0.25, 0.25, 0.25 },
                { 0.25, 0.25, 0.25, 0.25 },
            };

            pi = new double[] { 1, 0 };

            Assert.AreEqual(2, hmm.States);
            Assert.AreEqual(4, hmm.Symbols);
            Assert.IsTrue(Matrix.Log(A).IsEqual(hmm.Transitions));
            Assert.IsTrue(Matrix.Log(B).IsEqual(hmm.Emissions));
            Assert.IsTrue(Matrix.Log(pi).IsEqual(hmm.Probabilities));



            hmm = new HiddenMarkovModel(new Forward(2), 4);

            A = new double[, ]
            {
                { 0.5, 0.5 },
                { 0.0, 1.0 }
            };

            B = new double[, ]
            {
                { 0.25, 0.25, 0.25, 0.25 },
                { 0.25, 0.25, 0.25, 0.25 },
            };

            pi = new double[] { 1, 0 };

            Assert.AreEqual(2, hmm.States);
            Assert.AreEqual(4, hmm.Symbols);
            Assert.IsTrue(Matrix.Log(A).IsEqual(hmm.Transitions));
            Assert.IsTrue(Matrix.Log(B).IsEqual(hmm.Emissions));
            Assert.IsTrue(Matrix.Log(pi).IsEqual(hmm.Probabilities));


            hmm = new HiddenMarkovModel(A, B, pi);
            Assert.AreEqual(2, hmm.States);
            Assert.AreEqual(4, hmm.Symbols);
            Assert.IsTrue(Matrix.Log(A).IsEqual(hmm.Transitions));
            Assert.IsTrue(Matrix.Log(B).IsEqual(hmm.Emissions));
            Assert.IsTrue(Matrix.Log(pi).IsEqual(hmm.Probabilities));
        }
 public abstract ForwardBackwardCalculator GenerateForwardBackwardCalculator(
     IMLDataSet sequence, HiddenMarkovModel hmm);
Example #52
0
        public void LearnTest()
        {
            Accord.Math.Tools.SetupGenerator(0);

            HiddenMarkovModel hmm = new HiddenMarkovModel(new Ergodic(2), 3);

            int[] observation = new int[]
            {
                0, 1, 1, 2, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 1, 1, 1, 2, 0, 0,
                0, 0, 0, 0, 1, 2, 1, 1, 1, 0, 2, 0, 1, 0, 2, 2, 2, 0, 0, 2, 0, 1, 2, 2, 0, 1,
                1, 2, 2, 2, 0, 0, 1, 1, 2, 2, 0, 0, 2, 2, 0, 0, 1, 0, 1, 2, 0, 0, 0, 0, 2, 0,
                2, 0, 1, 1, 0, 1, 0, 0, 0, 1, 2, 1, 1, 2, 0, 2, 0, 2, 2, 0, 0, 1
            };

            int[] observation2 = new int[]
            {
                0, 1, 0, 0, 2, 1, 1, 0, 0, 2, 1, 0, 1, 1, 2, 0, 1, 1, 1, 0, 0, 2, 0, 0, 2, 1,
                1, 1, 2, 0, 2, 2, 1, 0, 1, 2, 0, 2, 1, 0, 2, 1, 1, 2, 0, 1, 0, 1, 1, 0, 1, 2,
                1, 0, 2, 0, 1, 0, 1, 2, 0, 0, 2, 0, 2, 0, 0, 1, 0, 0, 0, 0, 1, 1, 2, 2, 1, 2,
                0, 1, 1, 1, 2, 2, 1, 1, 1, 2, 2, 0, 2, 1, 1, 2, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0,
                0, 1, 0, 1, 0, 1, 0, 0, 2, 0, 1, 0, 2, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 2, 0,
                2, 2, 1, 2, 1, 2, 1, 0, 2, 1, 1, 2, 1, 2, 1, 0, 0, 2, 0, 0, 2, 2, 2, 0, 0, 1,
                0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0,
                0, 0, 1, 0, 2, 2, 2, 2, 2, 1, 2, 0, 1, 0, 1, 2, 2, 1, 0, 1, 1, 2, 1, 1, 1, 2,
                2, 2, 0, 1, 1, 1, 1, 2, 1, 0, 1, 0, 1, 1, 0, 2, 2, 2, 1, 1, 1, 1, 0, 2, 1, 0,
                2, 1, 1, 1, 2, 0, 0, 1, 1, 1, 1, 2, 1, 1, 2, 0, 0, 0, 0, 0, 2, 2, 2, 0, 1, 1,
                1, 0, 1, 0, 0, 0, 0, 2, 2, 2, 2, 0, 1, 1, 0, 1, 2, 1, 2, 1, 1, 0, 0, 0, 0, 2,
                2, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 2, 1, 2, 2, 0, 0, 0, 0, 0,
                0, 2, 0, 0, 2, 0, 0, 0, 2, 0, 1, 1, 2, 2, 1, 2, 1, 2, 0, 0, 0, 0, 2, 0, 2, 0,
                1, 0, 0, 2, 2, 1, 2, 1, 2, 2, 0, 1, 1, 1, 0, 0, 1, 1, 1, 2, 1, 0, 0, 2, 0, 0,
                0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 0, 2, 1, 1, 1, 1, 1, 2, 2, 0, 0, 1, 1, 1, 0, 0,
                2, 0, 1, 1, 0, 2, 2, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 1, 1, 0, 2, 0, 0, 0, 1, 1,
                1, 2, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 2, 2, 2, 0, 2, 0, 2, 1,
                2, 1, 0, 2, 1, 2, 1, 0, 0, 2, 1, 1, 1, 1, 0, 0, 0, 1, 2, 0, 2, 2, 1, 2, 1, 1,
                1, 0, 1, 0, 0, 0, 0, 2, 0, 1, 1, 1, 0, 2, 0, 1, 0, 2, 1, 2, 2, 0, 2, 1, 0, 0,
                2, 1, 2, 2, 0, 2, 1, 2, 1, 2, 0, 0, 0, 1, 2, 1, 2, 2, 1, 0, 0, 0, 1, 1, 2, 0,
                2, 1, 0, 0, 0, 1, 0, 0, 1, 2, 0, 0, 1, 2, 2, 2, 0, 1, 2, 0, 1, 0, 1, 0, 2, 2,
                0, 2, 0, 1, 1, 0, 1, 1, 1, 2, 2, 0, 0, 0, 0, 0, 1, 1, 0, 0, 2, 0, 0, 1, 0, 0,
                1, 0, 2, 1, 1, 1, 1, 1, 2, 0, 0, 2, 0, 1, 2, 0, 1, 1, 1, 2, 0, 0, 0, 1, 2, 0,
                0, 0, 2, 2, 1, 1, 1, 0, 1, 1, 0, 2, 2, 0, 1, 2, 2, 1, 1, 1, 2, 1, 0, 2, 0, 0,
                1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 0, 1, 0, 2, 2, 0, 1, 2, 1, 1, 2, 1, 0, 1, 2, 1
            };


            var teacher = new ViterbiLearning(hmm)
            {
                Iterations = 650,
                Tolerance  = 0
            };

            double ll = teacher.Run(observation);


            double[] pi = { 0.66, 0.33 };

            double[,] A =
            {
                { 0.99, 0.01 },
                { 0.50, 0.50 }
            };

            double[,] B =
            {
                { 0.44, 0.27, 0.28 },
                { 0.33, 0.33, 0.33 }
            };


            var hmmA = Matrix.Exp(hmm.Transitions);
            var hmmB = Matrix.Exp(hmm.Emissions);
            var hmmP = Matrix.Exp(hmm.Probabilities);


            Assert.IsTrue(Matrix.IsEqual(A, hmmA, 0.1));
            Assert.IsTrue(Matrix.IsEqual(B, hmmB, 0.1));
            Assert.IsTrue(Matrix.IsEqual(pi, hmmP, 0.1));
        }
 /// <summary>
 ///   Creates a new instance of the Maximum Likelihood learning algorithm.
 /// </summary>
 /// 
 public MaximumLikelihoodLearning(HiddenMarkovModel model)
 {
     this.model = model;
 }
Example #54
0
        public void LearnTest3()
        {
            Accord.Math.Tools.SetupGenerator(0);

            // We will try to create a Hidden Markov Model which
            //  can detect if a given sequence starts with a zero
            //  and has any number of ones after that.
            //
            int[][] sequences = new int[][]
            {
                new int[] { 0, 1, 1, 1, 1, 0, 1, 1, 1, 1 },
                new int[] { 0, 1, 1, 1, 0, 1, 1, 1, 1, 1 },
                new int[] { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
                new int[] { 0, 1, 1, 1, 1, 1 },
                new int[] { 0, 1, 1, 1, 1, 1, 1 },
                new int[] { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
                new int[] { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
            };

            // Creates a new Hidden Markov Model with 3 states for
            //  an output alphabet of two characters (zero and one)
            //
            HiddenMarkovModel hmm = new HiddenMarkovModel(new Forward(3), 2);

            // Try to fit the model to the data until the difference in
            //  the average log-likelihood changes only by as little as 0.0001
            //
            var teacher = new ViterbiLearning(hmm)
            {
                Tolerance = 0.0001, Iterations = 0
            };

            //
            double ll = teacher.Run(sequences);

            // Calculate the probability that the given
            //  sequences originated from the model
            //
            double l1; hmm.Decode(new int[] { 0, 1 }, out l1);        // 0.5394
            double l2; hmm.Decode(new int[] { 0, 1, 1, 1 }, out l2);  // 0.4485

            // Sequences which do not start with zero have much lesser probability.
            double l3; hmm.Decode(new int[] { 1, 1 }, out l3);        // 0.0864
            double l4; hmm.Decode(new int[] { 1, 0, 0, 0 }, out l4);  // 0.0004


            // Sequences which contains few errors have higher probability
            //  than the ones which do not start with zero. This shows some
            //  of the temporal elasticity and error tolerance of the HMMs.
            //
            double l5; hmm.Decode(new int[] { 0, 1, 0, 1, 1, 1, 1, 1, 1 }, out l5); // 0.0154
            double l6; hmm.Decode(new int[] { 0, 1, 1, 1, 1, 1, 1, 0, 1 }, out l6); // 0.0154


            ll = System.Math.Exp(ll);
            l1 = System.Math.Exp(l1);
            l2 = System.Math.Exp(l2);
            l3 = System.Math.Exp(l3);
            l4 = System.Math.Exp(l4);
            l5 = System.Math.Exp(l5);
            l6 = System.Math.Exp(l6);

            Assert.AreEqual(1.754393540912413, ll, 1e-6);
            Assert.AreEqual(0.53946360153256712, l1, 1e-6);
            Assert.AreEqual(0.44850249229903377, l2, 1e-6);
            Assert.AreEqual(0.08646414524833077, l3, 1e-6);
            Assert.AreEqual(0.00041152263374485, l4, 1e-6);
            Assert.AreEqual(0.01541807695931400, l5, 1e-6);
            Assert.AreEqual(0.01541807695931400, l6, 1e-6);

            Assert.IsTrue(l1 > l3 && l1 > l4);
            Assert.IsTrue(l2 > l3 && l2 > l4);
        }
Example #55
0
 public ParticleSet(HiddenMarkovModel hmm)
 {
     particles = new List<Particle>();
     this.hmm = hmm;
 }
Example #56
0
        public void LearnTest6()
        {
            Accord.Math.Tools.SetupGenerator(0);

            // We will try to create a Hidden Markov Model which
            //  can detect if a given sequence starts with a zero
            //  and has any number of ones after that.
            //
            int[][] sequences = new int[][]
            {
                new int[] { 0, 1, 1, 1, 1, 0, 1, 1, 1, 1 },
                new int[] { 0, 1, 1, 1, 0, 1, 1, 1, 1, 1 },
                new int[] { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
                new int[] { 0, 1, 1, 1, 1, 1 },
                new int[] { 0, 1, 1, 1, 1, 1, 1 },
                new int[] { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
                new int[] { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
            };

            // Creates a new Hidden Markov Model with 3 states for
            //  an output alphabet of two characters (zero and one)
            //
            HiddenMarkovModel hmm = new HiddenMarkovModel(new Forward(3), 2);

            // Try to fit the model to the data until the difference in
            //  the average log-likelihood changes only by as little as 0.0001
            //
            var teacher = new ViterbiLearning(hmm)
            {
                Tolerance = 0.0001, Iterations = 0
            };

            double ll = teacher.Run(sequences);


            // Calculate the probability that the given
            //  sequences originated from the model
            double l1 = hmm.Evaluate(new int[] { 0, 1 });       // 0.613
            double l2 = hmm.Evaluate(new int[] { 0, 1, 1, 1 }); // 0.500


            // Sequences which do not start with zero have much lesser probability.
            double l3 = hmm.Evaluate(new int[] { 1, 1 });       // 0.186
            double l4 = hmm.Evaluate(new int[] { 1, 0, 0, 0 }); // 0.003

            // Sequences which contains few errors have higher probability
            //  than the ones which do not start with zero. This shows some
            //  of the temporal elasticity and error tolerance of the HMMs.
            //
            double l5 = hmm.Evaluate(new int[] { 0, 1, 0, 1, 1, 1, 1, 1, 1 }); // 0.033
            double l6 = hmm.Evaluate(new int[] { 0, 1, 1, 1, 1, 1, 1, 0, 1 }); // 0.026


            double pl = System.Math.Exp(ll);
            double p1 = System.Math.Exp(l1);
            double p2 = System.Math.Exp(l2);
            double p3 = System.Math.Exp(l3);
            double p4 = System.Math.Exp(l4);
            double p5 = System.Math.Exp(l5);
            double p6 = System.Math.Exp(l6);

            Assert.AreEqual(1.754393540912413, pl, 1e-6);
            Assert.AreEqual(0.61368718756104801, p1, 1e-6);
            Assert.AreEqual(0.50049466955818356, p2, 1e-6);
            Assert.AreEqual(0.18643340385264684, p3, 1e-6);
            Assert.AreEqual(0.00300262431355424, p4, 1e-6);
            Assert.AreEqual(0.03338686211012481, p5, 1e-6);
            Assert.AreEqual(0.02659161933179825, p6, 1e-6);

            Assert.IsTrue(l1 > l3 && l1 > l4);
            Assert.IsTrue(l2 > l3 && l2 > l4);
        }
 public override ForwardBackwardCalculator GenerateForwardBackwardCalculator(
         IMLDataSet sequence, HiddenMarkovModel hmm)
 {
     return new ForwardBackwardScaledCalculator(sequence, hmm,
             true, true);
 }
Example #58
0
 /// <summary>
 ///   Creates a new instance of the Baum-Welch learning algorithm.
 /// </summary>
 ///
 public BaumWelchLearning(HiddenMarkovModel <TDistribution> model)
     : base(model)
 {
     this.model = model;
 }
Example #59
0
        public void LearnTest2()
        {
            Accord.Math.Tools.SetupGenerator(0);
            int[][] sequences = new int[500][];
            for (int i = 0; i < sequences.Length; i++)
            {
                sequences[i] = new int[Accord.Math.Tools.Random.Next(20, 80)];

                int start = Accord.Math.Tools.Random.Next();

                for (int j = 0; j < sequences[i].Length; j++)
                {
                    double s = Math.Sin(j + start);
                    double u = ((s + 1) / 2.0);
                    sequences[i][j] = (int)(u * 10);
                }
            }

            HiddenMarkovModel hmm1;
            double            ll1;

            {
                Accord.Math.Tools.SetupGenerator(0);
                hmm1 = new HiddenMarkovModel(10, 10, true);
                var teacher = new ViterbiLearning(hmm1)
                {
                    Iterations     = 1,
                    Tolerance      = 1e-15,
                    Batches        = 1,
                    UseLaplaceRule = true
                };
                ll1 = teacher.Run(sequences);
            }

            HiddenMarkovModel hmm10;
            double            ll10;

            {
                Accord.Math.Tools.SetupGenerator(0);
                hmm10 = new HiddenMarkovModel(10, 10, true);

                var teacher = new ViterbiLearning(hmm10)
                {
                    Iterations     = 100,
                    Tolerance      = 1e-15,
                    Batches        = 1,
                    UseLaplaceRule = true
                };

                ll10 = teacher.Run(sequences);
            }

            Assert.IsTrue(ll10 > ll1);
            Assert.IsTrue(Math.Abs(ll1 - ll10) > 10);

            // Those results must match the ones in ViterbiLearningTest`1.
            Assert.AreEqual(-33.834836461044411, ll1);
            Assert.AreEqual(-23.362967205628703, ll10);

            Assert.IsFalse(AreEqual(hmm1, hmm10));
        }
        public void LearnTest2()
        {
            Accord.Math.Tools.SetupGenerator(0);
            double[][][] sequences = new double[500][][];
            for (int i = 0; i < sequences.Length; i++)
            {
                sequences[i] = new double[Accord.Math.Tools.Random.Next(20, 80)][];

                int start = Accord.Math.Tools.Random.Next();

                for (int j = 0; j < sequences[i].Length; j++)
                {
                    double s = Math.Sin(j + start);
                    double u = ((s + 1) / 2.0);
                    sequences[i][j] = new double[] { (int)(u * 10) };
                }
            }

            HiddenMarkovModel <GeneralDiscreteDistribution> hmm1;
            double ll1;

            {
                Accord.Math.Tools.SetupGenerator(0);
                hmm1 = HiddenMarkovModel.CreateGeneric(10, 10, true);
                var teacher = new ViterbiLearning <GeneralDiscreteDistribution>(hmm1)
                {
                    Iterations     = 1,
                    Tolerance      = 1e-15,
                    Batches        = 1,
                    UseLaplaceRule = true,
                    FittingOptions = new GeneralDiscreteOptions
                    {
                        UseLaplaceRule = true
                    }
                };
                ll1 = teacher.Run(sequences);
            }

            HiddenMarkovModel <GeneralDiscreteDistribution> hmm10;
            double ll10;

            {
                Accord.Math.Tools.SetupGenerator(0);
                hmm10 = HiddenMarkovModel.CreateGeneric(10, 10, true);

                var teacher = new ViterbiLearning <GeneralDiscreteDistribution>(hmm10)
                {
                    Iterations     = 100,
                    Tolerance      = 1e-15,
                    Batches        = 1,
                    UseLaplaceRule = true,
                    FittingOptions = new GeneralDiscreteOptions
                    {
                        UseLaplaceRule = true
                    }
                };

                ll10 = teacher.Run(sequences);
            }

            Assert.IsTrue(ll10 > ll1);
            Assert.AreNotEqual(ll1, ll10, 10);

            // Those results must match the ones in ViterbiLearningTest.
            Assert.AreEqual(-33.834836461044411, ll1);
            Assert.AreEqual(-23.362967205628703, ll10);

            Assert.IsFalse(AreEqual(hmm1, hmm10));
        }