---
kind: concept
slug: hidden-markov-model
title: Hidden Markov model
summary: >-
  A hidden Markov model labels a sequence with hidden states linked by transition probabilities, each state emitting observations. Viterbi decoding finds the most likely state path. Covered: one ECG segmentation pipeline that refines CNN outputs with a six-state HMM, and the open choices an implementer must still make.
tags: [sequence-modeling, viterbi-decoding, segmentation, ecg]
papers: ["1807.02569"]
related: [sequence-labeling, convolutional-neural-network, conditional-random-field, interpretable-machine-learning]
status: draft
updated_at: 2026-11-09
---

## Overview

A hidden Markov model (HMM) describes a sequence in which each step has a
hidden state, the next state depends only on the current one through a
transition matrix, and each state produces an observed value through an
emission distribution. The states are never seen directly; they are inferred
from the observations. In the one paper on this concept so far, the HMM is
used after a neural network: the network scores each sample for its class, and
the HMM turns those per-sample scores into a consistent sequence of segments
[arxiv:1807.02569 § Methods] (Enhancing ECG segmentation with HMMs).

The shared core across uses is the decoding step: given the observations, find
the most likely hidden state path. Viterbi decoding does this exactly for a
first-order HMM. Whether the state order is fixed and known is the main design
question, because it determines which transitions the model should allow.

## Variants

Only one variant is covered so far.

### CNN scores refined by a six-state HMM

The HMM has one state per segment class of a 12-lead ECG: P wave, PR segment,
QRS complex, ST segment, T wave and TP segment. Start and transition
probabilities are set from manual labels, and emission probabilities are
learned from the CNN output on the training data. A post-processing rule then
removes complexes shorter than 10 ms [arxiv:1807.02569 § Methods] (Enhancing
ECG segmentation with HMMs). The paper reports intersection-over-union values
for each class, with the QRS class highest, but reports no run without the HMM,
so its gain from the HMM step is not measured [arxiv:1807.02569 § Results]
(Validation of ecgAI Machine Learning-based ECG Segmentation). Card:
[Patient ECG profiles (1807.02569)](/papers/1807.02569).

## When to use which

There is only one row so far, so the table below states constraints rather
than a comparison of variants.

| Situation | Use | Why |
|---|---|---|
| Per-sample labels come from a classifier, the label order is fixed and known, and short false segments are a problem | An HMM with Viterbi decoding over the classifier output | The paper uses it this way for six ECG segment classes [arxiv:1807.02569 § Methods] (Enhancing ECG segmentation with HMMs). |
| No reliable transition or start probabilities can be estimated | Do not use this variant as described | The paper gives no values for the start and transition probabilities and sets them from manual labels [arxiv:1807.02569 § Methods] (Enhancing ECG segmentation with HMMs). |
| The label order is free or not known in advance | Check the sources before choosing | The only covered source assumes a fixed segment order. No other order is tested. |

The paper's result tables do not show segmentation with and without the HMM
step, so they do not show that the HMM is needed for the reported accuracy
[arxiv:1807.02569 § Results] (Validation of ecgAI Machine Learning-based ECG
Segmentation). Do not present the HMM as the source of the gain.

## Implementation sketch

Our own pseudocode, following the paper's description. The observation at each
step is the class the network predicts; the emission table gives the
probability of each observed class given each hidden state, learned on training
data. The transition and start values are inputs the implementer must supply.

```pseudocode
# Viterbi refinement of per-sample network labels
# Input:  observed class per sample (T,), start (S,), transition (S, S), emission (S, C)
# Output: most likely state per sample (T,)
# [arxiv:1807.02569 § Methods] (Enhancing ECG segmentation with HMMs)

def viterbi(obs, start, trans, emit):
    # 1. Work in log space to avoid underflow on long sequences
    log_start, log_trans, log_emit = log(start), log(trans), log(emit)
    # 2. Initialise each state with its start score and the first observation
    score = log_start + log_emit[:, obs[0]]              # (S,)
    back = []
    # 3. Extend the best path one sample at a time, keeping back-pointers
    for t in range(1, len(obs)):
        cand = score[:, None] + log_trans                # (S, S)
        back.append(argmax(cand, axis=0))                # (S,)
        score = max(cand, axis=0) + log_emit[:, obs[t]]  # (S,)
    # 4. Trace back from the best final state
    path = [argmax(score)]
    for ptr in reversed(back):
        path.append(ptr[path[-1]])
    return reversed(path)
```

A post-processing step that drops very short segments is a separate
heuristic. The paper uses a 10 ms threshold and does not state its exact form
[arxiv:1807.02569 § Methods] (Enhancing ECG segmentation with HMMs).

## Contradictions

None known. Only one paper covers this concept. Within that paper, the released
code and the text differ on where the emission probabilities are estimated and
on the transition values; see the card's "Paper vs code" section
([Patient ECG profiles](/papers/1807.02569)). This
page follows the paper's text.

## Papers

- [Patient ECG profiles (1807.02569)](/papers/1807.02569): a CNN with a six-state HMM segments 12-lead ECGs, and the segment timings feed a fixed-length profile for downstream models.
