HmmTrainer { public static HmmModel trainViterbi(HmmModel initialModel, int[] observedSequence, double pseudoCount, double epsilon, int maxIterations, boolean scaled) { pseudoCount = pseudoCount == 0 ? Double.MIN_VALUE : pseudoCount; HmmModel lastIteration = initialModel.clone(); HmmModel iteration = initialModel.clone(); int[] viterbiPath = new int[observedSequence.length]; int[][] phi = new int[observedSequence.length - 1][initialModel .getNrOfHiddenStates()]; double[][] delta = new double[observedSequence.length][initialModel .getNrOfHiddenStates()]; for (int i = 0; i < maxIterations; ++i) { HmmAlgorithms.viterbiAlgorithm(viterbiPath, delta, phi, lastIteration, observedSequence, scaled); Matrix emissionMatrix = iteration.getEmissionMatrix(); Matrix transitionMatrix = iteration.getTransitionMatrix(); emissionMatrix.assign(pseudoCount); transitionMatrix.assign(pseudoCount); countTransitions(transitionMatrix, emissionMatrix, observedSequence, viterbiPath); for (int j = 0; j < iteration.getNrOfHiddenStates(); ++j) { double sum = 0; for (int k = 0; k < iteration.getNrOfHiddenStates(); ++k) { sum += transitionMatrix.getQuick(j, k); } for (int k = 0; k < iteration.getNrOfHiddenStates(); ++k) { transitionMatrix .setQuick(j, k, transitionMatrix.getQuick(j, k) / sum); } sum = 0; for (int k = 0; k < iteration.getNrOfOutputStates(); ++k) { sum += emissionMatrix.getQuick(j, k); } for (int k = 0; k < iteration.getNrOfOutputStates(); ++k) { emissionMatrix.setQuick(j, k, emissionMatrix.getQuick(j, k) / sum); } } if (checkConvergence(lastIteration, iteration, epsilon)) { break; } lastIteration.assign(iteration); } return iteration; } private  HmmTrainer(); static HmmModel trainSupervised(int nrOfHiddenStates, int nrOfOutputStates, int[] observedSequence,
      int[] hiddenSequence, double pseudoCount); static HmmModel trainSupervisedSequence(int nrOfHiddenStates,
                                                 int nrOfOutputStates, Collection<int[]> hiddenSequences,
                                                 Collection<int[]> observedSequences, double pseudoCount); static HmmModel trainViterbi(HmmModel initialModel,
                                      int[] observedSequence, double pseudoCount, double epsilon,
                                      int maxIterations, boolean scaled); static HmmModel trainBaumWelch(HmmModel initialModel,
                                        int[] observedSequence, double epsilon, int maxIterations, boolean scaled);  }
@Test public void testViterbiTraining() { double[][] transitionE = {{0.3125, 0.0625, 0.3125, 0.3125}, {0.25, 0.25, 0.25, 0.25}, {0.5, 0.071429, 0.357143, 0.071429}, {0.5, 0.1, 0.1, 0.3}}; double[][] emissionE = {{0.882353, 0.058824, 0.058824}, {0.333333, 0.333333, 0.3333333}, {0.076923, 0.846154, 0.076923}, {0.111111, 0.111111, 0.777778}}; int[] observed = {1, 0, 2, 2, 0, 0, 1, 1, 1, 0, 2, 0, 1, 0, 0}; HmmModel trained = HmmTrainer.trainViterbi(getModel(), observed, 0.5, 0.1, 10, false); Matrix emissionMatrix = trained.getEmissionMatrix(); Matrix transitionMatrix = trained.getTransitionMatrix(); for (int i = 0; i < trained.getNrOfHiddenStates(); ++i) { for (int j = 0; j < trained.getNrOfHiddenStates(); ++j) { assertEquals(transitionMatrix.getQuick(i, j), transitionE[i][j], EPSILON); } for (int j = 0; j < trained.getNrOfOutputStates(); ++j) { assertEquals(emissionMatrix.getQuick(i, j), emissionE[i][j], EPSILON); } } }
@Test public void testScaledViterbiTraining() { double[][] transitionE = {{0.3125, 0.0625, 0.3125, 0.3125}, {0.25, 0.25, 0.25, 0.25}, {0.5, 0.071429, 0.357143, 0.071429}, {0.5, 0.1, 0.1, 0.3}}; double[][] emissionE = {{0.882353, 0.058824, 0.058824}, {0.333333, 0.333333, 0.3333333}, {0.076923, 0.846154, 0.076923}, {0.111111, 0.111111, 0.777778}}; int[] observed = {1, 0, 2, 2, 0, 0, 1, 1, 1, 0, 2, 0, 1, 0, 0}; HmmModel trained = HmmTrainer.trainViterbi(getModel(), observed, 0.5, 0.1, 10, true); Matrix emissionMatrix = trained.getEmissionMatrix(); Matrix transitionMatrix = trained.getTransitionMatrix(); for (int i = 0; i < trained.getNrOfHiddenStates(); ++i) { for (int j = 0; j < trained.getNrOfHiddenStates(); ++j) { assertEquals(transitionMatrix.getQuick(i, j), transitionE[i][j], EPSILON); } for (int j = 0; j < trained.getNrOfOutputStates(); ++j) { assertEquals(emissionMatrix.getQuick(i, j), emissionE[i][j], EPSILON); } } }