public void LearnTest7()
{
// Create a Continuous density Hidden Markov Model Sequence Classifier
// to detect a multivariate sequence and the same sequence backwards.
double[][][] sequences = new double[][][]
{
new double[][]
{
// This is the first sequence with label = 0
new double[] { 0, 1 },
new double[] { 1, 2 },
new double[] { 2, 3 },
new double[] { 3, 4 },
new double[] { 4, 5 },
},
new double[][]
{
// This is the second sequence with label = 1
new double[] { 4, 3 },
new double[] { 3, 2 },
new double[] { 2, 1 },
new double[] { 1, 0 },
new double[] { 0, -1 },
}
};
// Labels for the sequences
int[] labels = { 0, 1 };
var initialDensity = new MultivariateNormalDistribution(2);
// Creates a sequence classifier containing 2 hidden Markov Models with 2 states
// and an underlying multivariate mixture of Normal distributions as density.
var classifier = new HiddenMarkovClassifier<MultivariateNormalDistribution, double[]>(
classes: 2, topology: new Forward(2), initial: initialDensity);
// Configure the learning algorithms to train the sequence classifier
var teacher = new HiddenMarkovClassifierLearning<MultivariateNormalDistribution, double[]>(classifier)
{
// Train each model until the log-likelihood changes less than 0.0001
Learner = modelIndex => new BaumWelchLearning<MultivariateNormalDistribution, double[], NormalOptions>(classifier.Models[modelIndex])
{
Tolerance = 0.0001,
Iterations = 0,
FittingOptions = new NormalOptions()
{
Diagonal = true, // only diagonal covariance matrices
Regularization = 1e-5 // avoid non-positive definite errors
}
}
};
// Train the sequence classifier using the algorithm
teacher.Learn(sequences, labels);
double logLikelihood = teacher.LogLikelihood;
// Calculate the probability that the given
// sequences originated from the model
double likelihood, likelihood2;
int c1 = classifier.Decide(sequences[0]);
likelihood = classifier.Probability(sequences[0]);
// Try to classify the second sequence (output should be 1)
int c2 = classifier.Decide(sequences[1]);
likelihood2 = classifier.Probability(sequences[1]);
Assert.AreEqual(0, c1);
Assert.AreEqual(1, c2);
Assert.AreEqual(-24.560663315259973, logLikelihood, 1e-10);
Assert.AreEqual(0.99999999998805045, likelihood, 1e-10);
Assert.AreEqual(0.99999999998805045, likelihood2, 1e-10);
Assert.IsFalse(double.IsNaN(logLikelihood));
Assert.IsFalse(double.IsNaN(likelihood));
Assert.IsFalse(double.IsNaN(likelihood2));
}