Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Penalties

FuzzyPenalties sets the cost each edit operation adds to a candidate’s total penalty, which in turn drives the score. Shaping these costs lets you express what kinds of error are likely in your domain.

use fuzzy_aho_corasick::{FuzzyAhoCorasickBuilder, FuzzyLimits, FuzzyPenalties};

let engine = FuzzyAhoCorasickBuilder::new()
    .fuzzy(FuzzyLimits::new().edits(2))
    .penalties(
        FuzzyPenalties::default()
            .substitution(0.7)
            .insertion(0.9)
            .deletion(0.9)
            .swap(1.0),
    )
    .build(["pattern"]);

The four costs

FieldApplies toNotes
substitutionreplacing one symbol with anotherscaled by similarity: the added penalty is substitution * (1 - sim), so a near-miss costs little and an exact match costs nothing.
insertionan extra symbol in the textflat cost.
deletiona missing pattern symbolflat cost.
swaptransposing two adjacent symbolsflat cost, counted as a single operation.

Defaults

The defaults are tuned so that a substitution is the most expensive edit, insertions the cheapest, with deletions and swaps in between (roughly substitution ≈ 1.43, deletion ≈ 0.91, insertion ≈ 0.52, swap ≈ 0.52). This reflects that an inserted or transposed character usually preserves more of the intended word than an outright wrong character does.

You rarely need to change these, but doing so is the right tool when you know your errors: for OCR, substitutions between look-alike glyphs should be cheap (do that via the similarity table rather than the flat substitution cost); for speech-to-text, insertions/deletions of small words might dominate.

How penalties become a score

The costs accumulate over the edits in a candidate, then feed the score:

similarity = (N - Σ penalties) / N * weight

Because the substitution cost is multiplied by (1 - sim), two symbols the similarity table rates as 0.7-similar incur only 30% of the full substitution penalty. That interplay — flat costs for insert/delete/swap, similarity-scaled cost for substitution — is what lets the engine treat 0o as a near-match while treating an unrelated substitution as a real error.

Tip: penalties and the threshold work together. If you find yourself pushing a penalty very high just to exclude a certain match, consider whether an edit limit or the weakest-link floor expresses your intent more directly.