Reputation: 617
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 & Recreation and Arts & 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.
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.
The code is as follows:
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 & Recreation", "Arts & 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))
Upvotes: 5
Views: 2652
Reputation: 2679
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.
As far as I know, there is no general recipe for dealing with it. Among the things you might try are:
predict
on it and use the predictions to map the state indices to the corresponding labels. Update: An ad-hoc version of guessing state to label mapping from labelled data.
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
Upvotes: 5