mcq / lemmatizer.py
4deffo's picture
Upload folder using huggingface_hub
b96156b verified
Raw
History Blame Contribute Delete
5.47 kB
"""
Tamil Rule-Based Lemmatizer
Converts inflected Tamil word forms back to their root/base form.
Strategy:
1. Sandhi reversal — handles gemination changes that happen when
case suffixes attach (e.g. நாடு + தின் → நாட்டின் → நாடு)
2. Plain suffix stripping — removes case/number markers that attach
without phonological change (e.g. கட்சிகள் → கட்சி)
Rules are ordered longest-first within each table so the most specific
pattern always wins.
"""
# ---------------------------------------------------------------------------
# TABLE 1: SANDHI REVERSAL
# Handles cases where the stem itself changes phonologically before the suffix.
# ---------------------------------------------------------------------------
_SANDHI_MAP = [
# -ம் nouns pluralised: stem-final ம் → ங்க before கள்
("ங்களின்", "ம்"),
("ங்களில்", "ம்"),
("ங்களை", "ம்"),
("ங்களுக்கு", "ம்"),
("ங்கள்", "ம்"),
# -டு nouns (நாடு, பாடு, …)
("ட்டின்", "டு"),
("ட்டில்", "டு"),
("ட்டை", "டு"),
("ட்டோடு", "டு"),
# -ண்டு nouns
("ண்டின்", "ண்டு"),
("ண்டில்", "ண்டு"),
# -ம் nouns with direct case (சட்டமன்றம் → த்த + case)
("த்தின்", "ம்"),
("த்தில்", "ம்"),
("த்தை", "ம்"),
# -று nouns
("ற்றில்", "று"),
("ற்றின்", "று"),
# -கு nouns
("க்கில்", "கு"),
("க்கின்", "கு"),
# -பு nouns
("ப்பில்", "பு"),
("ப்பின்", "பு"),
# -ல் nouns
("ல்லில்", "ல்"),
("ல்லின்", "ல்"),
# -ர் agent nouns, pluralised
("ர்களை", "ர்"),
("ர்களின்", "ர்"),
("ர்களில்", "ர்"),
("ர்கள்", "ர்"),
]
# ---------------------------------------------------------------------------
# TABLE 2: PLAIN SUFFIX STRIPPING
# No stem change; just remove the suffix (and optionally append a replacement).
# ---------------------------------------------------------------------------
_SUFFIX_MAP = [
# Verbal nouns ending in -த்து with possessive plural
("த்துக்களின்", "த்து"),
("த்துக்களை", "த்து"),
("த்துக்கள்", "த்து"),
# கள் + case markers — strip only the case marker, keep கள்
# (மக்கள் is itself a root; stripping கள் would be wrong)
("களுக்கு", "கள்"),
("களிடம்", "கள்"),
("களோடு", "கள்"),
("களால்", "கள்"),
# Plain கள் plurals — strip entirely (root has no கள்)
("களின்", ""),
("களில்", ""),
("களை", ""),
("கள்", ""),
# -ய் / -யு stems with case
("யின்", ""),
("யில்", ""),
("யை", ""),
("யோடு", ""),
# -வு stems
("விற்கு", "வு"),
("வின்", "வு"),
("வில்", "வு"),
("வை", "வு"),
# Role suffixes (-ராக → -ர்)
("ராகவே", "ர்"),
("ராக", "ர்"),
("வராக", "வர்"),
# General oblique / case suffixes
("ஆக", ""),
("இன்", ""),
("இல்", ""),
("க்கு", ""),
("டன்", ""),
("உடன்", ""),
("ஓடு", ""),
("ஆல்", ""),
("இருந்து", ""),
("க்காக", ""),
("உக்கு", ""),
]
# Minimum character length to accept a stripped root as valid
_MIN_ROOT_LEN = 2
def get_root(word: str) -> str:
"""
Return the root/base form of a Tamil word.
Examples
--------
>>> get_root("சட்டமன்றத்தில்")
'சட்டமன்றம்'
>>> get_root("கட்சிகள்")
'கட்சி'
>>> get_root("சென்னை")
'சென்னை' # proper noun with no suffix — returned unchanged
"""
word = word.strip()
# Step 1: sandhi reversal
for suffix, replacement in _SANDHI_MAP:
if word.endswith(suffix):
root = word[: -len(suffix)] + replacement
if len(root) >= _MIN_ROOT_LEN:
return root
# Step 2: plain suffix stripping
for suffix, replacement in _SUFFIX_MAP:
if word.endswith(suffix):
root = word[: -len(suffix)] + replacement
if len(root) >= _MIN_ROOT_LEN:
return root
return word
def get_root_with_surface(surface_word: str) -> tuple[str, str]:
"""
Return (root, surface_word).
Convenience wrapper so callers can keep both forms easily.
"""
return get_root(surface_word), surface_word