Skip to main content

Correcting post-lemmatization spelling errors

Project description

🧬 lemma-corrector

Treating text corpora like sequenced genomes to fix lemmatization artifacts.

Standard NLP lemmatizers often propagate spelling errors, resulting in corrupted, non-existent lemmas (e.g., happi instead of happy, or runn instead of run). lemma-corrector bypasses traditional rigid dictionary lookups by applying graph-based error-correction algorithms inspired by bioinformatics to your text corpus.

By treating lemmas as nodes in a similarity graph, this library uses Louvain community detection and PageRank consensus to identify and repair misspelled lemmas without relying on pre-defined dictionaries.

✨ Features

  • Graph-Based Correction: Maps lemmas into a NetworkX graph based on Damerau-Levenshtein edit distance.
  • Smart Community Detection: Uses the Louvain algorithm to cluster morphologically similar lemmas together.
  • Consensus Leader Election: Identifies the correct spelling by finding the node that is both the most frequent and the most central (PageRank) in its community.
  • Vocabulary Guardrails: Optionally accepts a set of known correct words to prevent over-correcting valid, domain-specific terminology.
  • Length-Aware Weighting: Edge weights scale with string length, recognizing that a single typo in a long word is statistically more likely to be an error than a single character difference between two short words.

🚀 Quick Start

from collections import Counter
from lemma_corrector import LemmaCorrector

# 1. Create a bag of lemmata (e.g., from your NLP pipeline)
# Notice the misspelled/over-lemmatized words: "happi", "runn", "quikly"
bag_of_lemmata = Counter({
    "happy": 150,
    "happi": 12,      # Misspelling
    "run": 200,
    "runn": 8,        # Misspelling
    "quickly": 90,
    "quikly": 5,      # Misspelling
    "the": 1000,
    "a": 800,
})

# 2. Initialize the corrector
corrector = LemmaCorrector(bag_of_lemmata)

# 3. Get the corrections
corrections = corrector.get_corrections()
print(corrections)
# Output: {'happi': 'happy', 'runn': 'run', 'quikly': 'quickly'}

Using a Known Vocabulary

If you have domain-specific jargon that looks like a typo but is actually correct, pass a vocabulary set to protect those words:

# "foo" and "bar" are domain-specific variables, not typos
vocabulary = {"foo", "bar", "baz"}

corrector = LemmaCorrector(bag_of_lemmata, vocabulary=vocabulary)

🧠 How It Works

The algorithm operates in four distinct phases:

  1. Graph Construction: Each unique lemma becomes a node, weighted by its normalized frequency (frequency divided by the max frequency in the corpus). Edges are drawn between lemmas that have a Damerau-Levenshtein distance of exactly 1. Edge weights are calculated as 1.0 - (1.0 / max_length), meaning longer strings with a single edit get stronger connections.

  2. Community Detection: The Louvain algorithm partitions the graph into communities. Lemmas that are structurally similar and connected are grouped together.

  3. Leader Election (Consensus): For each community, the algorithm looks for a "leader" (the correct spelling). To be chosen as the leader, a lemma must satisfy two conditions simultaneously:

    • It must be the most frequent lemma in the community (highest node weight).
    • It must be the most central lemma in the community (highest PageRank). If the most frequent and most central lemmas are different, the community is deemed ambiguous and skipped.
  4. Vocabulary Validation: If a vocabulary is provided, the algorithm enforces two rules:

    • Edges are never created between two known, correct words.
    • A community leader cannot be an unknown word if a known word already exists in that community.

📖 API Reference

LemmaCorrector

The main class for correcting lemmas.

__init__(bag_of_lemmata, vocabulary=None, epsilon=1.0e-6)

  • bag_of_lemmata (Counter[str]): A Counter mapping lemmas to their frequencies.
  • vocabulary (set[str] | None): Optional set of known correct words to protect from correction.
  • epsilon (float): Tolerance threshold for Louvain and PageRank algorithms.

get_corrections() -> dict[str, str]

Computes and returns a dictionary mapping misspelled lemmas to their corrected leaders.

🤝 Contributing

Contributions, issues, and feature requests are welcome! Feel free to check the issues page.

📄 License

This project is licensed under the MIT License.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

lemma_corrector-1.0.0.tar.gz (5.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

lemma_corrector-1.0.0-py3-none-any.whl (6.1 kB view details)

Uploaded Python 3

File details

Details for the file lemma_corrector-1.0.0.tar.gz.

File metadata

  • Download URL: lemma_corrector-1.0.0.tar.gz
  • Upload date:
  • Size: 5.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for lemma_corrector-1.0.0.tar.gz
Algorithm Hash digest
SHA256 0c1aa8789443623915007eb8545c2f9de8c780555084201df31f50ee0b6ed159
MD5 07e678cffe605213df5837e169864e4f
BLAKE2b-256 f60a9b028180cfc762dc92c385cb5975df8dfa8000cff36121eecf3d171b5ff6

See more details on using hashes here.

File details

Details for the file lemma_corrector-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: lemma_corrector-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 6.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for lemma_corrector-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 5f4df3e2f64ff1b8ab5e31bfa8d1e2e919b41c32c16b41a9eb428d07cf0b34bc
MD5 a6d847f2941fbbe3a87d81d638a20c6a
BLAKE2b-256 302a0361d1843abd5db4854b52dc0ab9b8c7917cfa879ccb99b6f650fc93576e

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page