Skip to content
Work Practice Products Coding interviews Machine learning coding Quant developer HFT course Blog Method Why me About Enquire Book a call

ML coding · Probabilistic models

The Viterbi algorithm for a hidden Markov model

Medium · Target 25 minutes · Python and NumPy

A hidden Markov model has S states with initial probabilities start (length S), transition matrix trans (S × S, row i gives the probabilities of moving from i) and emission matrix emit (S × V, row i gives the probabilities of each observation from state i). Given a sequence of observation indices obs, return [path, logp]: the most likely sequence of hidden states and the natural log of its joint probability with the observations.

All probabilities are positive, and the best path is unique in the tests.

Examples

Input start = [0.6, 0.4], trans = [[0.7, 0.3], [0.4, 0.6]], emit = [[0.5, 0.4, 0.1], [0.1, 0.3, 0.6]], obs = [0, 1, 2]

Output [[0, 0, 1], -4.1917]

The textbook weather example: the hidden states drift from the first to the second as the observations change.

Input start = [0.5, 0.5], trans = [[0.9, 0.1], [0.1, 0.9]], emit = [[0.9, 0.1], [0.2, 0.8]], obs = [0, 0, 1, 1, 1]

Output [[0, 0, 1, 1, 1], -4.192]

Sticky states: one switch, where the observations change.

Input start = [0.3, 0.7], trans = [[0.5, 0.5], [0.5, 0.5]], emit = [[0.8, 0.2], [0.3, 0.7]], obs = [0]

Output [[0], -1.4271]

One observation: the state with the largest start × emission.

Constraints

  • 1 ≤ S ≤ 50, 1 ≤ V ≤ 100, 1 ≤ len(obs) ≤ 10⁴
  • All probabilities positive
  • logp checked to a relative tolerance of 10⁻⁹

Hints

Hint 1

Keep score[j]: the best log-probability of any path ending in state j after the observations so far.

Hint 2

At each step, cand[i, j] = score[i] + log trans[i, j]. The new score[j] is the column maximum plus log emit[j, obs_t]; remember the argmax.

Hint 3

At the end, start from the best final state and follow the stored argmaxes backwards.

Where candidates go wrong

  • Multiplying probabilities: with a few hundred observations every path has probability zero in float64.
  • Taking the maximum over the wrong axis of cand, so that you choose where to go rather than where you came from.
  • Building the path forwards from the argmax at each step, which gives the most likely state at each time, not the most likely sequence.
  • An off-by-one between the back-pointer list and the observations.
Console⌘/Ctrl + Enter runs

Python runs in your browser with NumPy. The first run downloads the runtime, which takes a few seconds.


Why interviewers ask it

Viterbi is dynamic programming wearing a probabilistic hat, which makes it a favourite with interviewers who want one problem to test both. It appears in speech, genomics and regime-switching models in finance, and the log-space version is the only one that works on real sequence lengths.

The theory behind it is in the lesson Naive Bayes, EM, Viterbi and Markov chains from scratch.


Keep going