Skip to main content

A spaCy-compatible Scottish Gaelic NLP pipeline with POS tagging and a POS-aware lemmatizer.

Project description

Scottish Gaelic Lemmatizer – CSRI Research Project

This project is part of an ongoing collaborative research initiative between the Cornell College Computer Science Department and Napier University in Edinburgh, Scotland. The goal is to build tools that enable deeper text analysis for the Scottish Gaelic language — a low-resource language with limited computational tools.


Project Context

  • Year 1: A team of students created a cleaned corpus of Scottish Gaelic text and a tokenizer.
  • Year 2 (Current): Focused on developing a rule-based lemmatizer, generating word frequency statistics, and implementing preprocessing techniques specific to Scottish Gaelic grammar and spelling.

What This Tool Does

This lemmatizer reduces inflected Scottish Gaelic word forms to their base forms (lemmas) using:

  • A manually curated irregular dictionary for unpredictable wordforms (e.g., chunnaic → faic)
  • A set of carefully tested suffix rules for regular morphological patterns (e.g., taighean → taigh)
  • Preprocessing steps that handle accents, emphatic suffixes, prosthetic consonants, and lenition
  • Frequency-guided refinement: rules and dictionary are informed by analysis of the most common words
  • Output in a simple, editable format for future researchers to reuse or expand

Tree-like Folder Structure

lemmatizer_gaelic/
├── lemmatizer.py                       # Main lemmatization script using spaCy custom component
├── irregular_dict.json                 # Irregular word → lemma mappings
├── Latest_Corpus.txt                   # Cleaned corpus with "word source" format
├── lemmatized_output.txt               # Output from previous lemmatizer version / reference output
├── lemmatized_output_pos_aware_example.txt # Example output from the new POS-aware lemmatizer
├── compare_lemmas.py                   # Script to compare two lemmatizer output files
├── word_frequency.py                   # Word frequency analysis script (by source)
├── stopWords.txt                       # List of Gaelic stop words (excluded from stats)
├── CorpusBySource.py                   # Exports per-source texts from the raw corpus
└── README.md                           # Project documentation

How It Works

1. Corpus Preparation

  • The input corpus (Latest_Corpus.txt) contains lines in the format:
  • Only the first word of each line is used for lemmatization.

2. Preprocessing Steps

  • Replace acute accents with grave accents
  • Remove emphatic suffixes: -sa, -se, -san, -ne
  • Strip prosthetic consonants: t-, h-, n- (at beginning)
  • Remove lenition marker: h as second letter (e.g., bhean → bean)

3. Lemmatization Logic (lemmatizer.py)

  • Apply preprocessing to each token
  • If token exists in irregular dictionary → use its mapped lemma
  • If not, apply suffix rules (-ean, -an, -achadh, etc.)
  • If no rules match, return preprocessed token (unless it's too short)

Code Flowchart

Load input corpus file
  ↓
Process text with spaCy pipeline (Tokenizer -> POS Tagger -> Custom Lemmatizer)
  ↓                                  (This step assigns POS tags to tokens)
For each token in the spaCy `Doc` object:
  ↓
  Get lowercased raw text
  Initialize lemma with raw text
  ↓
  1. Check if raw token text exists in irregular dictionary
  ├─ Yes → Use lemma from irregulars (e.g., "deach" → "rach") and SKIP further steps for this token
  └─ No → Proceed to preprocessing
             ↓
      2. Preprocess token text (e.g., "chuala" → "cuala", "bhean" → "bean"):
        ├─ Replace acute accents with grave accents
        ├─ Remove emphatic suffixes
        ├─ Remove prosthetic consonants
        └─ Remove lenition marker
             ↓
      3. Check if preprocessed token text exists in irregular dictionary
      ├─ Yes → Use lemma from irregulars (e.g., "cuala" → "cluinn") and SKIP further steps
      └─ No → Proceed to POS-informed suffix rules
                  ↓
          4. Apply POS-informed suffix rules (based on `token.pos_`):
            ├─ If `token.pos_ == "NOUN"`:
            │  ├─ Apply longest noun suffixes first (e.g., "-aichean" -> "", "-annan" -> "", "-ean" -> "", "-an" -> "")
            │  └─ Examples: "eileanan" → "eilean", "stàitean" → "stàit", "lochan" → "loch"
            ├─ If `token.pos_ == "VERB"`:
            │  ├─ Apply longest verb suffixes first (e.g., "-eachadh" -> "-ich", "-eadh" -> "", "-te" -> "", "-ta" -> "")
            │  └─ Examples: "atharrachadh" → "atharraich", "stèidheachadh" → "stèidhich", "aonaichte" → "aonaich", "sònraichte" → "sònraich"
            ├─ If `token.pos_ == "ADJ"`:
            │  ├─ Apply adjective-specific rules
            │  └─ Examples: (comparatives, superlatives, ensuring base forms like "cumanta" remain unchanged)
            └─ If no POS-specific rule matched:
                   ↓
                  5. Fallback: If preprocessing changed the word and no rule applied, use preprocessed word as lemma.
                      If lemma length is 1 or less (and not an irregular), revert to original raw text.
  ↓
Assign final lemma to token in spaCy `Doc` object
  ↓
Repeat for all tokens
  ↓
Output results:
  ├─ Print token → lemma to console
  └─ Save results to `lemmatized_output_pos_aware_example.txt`
  ↓
Print summary:
  ├─ Changed by irregulars
  ├─ Changed by preprocessing
  ├─ Changed by suffix
  ├─ Total changed / unchanged words
  └─ Total operations applied

4. Word Frequency Analysis (word_frequency.py)

  • Computes the top 100 most frequent words by source
  • Excludes stopwords (stopWords.txt)
  • Guides rule updates and dictionary development

Future Work

  • Integrate a robust Gaelic POS tagger to improve lemmatizer accuracy
  • Expand suffix rules and irregulars using linguistic input from Napier University
  • Group frequent words by part of speech (noun, verb, adj) for better rule targeting
  • Evaluate lemmatizer accuracy using a manually verified gold standard

Status

Work in Progress — June 2025

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

gd_core_web_sm-0.1.2.tar.gz (24.2 MB view details)

Uploaded Source

Built Distribution

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

gd_core_web_sm-0.1.2-py3-none-any.whl (24.5 MB view details)

Uploaded Python 3

File details

Details for the file gd_core_web_sm-0.1.2.tar.gz.

File metadata

  • Download URL: gd_core_web_sm-0.1.2.tar.gz
  • Upload date:
  • Size: 24.2 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.5

File hashes

Hashes for gd_core_web_sm-0.1.2.tar.gz
Algorithm Hash digest
SHA256 aff38607b19e7aa45f481de7912c934ff8052dcaa1e2bbff9e97b6752b41f9ca
MD5 d9f974be442a16e2a18e002cf40a2ddd
BLAKE2b-256 0137af8121e3ea7886979adbf874f036bf2c420ac2242c5e5e43f9375cca2e25

See more details on using hashes here.

File details

Details for the file gd_core_web_sm-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: gd_core_web_sm-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 24.5 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.5

File hashes

Hashes for gd_core_web_sm-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 ab1805e8f8346523d595db2a8f42519f4e89a3a72154f4c8d40b868bffb9265b
MD5 0de261a95561e2c8265acde1c1d6af87
BLAKE2b-256 f2e0cdbea91b68afe435a8fb0169ee07d46d20de16564d92dc0283b2e8941d17

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