Hidden Markov Models (HMM)
Advanced Statistical Methods
Modeling Sequences With Hidden States
Hidden Markov Models capture systems that transition between unobservable states while generating observable outputs. The forward-backward, Viterbi, and Baum-Welch algorithms enable inference and learning in these doubly stochastic processes.
- Speech recognition — Model phoneme sequences where acoustic observations depend on hidden articulatory states
- Bioinformatics — Identify gene regions using hidden states representing functional annotations
- Finance — Detect regime changes in market volatility using hidden bull/bear states
HMMs let you decode the hidden story behind observable sequences.
The Forward-Backward Algorithm
The Viterbi Algorithm
import numpy as np
class HiddenMarkovModel:
def __init__(self, n_states, n_observations):
self.N = n_states
self.M = n_observations
self.A = np.ones((n_states, n_states)) / n_states
self.B = np.ones((n_states, n_observations)) / n_observations
self.pi = np.ones(n_states) / n_states
def forward(self, obs):
T = len(obs)
alpha = np.zeros((T, self.N))
alpha[0] = self.pi * self.B[:, obs[0]]
for t in range(1, T):
for j in range(self.N):
alpha[t, j] = np.sum(alpha[t-1] * self.A[:, j]) * self.B[j, obs[t]]
return alpha
def backward(self, obs):
T = len(obs)
beta = np.zeros((T, self.N))
beta[T-1] = 1.0
for t in range(T-2, -1, -1):
for i in range(self.N):
beta[t, i] = np.sum(self.A[i] * self.B[:, obs[t+1]] * beta[t+1])
return beta
def viterbi(self, obs):
T = len(obs)
delta = np.zeros((T, self.N))
psi = np.zeros((T, self.N), dtype=int)
delta[0] = self.pi * self.B[:, obs[0]]
for t in range(1, T):
for j in range(self.N):
candidates = delta[t-1] * self.A[:, j]
psi[t, j] = np.argmax(candidates)
delta[t, j] = candidates[psi[t, j]] * self.B[j, obs[t]]
states = np.zeros(T, dtype=int)
states[T-1] = np.argmax(delta[T-1])
for t in range(T-2, -1, -1):
states[t] = psi[t+1, states[t+1]]
return states, delta[T-1, states[T-1]]