Skip to main content
This page covers the implementation details, database requirements, beam search tuning, and Cython acceleration for the Viterbi decoder used in mySpellChecker’s POS tagging and joint segmentation pipeline.

Overview

The Viterbi algorithm finds the most likely sequence of hidden states (POS tags) given observed emissions (words). It uses dynamic programming with beam search, running in O(N × B² × T) time where N is the sequence length, B is the beam width, and T is the tagset size.

Requirements

The Viterbi POS tagger requires probability tables in the database to function effectively:

Building Database with POS Probabilities

POS probability tables are populated when you build a database with a POS tagger:

Checking Database for POS Tables

Fallback Behavior

If POS probability tables are empty or missing:
  1. Viterbi falls back to morphological analysis for tag prediction
  2. Accuracy drops from ~85% to ~70% (similar to rule-based tagger)
  3. A warning is logged: “Provider does not support bigram probabilities”

How It Works

Trigram Hidden Markov Model

The implementation uses a trigram HMM with deleted interpolation smoothing:

Algorithm Steps

  1. Initialization: Set probabilities for first position
  2. Recursion: For each position, compute best path using trigram transitions with beam pruning
  3. Termination: Find best final state
  4. Backtracking: Reconstruct optimal path

Implementation

Python Wrapper

Cython Acceleration

The library includes a Cython implementation for 2-5x speedup:

Configuration

Note: Unknown word handling is controlled via the min_prob (default: 1e-10) and unknown_word_tag (default: "UNK") parameters on the ViterbiTagger constructor, not via a separate penalty parameter.
Config resolution: When both constructor arguments and a POSTaggerConfig are provided, explicit constructor arguments always take precedence, even if they match the default value. This means ViterbiTagger(beam_width=10, config=config) uses 10 regardless of what config.viterbi_beam_width says. Omitted parameters fall back to the config, then to built-in defaults.

POSTaggerConfig Viterbi Fields

The POSTaggerConfig class exposes Viterbi-specific tuning parameters. These are separate from the constructor parameters on ViterbiTagger — they control the config-driven pipeline integration.
The lambda_* weights control deleted interpolation smoothing and must sum to 1.0. Higher lambda_trigram gives more weight to trigram context (better for well-trained models), while higher lambda_unigram adds robustness when training data is sparse. Beam search prunes unlikely paths for efficiency:

Joint Segmentation + Tagging

The Viterbi algorithm can jointly segment and tag text:
See Joint Segment Tagger for details.

Emission Score Logic

For the first token (t=1), emission scores are handled specially:

Performance

Integration

See Also