Example #1
0
        internal static void Run()
        {
            // http://ocw.mit.edu/courses/aeronautics-and-astronautics/16-410-principles-of-autonomy-and-decision-making-fall-2010/lecture-notes/MIT16_410F10_lec21.pdf

            var states = new Registry <IState>();
            var x1     = states.Add(new NamedState("x1"));
            var x2     = states.Add(new NamedState("x2"));
            var x3     = states.Add(new NamedState("x3"));

            var observations = new Registry <IObservation>();
            var o2           = observations.Add(new NamedObservation("o2"));
            var o3           = observations.Add(new NamedObservation("o3"));

            // test the HMM with a known graph
            {
                var initial = new InitialStateMatrix(states);
                initial.SetProbability(x1, 1);
                initial.SetProbability(x2, 0);
                initial.SetProbability(x3, 0);

                var transitions = new TransitionMatrix(states);
                transitions.SetTransition(x1, x1, 0);
                transitions.SetTransition(x1, x2, 0.5);
                transitions.SetTransition(x1, x3, 0.5);
                transitions.SetTransition(x2, x1, 0);
                transitions.SetTransition(x2, x2, 0.9);
                transitions.SetTransition(x2, x3, 0.1);
                transitions.SetTransition(x3, x1, 0);
                transitions.SetTransition(x3, x2, 0);
                transitions.SetTransition(x3, x3, 1);

                var emissions = new EmissionMatrix(states, observations);
                emissions.SetEmission(x1, o2, 0.5);
                emissions.SetEmission(x2, o2, 0.9);
                emissions.SetEmission(x3, o2, 0.1);

                emissions.SetEmission(x1, o3, 0.5);
                emissions.SetEmission(x2, o3, 0.1);
                emissions.SetEmission(x3, o3, 0.9);

                var hmm = new HiddenMarkovModel(states, initial, transitions, emissions);

                // expected output: 1, 3, 3, 3, 3, 3, 3, 3, 3
                hmm.ApplyViterbiAndPrint(new[] { o2, o3, o3, o2, o2, o2, o3, o2, o3 });

                // expected output: 1, 2, 2, 2, 2, 2, 2, 2
                hmm.ApplyViterbiAndPrint(new[] { o2, o3, o3, o2, o2, o2, o3, o2 });
            }
        }
Example #2
0
        private void ValidateParameters()
        {
            if (EmissionMatrix == null || TransitionMatrix == null || SequenceOfObservations == null ||
                StateSpace == null || ObservationSpace == null)
            {
                throw new ArgumentException("Parameters cannot be null");
            }

            if (ObservationSpace.Length != EmissionMatrix.GetLength(1) || ObservationSpace.Length == 0)
            {
                throw new ArgumentException("N should be greater than 0 and consistent");
            }

#if _USE_ARRAYS_INSTEAD_OF_MATRIX_HASHTABLE
            if (StateSpace.Length != TransitionMatrix.GetLength(0) || TransitionMatrix.GetLength(0) != TransitionMatrix.GetLength(1) || TransitionMatrix.GetLength(1) != EmissionMatrix.GetLength(0) || EmissionMatrix.GetLength(0) != InitialProbabilitiesOfStates.Length || StateSpace.Length == 0)
            {
                throw new ArgumentException("K should be greater than 0 and consistent");
            }
#else
            if (StateSpace.Length != TransitionMatrix.GetLength(0) ||
                TransitionMatrix.GetLength(0) != TransitionMatrix.GetLength(1) ||
                TransitionMatrix.GetLength(1) != EmissionMatrix.GetLength(0) ||
                EmissionMatrix.GetLength(0) != InitialProbabilitiesOfStates.Count || StateSpace.Length == 0)
            {
                throw new ArgumentException("K should be greater than 0 and consistent");
            }
#endif
            if (SequenceOfObservations.Length == 0)
            {
                throw new ArgumentException("T should be greater than 0 and consistent");
            }

            if (
                StateSpace.Select(state => ObservationSpace.Sum(observation => EmissionMatrix[state, observation]))
                .Any(sum => sum <= 0.99 || sum >= 1.01))
            {
                throw new ArgumentException("EmissionMatrix has not normalized probabilities"); //Exception("Emi");
            }

            if (
                StateSpace.Select(state1 => StateSpace.Sum(state2 => TransitionMatrix[state1, state2]))
                .Any(sum => sum <= 0.99 || sum >= 1.01))
            {
                throw new ArgumentException("TransitionMatrix has not normalized probabilities"); //Exception("Emi");
            }
        }
Example #3
0
        internal static void Run()
        {
            // http://www.cs.sfu.ca/~anoop/teaching/CMPT-413-Spring-2014/index.html

            const double compareEpsilon = 0.000001D;

            var states    = new Registry <IState>();
            var adjective = states.Add(new NamedState("A"));
            var noun      = states.Add(new NamedState("N"));

            var observations = new Registry <IObservation>();
            var clown        = observations.Add(new NamedObservation("clown"));
            var killer       = observations.Add(new NamedObservation("killer"));
            var crazy        = observations.Add(new NamedObservation("crazy"));
            var problem      = observations.Add(new NamedObservation("problem"));

            // test the HMM with a known graph
            {
                var initial = new InitialStateMatrix(states);
                initial.SetProbability(adjective, 1 / 3D);
                initial.SetProbability(noun, 2 / 3D);

                var transitions = new TransitionMatrix(states);
                transitions.SetTransition(adjective, adjective, 0);
                transitions.SetTransition(adjective, noun, 1);
                transitions.SetTransition(noun, adjective, 0.5);
                transitions.SetTransition(noun, noun, 0.5);

                var emissions = new EmissionMatrix(states, observations);
                emissions.SetEmission(adjective, clown, 0);
                emissions.SetEmission(adjective, killer, 0);
                emissions.SetEmission(adjective, problem, 0);
                emissions.SetEmission(adjective, crazy, 1);
                emissions.SetEmission(noun, clown, 0.4);
                emissions.SetEmission(noun, killer, 0.3);
                emissions.SetEmission(noun, problem, 0.3);
                emissions.SetEmission(noun, crazy, 0);

                var hmm = new HiddenMarkovModel(states, initial, transitions, emissions);

                // P(AA | killer clown)
                var paa = hmm.GetProbability(killer.As(adjective), clown.As(adjective));
                Debug.Assert(Math.Abs(paa) < compareEpsilon);

                // P(AN | killer clown)
                var pan = hmm.GetProbability(killer.As(adjective), clown.As(noun));
                Debug.Assert(Math.Abs(pan) < compareEpsilon);

                // P(NN | killer clown)
                var pnn = hmm.GetProbability(killer.As(noun), clown.As(noun));
                Debug.Assert(Math.Abs(0.04 - pnn) < compareEpsilon);

                // P(NA | killer clown)
                var pna = hmm.GetProbability(killer.As(noun), clown.As(adjective));
                Debug.Assert(Math.Abs(pna) < compareEpsilon);
            }

            // test supervised learning of the HMM
            {
                var trainingSet = new List <IList <LabeledObservation> >
                {
                    new[] { killer.As(noun), clown.As(noun) },
                    new[] { killer.As(noun), problem.As(noun) },
                    new[] { crazy.As(adjective), problem.As(noun) },
                    new[] { crazy.As(adjective), clown.As(noun) },
                    new[] { problem.As(noun), crazy.As(adjective), clown.As(noun) },
                    new[] { clown.As(noun), crazy.As(adjective), killer.As(noun) },
                };

                // prepare the matrices
                var initial     = new InitialStateMatrix(states);
                var transitions = new TransitionMatrix(states);
                var emissions   = new EmissionMatrix(states, observations);

                // learn the probabilities
                var learner = new ClassicalBaumWelchLearning();
                learner.Learn(initial, transitions, emissions, trainingSet);

                var hmm = new HiddenMarkovModel(states, initial, transitions, emissions);

                // P(AA | killer clown)
                var paa = hmm.GetProbability(killer.As(adjective), clown.As(adjective));
                Debug.Assert(Math.Abs(paa) < compareEpsilon);

                // P(AN | killer clown)
                var pan = hmm.GetProbability(killer.As(adjective), clown.As(noun));
                Debug.Assert(Math.Abs(pan) < compareEpsilon);

                // P(NN | killer clown)
                var pnn = hmm.GetProbability(killer.As(noun), clown.As(noun));
                Debug.Assert(Math.Abs(0.04 - pnn) < compareEpsilon);

                // P(NA | killer clown)
                var pna = hmm.GetProbability(killer.As(noun), clown.As(adjective));
                Debug.Assert(Math.Abs(pna) < compareEpsilon);

                // apply the viterbi algorithm to find the most likely sequence
                hmm.ApplyViterbiAndPrint(new[] { killer, crazy, clown, problem });
                hmm.ApplyViterbiAndPrint(new[] { crazy, killer, clown, problem });
                hmm.ApplyViterbiAndPrint(new[] { crazy, clown, killer, crazy, problem });

                var p = hmm.Evaluate(new[] { killer, crazy, clown, problem });
            }
        }