nmstech's picture
Initial release: TurkTokenizer v1.0.0 — TR-MMLU 92%
ca41c16 verified
"""Fix 10: Turkish compound word annotation."""
from __future__ import annotations
KNOWN_COMPOUNDS: dict[str, list[str]] = {
"başbakan": ["baş", "bakan"],
"cumhurbaşkanı": ["cumhur", "başkan"],
"dışişleri": ["dış", "iş"],
"içişleri": ["iç", "iş"],
"maliye": ["mal", "iye"],
"belediye": ["beled", "iye"],
"ayakkabı": ["ayak", "kap"],
"yelkovan": ["yel", "kovan"],
"saatlik": ["saat", "lik"],
"günlük": ["gün", "lük"],
"yıllık": ["yıl", "lık"],
"aylık": ["ay", "lık"],
"haftalık": ["hafta", "lık"],
"gastrointestinal": ["gastro", "intestinal"],
"kardiyovasküler": ["kardio", "vasküler"],
"nöropsikiyatri": ["nöro", "psikiyatri"],
"biyokimya": ["biyo", "kimya"],
"mikrobiyoloji": ["mikro", "biyoloji"],
"farmakoloji": ["farma", "koloji"],
"patoloji": ["pato", "loji"],
"hematoloji": ["hemato", "loji"],
"nefroloji": ["nefro", "loji"],
"kardiyoloji": ["kardio", "loji"],
"radyoloji": ["radyo", "loji"],
"onkoloji": ["onko", "loji"],
"elektromanyetik": ["elektro", "manyetik"],
"termodinamik": ["termo", "dinamik"],
"hidroelektrik": ["hidro", "elektrik"],
"biyoinformatik": ["biyo", "informatik"],
"nanoteknoloji": ["nano", "teknoloji"],
"futbolcu": ["futbol", "cu"],
"basketbolcu": ["basketbol", "cu"],
"voleybolcu": ["voleybol", "cu"],
}
def _decompose_zemberek(word: str, morphology) -> list[str] | None:
try:
import jpype # noqa: PLC0415
wa = morphology.analyze(jpype.JString(word))
for sa in wa.getAnalysisResults():
morphemes = [str(m) for m in sa.getMorphemes()]
roots = [m for m in morphemes if "Noun" in m or "Verb" in m or "Adj" in m]
if len(roots) > 1:
return roots
except Exception: # noqa: BLE001
pass
return None
def add_compound_info(tokens: list[dict], morphology=None) -> list[dict]:
"""Annotate ROOT tokens that are compound words with ``_compound`` and ``_parts``."""
result: list[dict] = []
for tok in tokens:
if tok["type"] != "ROOT" or tok["token"].strip().startswith("<"):
result.append(tok)
continue
surface = tok["token"].strip().lower()
if morphology is not None:
parts = _decompose_zemberek(surface, morphology)
if parts and len(parts) > 1:
result.append({**tok, "_compound": True, "_parts": parts, "_source": "zemberek"})
continue
if surface in KNOWN_COMPOUNDS:
result.append({**tok, "_compound": True, "_parts": KNOWN_COMPOUNDS[surface], "_source": "manual"})
else:
result.append(tok)
return result