Hidden Markov Models, drawn out

You see the ice creams someone ate; you want the weather. A hidden Markov model (HMM) is the smallest honest model of that situation: a chain of hidden states that you cannot see, each of which emits something you can. This poster walks the whole story from the Markov chain to training, using one tiny example so that every number can be checked by hand.

Everything on the poster is computed by the same code that powers the calculator below it, not copied from a figure. The example and the three-problem framing follow Appendix A of Jurafsky & Martin; the commentary and the practice notes are mine.

trishchuk.com / learn
Infographic

Hidden Markov Models

Recover a hidden sequence (weather, part-of-speech tags, phonemes) from what you can actually observe. One model, three problems, three dynamic-programming algorithms.

HCHHHCCHHHHOTCOLD
Ice creams eaten each day (the scoops) and the weather Viterbi infers from them (the lit path). Amber is hot, blue is cold.

Markov assumption

P(qi | q1 … qi−1) = P(qi | qi−1)

The next state depends only on the current one, not on the history.

Output independence

P(oi | q1 … qT, o1 … oT) = P(oi | qi)

An observation depends only on the hidden state that emitted it.

Markov chain: states you can see

Weather chain, Fig. A.1a of the book

.1.3.1.1.3.1.8.6.6 COLDHOTWARM

Transition matrix A

from ↓ / to →HOTCOLDWARM
HOT.6.1.3
COLD.1.8.1
WARM.3.1.6

Every row sums to 1. Start distribution: π = [.1, .7, .2].

Same chain, two sequences

  • hot hot hot hot .0216
  • cold hot cold hot .0007

hot-hot-hot-hot is about 31× more likely than cold-hot-cold-hot: weather is sticky, and the heavy diagonal of A encodes exactly that.

Where does it settle? πA = π

  • after 0 steps 10 70 20
  • after 1 steps 19 59 22
  • after 2 steps 24 51 25
  • after 3 steps 27 46 27
  • after 5 steps 30 39 30
  • after 10 steps 33 34 33

Start from π and apply A again and again. A is symmetric, so its columns also sum to 1 and the uniform distribution is stationary: in the long run every state gets ⅓. A stationary distribution satisfies πA = π.

Hidden Markov model: add a layer you can’t see

The Eisner ice-cream task, Fig. A.2

.5.4 .5.6 π .2π .8 CCOLDHHOT P(o | C).51.42.13 P(o | H).21.42.43

Hidden: whether a day was cold (C) or hot (H). Observed: how many ice creams (1, 2 or 3) Jason ate. Given the diary, infer the weather.

Transitions A

CH
C.5.5
H.4.6

Emissions B

123
C.5.4.1
H.2.4.4

Start π

CH
π.2.8
Q
N hidden states (here C, H)
A
transition matrix, rows sum to 1
B
emission probabilities, P(o | state)
π
initial state distribution
O
T observations, one per step

One model, three problems

Problem 1
Σ

Likelihood

How probable is this diary under the model?

P(O | λ)
Forward algorithm
O(N²T), one pass
Problem 2
max

Decoding

Which weather sequence best explains it?

best Q
Viterbi algorithm
O(N²T) time, O(NT) memory
Problem 3
E → M

Learning

Which A and B make the diary most likely?

A, B
Forward-Backward (Baum–Welch)
O(N²T) per iteration

Forward: sum over all paths without listing them

Observations 3 1 3 (Jason ate 3, then 1, then 3 ice creams)

α₁(H) .32 α₁(C) .02 α₂(H) .0404 α₂(C) .069 α₃(H) .0235 α₃(C) .005066 o₁ = 3 o₂ = 1 o₃ = 3
αt(j) = NΣi=1 αt−1(i) · aij · bj(ot)

Each cell αₜ(j) is the probability of seeing the first t observations and being in state j. It is built from the previous column: multiply by a transition, add the incoming paths, multiply by the emission.

Start: α1(j) = πj · bj(o1)   End: P(O | λ) = Σ αT(i)

Forward values αt(j)
t=1 o=3t=2 o=1t=3 o=3
H.32.0404.0235
C.02.069.005066
Total likelihood P(O | λ) = .028562 Matches the brute-force sum below.

Why not just enumerate?

All 2³ = 8 hidden paths for 3 1 3, with joint probability P(O, Q)

  1. HCH .0128
  2. HHH .009216
  3. HCC .0032
  4. HHC .001536
  5. CCH .001
  6. CHH .00048
  7. CCC .00025
  8. CHC .00008
Their sum is the likelihood Σ = .028562
1020 paths to enumerate NT
2 000 forward steps N²·T

N = 10 states, T = 20 steps

Here N = 2, T = 3: 8 paths vs 12 steps. The gap is invisible at this size and astronomical at real sizes.

Viterbi: same trellis, max instead of sum

Keep only the best way into each cell, and remember where it came from

v₁(H) .32 v₁(C) .02 v₂(H) .0384 v₂(C) .064 v₃(H) .0128 v₃(C) .0032 o₁ = 3 o₂ = 1 o₃ = 3
vt(j) = maxi vt−1(i) · aij · bj(ot)
btt(j) = argmaxi vt−1(i) · aij · bj(ot)

Replace the sum by a max and store a backpointer for every cell. At the end, pick the best last cell and follow the pointers back.

Viterbi values vt(j)
t=1 o=3t=2 o=1t=3 o=3
H.32.0384←H.0128←C
C.02.064←H.0032←C
Best path HCH p = .0128 Runner-up: H H H = .009216

Intuition says “3 ice creams ⇒ hot, so H H H”. But on day 2 Jason ate just one, which is far likelier on a cold day (.5 vs .2), and the chain is not sticky enough to outweigh that. The best path dips to cold: H C H.

Learning: Forward-Backward (Baum–Welch)

No labels? Guess A and B, soft-count what the guess implies, re-estimate, repeat

Backward probability: what happens after t

βt(i) = NΣj=1 aij · bj(ot+1) · βt+1(j)

γ: how likely was state j on day t?

γt(j) = αt(j) βt(j) / P(O | λ)

ξ: how likely was the move i → j at t?

ξt(i, j) = αt(i) aij bj(ot+1) βt+1(j) / P(O | λ)

M-step: re-estimate

âij = Σt ξt(i, j) / ΣtΣk ξt(i, k)
b̂j(vk) = Σt: ot=vk γt(j) / Σt γt(j)
  1. E-step compute γ and ξ from the current A, B (needs α and β)
  2. M-step recompute A and B from the expected counts
  3. ↻ repeat until the likelihood stops improving
Posterior state probabilities for 3 1 3 γt(j)
t=1 o=3t=2 o=1t=3 o=3
H.937.396.823
C.0634.604.177

Example: ξ₁(H→C) = .5602  ·  β3 = [1, 1], β2 = [.25, .28]

With labelled data none of this is needed: count transitions and emissions and divide (maximum likelihood), exactly as for a Markov chain.

Key properties

  • First-order: one step of memory. Longer memory means a bigger state space.
  • Generative: it models P(O, Q). Discriminative cousins (CRFs) model P(Q | O) directly.
  • Geometric durations: staying d steps in state i has probability aᵢᵢ^(d−1) · (1 − aᵢᵢ).
  • Viterbi ≠ posterior: the best joint path is not the same as picking argmax γ at each step.

Applications

  • Part-of-speech tagging: tags are hidden, words are observed.
  • Speech recognition: sub-phone states, acoustic frames as observations.
  • Bioinformatics: gene finding, profile HMMs; the cousin of sequence alignment.
  • Communications: Viterbi (1967) decoded convolutional codes first.
  • Also: GPS map matching, activity recognition, regime switching in finance.

In practice

  • Underflow: products of many probabilities vanish. Use log probabilities for Viterbi; use log-sum-exp or per-step scaling for Forward.
  • Local optima: EM never decreases the likelihood but can stall. Initialise sensibly, restart randomly, zero out impossible transitions.
  • Zero counts: an unseen emission gets probability 0 and kills a path. Smooth B.
  • Pick N honestly: more states always fit better. Validate on held-out data.
Taras Trishchuk Based on Jurafsky & Martin, SLP3, Appendix A trishchuk.com/learn

↓ Download the poster as PNG

Try it

Type ice-cream counts (1, 2 or 3 per day, up to 30 days) and watch the same Forward and Viterbi code from the poster run on your sequence.

Forward αt(j)
day 1 o = 3day 2 o = 1day 3 o = 3
H.32.0404.0235
C.02.069.005066
Viterbi vt(j)
day 1 o = 3day 2 o = 1day 3 o = 3
H.32.0384.0128
C.02.064.0032
Likelihood P(O | λ)
.028562
Best hidden path
HCH
its probability
.0128

Model: the Eisner HMM above. Very small values are shown as ×10⁻ⁿ.

Sources and further reading