public void LearnTest8()
{
// Create continuous sequences. In the sequence below, there
// seems to be two states, one for values equal to 1 and another
// for values equal to 2.
double[][] sequences = new double[][]
{
new double[] { 1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2 }
};
// Specify a initial normal distribution for the samples.
var density = new NormalDistribution();
// Creates a continuous hidden Markov Model with two states organized in a forward
// topology and an underlying univariate Normal distribution as probability density.
var model = new HiddenMarkovModel<NormalDistribution, double>(new Ergodic(2), density);
// Configure the learning algorithms to train the sequence classifier until the
// difference in the average log-likelihood changes only by as little as 0.0001
var teacher = new BaumWelchLearning<NormalDistribution, double>(model)
{
Tolerance = 0.0001,
Iterations = 0,
// However, we will need to specify a regularization constant as the
// variance of each state will likely be zero (all values are equal)
FittingOptions = new NormalOptions() { Regularization = double.Epsilon }
};
// Fit the model
teacher.Learn(sequences);
double likelihood = teacher.LogLikelihood;
// See the probability of the sequences learned
double a1 = model.Evaluate(new double[] { 1, 2, 1, 2, 1, 2, 1, 2, 1 }); // exp(a1) = infinity
double a2 = model.Evaluate(new double[] { 1, 2, 1, 2, 1 }); // exp(a2) = infinity
// See the probability of an unrelated sequence
double a3 = model.Evaluate(new double[] { 1, 2, 3, 2, 1, 2, 1 }); // exp(a3) = 0
double a4 = model.Evaluate(new double[] { 1.1, 2.2, 1.3, 3.2, 4.2, 1.0 }); // exp(a4) = 0
Assert.AreEqual(double.PositiveInfinity, System.Math.Exp(likelihood));
Assert.AreEqual(3341.7098768473734, a1);
Assert.AreEqual(1856.5054871374298, a2);
Assert.AreEqual(0.0, Math.Exp(a3));
Assert.AreEqual(0.0, Math.Exp(a4));
Assert.AreEqual(2, model.Emissions.Length);
var state1 = (model.Emissions[0] as NormalDistribution);
var state2 = (model.Emissions[1] as NormalDistribution);
Assert.AreEqual(1.0, state1.Mean, 1e-10);
Assert.AreEqual(2.0, state2.Mean, 1e-10);
Assert.IsFalse(Double.IsNaN(state1.Mean));
Assert.IsFalse(Double.IsNaN(state2.Mean));
Assert.IsTrue(state1.Variance < 1e-30);
Assert.IsTrue(state2.Variance < 1e-30);
var A = model.LogTransitions.Exp();
Assert.AreEqual(2, A.GetLength(0));
Assert.AreEqual(2, A.Columns());
Assert.AreEqual(0, A[0][0]);
Assert.AreEqual(1, A[0][1]);
Assert.AreEqual(1, A[1][0]);
Assert.AreEqual(0, A[1][1]);
}