title: Hidden Markov Model, Clarification on a Previous Implementation
body: <p>I'm experimenting with hidden markov models. I really have no prior experience working with them so I decided to check out a few examples of implementations.</p>
  
  <p>Looking at the below implementation, I was a bit confused about the purpose of the Baum-Welch algorithm (found under the train method) taking a variable steps. I understand providing a training set, but not providing steps. Does anyone have an explanation for this, since I don't understand it from the documentation.</p>
  
  <p>Here's a link to the original code <a href="http://cs.nyu.edu/courses/spring04/G22.2591-001/BW%20demo/HMM.java" rel="nofollow">http://cs.nyu.edu/courses/spring04/G22.2591-001/BW%20demo/HMM.java</a> since the code isn't being presented very nicely in my post.</p>
  
  <pre><code>import java.text.*;
  
  /** This class implements a Hidden Markov Model, as well as
  the Baum-Welch Algorithm for training HMMs.
  @author Holger Wunsch (wunsch@sfs.nphil.uni-tuebingen.de) 
  */
  public class HMM {
    /** number of states */
    public int numStates;
  
    /** size of output vocabulary */
    public int sigmaSize;
  
    /** initial state probabilities */
    public double pi[];
  
    /** transition probabilities */
    public double a[][];
  
    /** emission probabilities */
    public double b[][];
  
    /** initializes an HMM.
    @param numStates number of states
    @param sigmaSize size of output vocabulary 
    */
  
   public HMM(int numStates, int sigmaSize) {
     this.numStates = numStates;
     this.sigmaSize = sigmaSize;
  
     pi = new double[numStates];
     a = new double[numStates][numStates];
     b = new double[numStates][sigmaSize];
   }
  
   /** implementation of the Baum-Welch Algorithm for HMMs.
    @param o the training set
    @param steps the number of steps
   */
    public void train(int[] o, int steps) {
       int T = o.length;
       double[][] fwd;
       double[][] bwd;
  
       double pi1[] = new double[numStates];
       double a1[][] = new double[numStates][numStates];
       double b1[][] = new double[numStates][sigmaSize];
  
       for (int s = 0; s &lt; steps; s++) {
        /* calculation of Forward- und Backward Variables from the
   current model */
        fwd = forwardProc(o);
        bwd = backwardProc(o);
  
        /* re-estimation of initial state probabilities */
        for (int i = 0; i &lt; numStates; i++)
      pi1[i] = gamma(i, 0, o, fwd, bwd);
  
        /* re-estimation of transition probabilities */ 
        for (int i = 0; i &lt; numStates; i++) {
      for (int j = 0; j &lt; numStates; j++) {
       double num = 0;
       double denom = 0;
       for (int t = 0; t &lt;= T - 1; t++) {
         num += p(t, i, j, o, fwd, bwd);
         denom += gamma(i, t, o, fwd, bwd);
       }
     a1[i][j] = divide(num, denom);
    }
      }
  
    /* re-estimation of emission probabilities */
    for (int i = 0; i &lt; numStates; i++) {
  for (int k = 0; k &lt; sigmaSize; k++) {
    double num = 0;
    double denom = 0;
  
    for (int t = 0; t &lt;= T - 1; t++) {
      double g = gamma(i, t, o, fwd, bwd);
      num += g * (k == o[t] ? 1 : 0);
      denom += g;
    }
    b1[i][k] = divide(num, denom);
  }
    }
    pi = pi1;
    a = a1;
    b = b1;
  }
  }
  
  
    /** calculation of Forward-Variables f(i,t) for state i at time
    t for output sequence O with the current HMM parameters
    @param o the output sequence O
    @return an array f(i,t) over states and times, containing
            the Forward-variables. 
    */
  
    public double[][] forwardProc(int[] o) {
  int T = o.length;
  double[][] fwd = new double[numStates][T];
  
  /* initialization (time 0) */
  for (int i = 0; i &lt; numStates; i++)
    fwd[i][0] = pi[i] * b[i][o[0]];
  
  /* induction */
  for (int t = 0; t &lt;= T-2; t++) {
    for (int j = 0; j &lt; numStates; j++) {
  fwd[j][t+1] = 0;
  for (int i = 0; i &lt; numStates; i++)
    fwd[j][t+1] += (fwd[i][t] * a[i][j]);
  fwd[j][t+1] *= b[j][o[t+1]];
    }
  }
  
  return fwd;
  }
  </code></pre>
  
  <p>The other two questions I have are in regards to the Forward method, which implements the Forward part of the Forward-Backward algorithm. From reading up on HMMs, I gather that, after training my model, I should use something like this method to predict future observations. So is the param O (representing output sequences) just the sequence of observations up until this point?</p>
  
  <p>With some experimentation with this method, I'm returned what the documentation says are Forward-Variables, which just look like a bunch of probabilities. How are these translated into future observations?</p>
  
  <p>I'm delving into regions of programming that are quite difficult for me, so I really appreciate your help in helping me understand this stuff!</p>