/// <summary> /// Constructs a new potential function modeling Hidden Markov Models. /// </summary> /// /// <param name="states">The number of states.</param> /// <param name="symbols">The number of symbols.</param> /// <param name="outputClasses">The number of output classes.</param> /// public DiscreteMarkovClassifierFunction(int states, int symbols, int outputClasses) { this.Outputs = outputClasses; this.Symbols = symbols; int factorIndex = 0; var factorParams = new List <double>(); var factorFeatures = new List <IFeature <int> >(); this.Factors = new FactorPotential <int> [Outputs]; // Create features for initial class probabilities for (int c = 0; c < outputClasses; c++) { var stateParams = new List <double>(); var stateFeatures = new List <IFeature <int> >(); var edgeParams = new List <double>(); var edgeFeatures = new List <IFeature <int> >(); var classParams = new List <double>(); var classFeatures = new List <IFeature <int> >(); // Create features for class labels classParams.Add(Math.Log(1.0 / outputClasses)); classFeatures.Add(new OutputFeature <int>(this, c, c)); // Create features for initial state probabilities for (int i = 0; i < states; i++) { edgeParams.Add((i == 0) ? Math.Log(1.0) : Math.Log(0.0)); edgeFeatures.Add(new InitialFeature <int>(this, c, i)); } // Create features for state transition probabilities for (int i = 0; i < states; i++) { for (int j = 0; j < states; j++) { edgeParams.Add(Math.Log(1.0 / states)); edgeFeatures.Add(new TransitionFeature <int>(this, c, i, j)); } } // Create features for symbol emission probabilities for (int i = 0; i < states; i++) { for (int k = 0; k < symbols; k++) { stateParams.Add(Math.Log(1.0 / symbols)); stateFeatures.Add(new EmissionFeature(this, c, i, k)); } } int startClassIndex = factorIndex; int startEdgeIndex = factorIndex + classParams.Count; int startStateIndex = factorIndex + classParams.Count + edgeParams.Count; // First features and params are always belonging to classes Factors[c] = new DiscreteMarkovModelFactor(this, states, c, symbols, startClassIndex, classParams.Count, // 1. classes startEdgeIndex, edgeParams.Count, // 2. edges startStateIndex, stateParams.Count); // 3. states // 1. classes factorFeatures.AddRange(classFeatures); factorParams.AddRange(classParams); // 2. edges factorFeatures.AddRange(edgeFeatures); factorParams.AddRange(edgeParams); // 3. states factorFeatures.AddRange(stateFeatures); factorParams.AddRange(stateParams); factorIndex += classParams.Count + stateParams.Count + edgeParams.Count; } System.Diagnostics.Debug.Assert(factorIndex == factorParams.Count); System.Diagnostics.Debug.Assert(factorIndex == factorFeatures.Count); this.Weights = factorParams.ToArray(); this.Features = factorFeatures.ToArray(); }
/// <summary> /// Constructs a new potential function modeling Hidden Markov Models. /// </summary> /// /// <param name="classifier">The classifier model.</param> /// <param name="includeClassFeatures">True to include class features (priors), false otherwise.</param> /// public DiscreteMarkovClassifierFunction(HiddenMarkovClassifier classifier, bool includeClassFeatures = true) { this.Symbols = classifier.Symbols; this.Outputs = classifier.Classes; int factorIndex = 0; var factorParams = new List <double>(); var factorFeatures = new List <IFeature <int> >(); this.Factors = new FactorPotential <int> [Outputs]; // Create features for initial class probabilities for (int c = 0; c < classifier.Classes; c++) { var stateParams = new List <double>(); var stateFeatures = new List <IFeature <int> >(); var edgeParams = new List <double>(); var edgeFeatures = new List <IFeature <int> >(); var classParams = new List <double>(); var classFeatures = new List <IFeature <int> >(); var model = classifier[c]; if (includeClassFeatures) { // Create features for class labels classParams.Add(Math.Log(classifier.Priors[c])); classFeatures.Add(new OutputFeature <int>(this, c, c)); } // Create features for initial state probabilities for (int i = 0; i < model.States; i++) { edgeParams.Add(model.Probabilities[i]); edgeFeatures.Add(new InitialFeature <int>(this, c, 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 <int>(this, c, i, j)); } } // Create features for symbol emission probabilities for (int i = 0; i < model.States; i++) { for (int k = 0; k < model.Symbols; k++) { stateParams.Add(model.Emissions[i, k]); stateFeatures.Add(new EmissionFeature(this, c, i, k)); } } int startClassIndex = factorIndex; int startEdgeIndex = factorIndex + classParams.Count; int startStateIndex = factorIndex + classParams.Count + edgeParams.Count; // First features and params are always belonging to classes Factors[c] = new DiscreteMarkovModelFactor(this, model.States, c, Symbols, startClassIndex, classParams.Count, // 1. classes startEdgeIndex, edgeParams.Count, // 2. edges startStateIndex, stateParams.Count); // 3. states // 1. classes factorFeatures.AddRange(classFeatures); factorParams.AddRange(classParams); // 2. edges factorFeatures.AddRange(edgeFeatures); factorParams.AddRange(edgeParams); // 3. states factorFeatures.AddRange(stateFeatures); factorParams.AddRange(stateParams); factorIndex += classParams.Count + stateParams.Count + edgeParams.Count; } System.Diagnostics.Debug.Assert(factorIndex == factorParams.Count); System.Diagnostics.Debug.Assert(factorIndex == factorFeatures.Count); this.Weights = factorParams.ToArray(); this.Features = factorFeatures.ToArray(); }