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; }
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); } } }
/* * 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; } }
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) { }
/// <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; }
/// <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); } } }
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> /// 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(); }
/// <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)); } }
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); }
/* * 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; } }
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; }
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; }
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; } }
/// <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); }
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)); }
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); }
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++; }
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);
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; }
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); }
public ParticleSet(HiddenMarkovModel hmm) { particles = new List<Particle>(); this.hmm = hmm; }
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); }
/// <summary> /// Creates a new instance of the Baum-Welch learning algorithm. /// </summary> /// public BaumWelchLearning(HiddenMarkovModel <TDistribution> model) : base(model) { this.model = model; }
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)); }