How to map hidden states to their corresponding categories after decoding in hmmlearn (Hidden Markov Model)?
<p>I would like to predict hidden states using Hidden Markov Model (decoding problem). The data is categorical. The hidden states include Hungry, Rest, Exercise and Movie. The observation set include Food, Home, Outdoor &amp; Recreation and Arts &amp; Entertainment. My program is first to train the HMM based on the observation sequence (Baum-Welch algorithm). And then I do the decoding (Viterbi algorithm) to predict the hidden state sequence.</p>

<p>My question is that how I can map the result (non-negative integers) to their corresponding categories like Hungry or Rest. Because of the non-deterministic property of the training algorithm , the parameters are different for every training of the same data. Therefore the hidden state sequence is different every time if I do the map like the following code. </p>

<p>The code is as follows:</p>

<pre><code>from __future__ import division
import numpy as np
from hmmlearn import hmm

states = ["Hungry", "Rest", "Exercise", "Movie"]
n_states = len(states)

observations = ["Food", "Home", "Outdoor &amp; Recreation", "Arts &amp; Entertainment"]

# The number in this sequence is the index of observation
category_sequence = [1, 0, 1, 2, 1, 3, 1]
Location = np.array([category_sequence]).T
model = hmm.MultinomialHMM(n_components=n_states).fit(Location)

logprob, result = model.decode(Location)
print "Category:", ", ".join(map(lambda x: observations[x], Location.T[0]))
print "Intent:", ", ".join(map(lambda x: states[x], result))
</code></pre>

<p>This is known as label-switching problem. The log-likelihood of the model sums over all of the states and is therefore independent of the particular ordering.</p>

<p>As far as I know, there is no general recipe for dealing with it. Among the things you might try are:</p>

<ul>
<li>Find a partially labelled dataset, run <code>predict</code> on it and use the predictions to map the state indices to the corresponding labels. </li>
<li>Come up with heuristics for possible parameter values in each state. This could be tricky to do for Multinomials, but is possible if you model e.g. accelerometer data.</li>
</ul>

<hr>

<p><strong>Update</strong>: An ad-hoc version of guessing state to label mapping from labelled data.</p>

<pre><code>def guess_labels(hmm, X, labels):
    result = [None] * hmm.n_components
    for label, y_t in zip(labels, hmm.predict(X)):
        assigned = result[y_t]
        if assigned is not None:
            # XXX clearly for any real data there might be
            #     (and there will be) conflicts. Here we just blindly
            #     hope the ``assert`` never fires.
            assert assigned == label
        else:
            result[y_t] = label
    return result
</code></pre>

python hidden-markov-models hmmlearn