mirror of
https://github.com/hanzoai/jube-fork.git
synced 2026-10-30 18:33:33 +00:00
Included open-source Accord.net library code natively to the solution given the deprecated state of that project. Accord.net will be supported inside Jube for own needs (such as upgrading to .Net 7+). Accord.net libraries modified to compile to .Net 6. Modified Accord.net libraries to better support Newtonsoft Json.net serialisation. Included annotations in the Accord.net libraries to house important dependency statistics. Serialised json can be used independently of Jube to recall a Neural Network. Removal of Binary Serializer totally as a precursor to the projects support of .Net 7+. Extensive bug fixing in crucial functions of Neural Network training and recall. While this part of the system remains in Alpha, it is substantially more fit for purpose.
358 lines
15 KiB
C#
358 lines
15 KiB
C#
// Accord Statistics Library
|
|
// The Accord.NET Framework
|
|
// http://accord-framework.net
|
|
//
|
|
// Copyright © César Souza, 2009-2017
|
|
// cesarsouza at gmail.com
|
|
//
|
|
// This library is free software; you can redistribute it and/or
|
|
// modify it under the terms of the GNU Lesser General Public
|
|
// License as published by the Free Software Foundation; either
|
|
// version 2.1 of the License, or (at your option) any later version.
|
|
//
|
|
// This library is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
// Lesser General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU Lesser General Public
|
|
// License along with this library; if not, write to the Free Software
|
|
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
//
|
|
|
|
namespace Accord.Statistics.Models.Markov
|
|
{
|
|
using System;
|
|
using Accord.Math;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Runtime.Serialization.Formatters.Binary;
|
|
using Accord.Statistics.Distributions;
|
|
using Accord.Statistics.Distributions.Univariate;
|
|
using Accord.Statistics.Models.Markov.Learning;
|
|
using Accord.Statistics.Models.Markov.Topology;
|
|
using Accord.Compat;
|
|
|
|
/// <summary>
|
|
/// Discrete-density Hidden Markov Model Set for Sequence Classification.
|
|
/// </summary>
|
|
///
|
|
/// <remarks>
|
|
/// <para>
|
|
/// This class uses a set of <see cref="HiddenMarkovModel">discrete hidden Markov models</see>
|
|
/// to classify sequences of integer symbols. Each model will try to learn and recognize each
|
|
/// of the different output classes. For examples and details on how to learn such models,
|
|
/// please take a look on the documentation for <see cref="HiddenMarkovClassifierLearning"/>.</para>
|
|
/// <para>
|
|
/// For other type of sequences, such as discrete sequences (not necessarily symbols) or even
|
|
/// continuous and multivariate variables, please see use the generic classifier counterpart
|
|
/// <see cref="HiddenMarkovClassifier{TDistribution}"/></para>
|
|
/// </remarks>
|
|
///
|
|
/// <example>
|
|
/// <para>
|
|
/// Examples are available at the respective learning algorithm pages. For
|
|
/// example, see <see cref="HiddenMarkovClassifierLearning"/>. </para>
|
|
/// </example>
|
|
///
|
|
/// <seealso cref="HiddenMarkovClassifier{TDistribution}"/>
|
|
/// <seealso cref="HiddenMarkovClassifierLearning"/>
|
|
///
|
|
#pragma warning disable 612, 618
|
|
[Serializable]
|
|
public class HiddenMarkovClassifier : BaseHiddenMarkovClassifier<
|
|
HiddenMarkovModel, GeneralDiscreteDistribution, int>,
|
|
IEnumerable<HiddenMarkovModel>,
|
|
IHiddenMarkovClassifier
|
|
#pragma warning restore 612, 618
|
|
{
|
|
|
|
/// <summary>
|
|
/// Obsolete. Please use <see cref="NumberOfSymbols"/> instead.
|
|
/// </summary>
|
|
///
|
|
[Obsolete("Please use NumberOfSymbols instead.")]
|
|
public int Symbols
|
|
{
|
|
get { return NumberOfSymbols; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the number of symbols
|
|
/// recognizable by the models.
|
|
/// </summary>
|
|
///
|
|
public int NumberOfSymbols
|
|
{
|
|
get { return this[0].NumberOfSymbols; }
|
|
}
|
|
|
|
|
|
#region Constructors
|
|
|
|
/// <summary>
|
|
/// Creates a new Sequence Classifier with the given number of classes.
|
|
/// </summary>
|
|
///
|
|
/// <param name="classes">The number of classes in the classifier.</param>
|
|
///
|
|
public HiddenMarkovClassifier(int classes)
|
|
: base(classes)
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a new Sequence Classifier with the given number of classes.
|
|
/// </summary>
|
|
///
|
|
/// <param name="classes">The number of classes in the classifier.</param>
|
|
/// <param name="topology">The topology of the hidden states. A forward-only topology
|
|
/// is indicated to sequence classification problems, such as speech recognition.</param>
|
|
/// <param name="symbols">The number of symbols in the models' discrete alphabet.</param>
|
|
/// <param name="names">The optional class names for each of the classifiers.</param>
|
|
///
|
|
public HiddenMarkovClassifier(int classes, ITopology topology, int symbols, string[] names)
|
|
: base(classes)
|
|
{
|
|
for (int i = 0; i < classes; i++)
|
|
Models[i] = new HiddenMarkovModel(topology, symbols) { Tag = names[i] };
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a new Sequence Classifier with the given number of classes.
|
|
/// </summary>
|
|
///
|
|
/// <param name="classes">The number of classes in the classifier.</param>
|
|
/// <param name="topology">The topology of the hidden states. A forward-only topology
|
|
/// is indicated to sequence classification problems, such as speech recognition.</param>
|
|
/// <param name="symbols">The number of symbols in the models' discrete alphabet.</param>
|
|
///
|
|
public HiddenMarkovClassifier(int classes, ITopology topology, int symbols)
|
|
: base(classes)
|
|
{
|
|
for (int i = 0; i < classes; i++)
|
|
Models[i] = new HiddenMarkovModel(topology, symbols);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a new Sequence Classifier with the given number of classes.
|
|
/// </summary>
|
|
///
|
|
/// <param name="classes">The number of classes in the classifier.</param>
|
|
/// <param name="topology">The topology of the hidden states. A forward-only topology
|
|
/// is indicated to sequence classification problems, such as speech recognition.</param>
|
|
/// <param name="symbols">The number of symbols in the models' discrete alphabet.</param>
|
|
///
|
|
public HiddenMarkovClassifier(int classes, ITopology[] topology, int symbols)
|
|
: base(classes)
|
|
{
|
|
if (topology.Length != classes)
|
|
throw new ArgumentException("The number of topology specifications should equal the number of classes", "classes");
|
|
|
|
for (int i = 0; i < classes; i++)
|
|
Models[i] = new HiddenMarkovModel(topology[i], symbols);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a new Sequence Classifier with the given number of classes.
|
|
/// </summary>
|
|
///
|
|
/// <param name="classes">The number of classes in the classifier.</param>
|
|
/// <param name="topology">The topology of the hidden states. A forward-only topology
|
|
/// is indicated to sequence classification problems, such as speech recognition.</param>
|
|
/// <param name="symbols">The number of symbols in the models' discrete alphabet.</param>
|
|
/// <param name="names">The optional class names for each of the classifiers.</param>
|
|
///
|
|
public HiddenMarkovClassifier(int classes, ITopology[] topology, int symbols, string[] names)
|
|
: base(classes)
|
|
{
|
|
if (topology.Length != classes)
|
|
throw new ArgumentException("The number of topology specifications should equal the number of classes", "classes");
|
|
|
|
for (int i = 0; i < classes; i++)
|
|
Models[i] = new HiddenMarkovModel(topology[i], symbols) { Tag = names[i] };
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a new Sequence Classifier with the given number of classes.
|
|
/// </summary>
|
|
///
|
|
/// <param name="classes">The number of classes in the classifier.</param>
|
|
/// <param name="states">An array specifying the number of hidden states for each
|
|
/// of the classifiers. By default, and Ergodic topology will be used.</param>
|
|
/// <param name="symbols">The number of symbols in the models' discrete alphabet.</param>
|
|
/// <param name="names">The optional class names for each of the classifiers.</param>
|
|
///
|
|
public HiddenMarkovClassifier(int classes, int[] states, int symbols, string[] names)
|
|
: base(classes)
|
|
{
|
|
if (states.Length != classes)
|
|
throw new ArgumentException("The number of state specifications should equal the number of classes.", "classes");
|
|
|
|
for (int i = 0; i < classes; i++)
|
|
Models[i] = new HiddenMarkovModel(new Ergodic(states[i]), symbols) { Tag = names[i] };
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a new Sequence Classifier with the given number of classes.
|
|
/// </summary>
|
|
///
|
|
/// <param name="classes">The number of classes in the classifier.</param>
|
|
/// <param name="states">An array specifying the number of hidden states for each
|
|
/// of the classifiers. By default, and Ergodic topology will be used.</param>
|
|
/// <param name="symbols">The number of symbols in the models' discrete alphabet.</param>
|
|
///
|
|
public HiddenMarkovClassifier(int classes, int[] states, int symbols)
|
|
: base(classes)
|
|
{
|
|
if (states.Length != classes)
|
|
throw new ArgumentException("The number of state specifications should equal the number of classes.", "classes");
|
|
|
|
for (int i = 0; i < classes; i++)
|
|
Models[i] = new HiddenMarkovModel(new Ergodic(states[i]), symbols);
|
|
}
|
|
#endregion
|
|
|
|
|
|
/// <summary>
|
|
/// Computes the most likely class for a given sequence.
|
|
/// </summary>
|
|
///
|
|
/// <param name="sequence">The sequence of observations.</param>
|
|
///
|
|
/// <returns>Return the label of the given sequence, or -1 if it has
|
|
/// been rejected by the <see cref="BaseHiddenMarkovClassifier{T}.Threshold">
|
|
/// threshold model</see>.</returns>
|
|
///
|
|
[Obsolete("Please use Decide(input) instead.")]
|
|
public int Compute(int[] sequence)
|
|
{
|
|
return base.Decide(sequence);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Computes the most likely class for a given sequence.
|
|
/// </summary>
|
|
///
|
|
/// <param name="sequence">The sequence of observations.</param>
|
|
/// <param name="response">The class responsibilities (or
|
|
/// the probability of the sequence to belong to each class). When
|
|
/// using threshold models, the sum of the probabilities will not
|
|
/// equal one, and the amount left was the threshold probability.
|
|
/// If a threshold model is not being used, the array should sum to
|
|
/// one.</param>
|
|
///
|
|
/// <returns>Return the label of the given sequence, or -1 if it has
|
|
/// been rejected by the <see cref="BaseHiddenMarkovClassifier{T}.Threshold">
|
|
/// threshold model</see>.</returns>
|
|
///
|
|
[Obsolete("Please use Decide(input) or Probability(input) instead.")]
|
|
public int Compute(int[] sequence, out double response)
|
|
{
|
|
int decision;
|
|
response = base.Probability(sequence, out decision);
|
|
return decision;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Computes the most likely class for a given sequence.
|
|
/// </summary>
|
|
///
|
|
/// <param name="sequence">The sequence of observations.</param>
|
|
/// <param name="responsibilities">The class responsibilities (or
|
|
/// the probability of the sequence to belong to each class). When
|
|
/// using threshold models, the sum of the probabilities will not
|
|
/// equal one, and the amount left was the threshold probability.
|
|
/// If a threshold model is not being used, the array should sum to
|
|
/// one.</param>
|
|
///
|
|
/// <returns>Return the label of the given sequence, or -1 if it has
|
|
/// been rejected by the <see cref="BaseHiddenMarkovClassifier{T}.Threshold">
|
|
/// threshold model</see>.</returns>
|
|
///
|
|
[Obsolete("Please use Decide(input) instead.")]
|
|
public int Compute(int[] sequence, out double[] responsibilities)
|
|
{
|
|
int decision;
|
|
responsibilities = base.Probabilities(sequence, out decision);
|
|
return decision;
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// Computes the log-likelihood of a set of sequences
|
|
/// belonging to their given respective classes according
|
|
/// to this classifier.
|
|
/// </summary>
|
|
/// <param name="sequences">A set of sequences of observations.</param>
|
|
/// <param name="outputs">The output class label for each sequence.</param>
|
|
///
|
|
/// <returns>The log-likelihood of the sequences belonging to the given classes.</returns>
|
|
///
|
|
public new double LogLikelihood(int[][] sequences, int[] outputs)
|
|
{
|
|
// for backwards compatibility
|
|
return base.LogLikelihood(sequences, outputs).Sum();
|
|
}
|
|
|
|
|
|
#pragma warning disable 612, 618
|
|
|
|
/// <summary>
|
|
/// Creates a new Sequence Classifier with the given number of classes.
|
|
/// </summary>
|
|
///
|
|
/// <param name="classes">The number of classes in the classifier.</param>
|
|
/// <param name="states">An array specifying the number of hidden states for each
|
|
/// of the classifiers. By default, and Ergodic topology will be used.</param>
|
|
/// <param name="symbols">The number of symbols in the models' discrete alphabet.</param>
|
|
///
|
|
public static HiddenMarkovClassifier<GeneralDiscreteDistribution> CreateGeneric(
|
|
int classes, int[] states, int symbols)
|
|
{
|
|
var classifier = new HiddenMarkovClassifier<GeneralDiscreteDistribution>(
|
|
classes, states, new GeneralDiscreteDistribution(symbols));
|
|
|
|
return classifier;
|
|
}
|
|
|
|
#pragma warning restore 612, 618
|
|
|
|
|
|
/// <summary>
|
|
/// Creates a new Sequence Classifier with the given number of classes.
|
|
/// </summary>
|
|
///
|
|
/// <param name="classes">The number of classes in the classifier.</param>
|
|
/// <param name="states">An array specifying the number of hidden states for each
|
|
/// of the classifiers. By default, and Ergodic topology will be used.</param>
|
|
/// <param name="symbols">The number of symbols in the models' discrete alphabet.</param>
|
|
///
|
|
public static HiddenMarkovClassifier<GeneralDiscreteDistribution, int> CreateGeneric2(
|
|
int classes, int[] states, int symbols)
|
|
{
|
|
var classifier = new HiddenMarkovClassifier<GeneralDiscreteDistribution, int>(
|
|
classes, states, new GeneralDiscreteDistribution(symbols));
|
|
|
|
return classifier;
|
|
}
|
|
|
|
#region ISequenceClassifier implementation
|
|
|
|
#pragma warning disable 612, 618
|
|
/// <summary>
|
|
/// Computes the most likely class for a given sequence.
|
|
/// </summary>
|
|
///
|
|
int IHiddenMarkovClassifier.Compute(Array sequence, out double[] likelihoods)
|
|
{
|
|
int decision;
|
|
likelihoods = base.LogLikelihoods(sequence as int[], out decision);
|
|
return decision;
|
|
}
|
|
#pragma warning restore 612, 618
|
|
#endregion
|
|
}
|
|
}
|