| """Milestone-(a) data audit for one fold: script inventory + dev coverage, attested-tag |
| ceiling, lemma charset, MWT/unencodable counts. Usage: python scripts/tagger/audit_fold.py 0""" |
| import os, sys, unicodedata |
| from collections import Counter |
| from pathlib import Path |
|
|
| sys.path.insert(0, str(Path(__file__).resolve().parents[2])) |
| from tagger.backbone import ALPHABET |
| from tagger.conllu import read_conllu |
| from tagger.dataset import encode_word |
| from tagger.edits import LabelVocab, compute_script, form_key |
|
|
| KFOLD = Path(os.path.expandvars("$STOICHEIA_DATA/treebanks/oga_repo/kfold")) |
| fold = sys.argv[1] if len(sys.argv) > 1 else "0" |
|
|
| train = list(read_conllu(KFOLD / f"train{fold}.conllu")) |
| dev = list(read_conllu(KFOLD / f"dev{fold}.conllu")) |
| print(f"train sents={len(train)} dev sents={len(dev)}") |
|
|
| enc_ok = lambda f: encode_word(f) is not None |
| vocab = LabelVocab.build(train, enc_ok) |
| print(f"scripts={vocab.n_scripts} tags={len(vocab.tags)} upos={vocab.upos}") |
| print("xpos position alphabet sizes:", [len(a) for a in vocab.xpos_alpha]) |
| print(f"lexicon forms={len(vocab.lex_f)} nongreek forms={len(vocab.nongreek)}") |
|
|
| n_tok = sum(len(s.tokens) for s in train) |
| n_mwt = sum(1 for s in train for k, _ in s.lines if k == "mwt") |
| n_empty = sum(1 for s in train for k, _ in s.lines if k == "empty") |
| print(f"train tokens={n_tok} mwt_ranges={n_mwt} empty_nodes={n_empty}") |
|
|
| |
| charset = Counter() |
| for s in train: |
| for t in s.tokens: |
| if enc_ok(t.form): |
| for c in unicodedata.normalize("NFD", t.lemma): |
| if c.lower() not in ALPHABET and not unicodedata.category(c).startswith("M"): |
| charset[c] += 1 |
| print("lemma non-greek chars (top 25):", charset.most_common(25)) |
|
|
| |
| cov = Counter() |
| for s in dev: |
| for t in s.tokens: |
| if not enc_ok(t.form): |
| cov["nongreek"] += 1 |
| key = t.form in vocab.nongreek |
| tag = (t.xpos or "-" * 9)[:9].ljust(9, "-") |
| if key and vocab.nongreek[t.form] == (t.lemma, t.upos, tag): |
| cov["nongreek_rule_ok"] += 1 |
| continue |
| cov["greek"] += 1 |
| key = form_key(t.form) |
| sc = compute_script(key, t.lemma) |
| cov["script_seen"] += vocab.script_id(sc) != -100 |
| tag = (t.xpos or "-" * 9)[:9].ljust(9, "-") |
| cov["tag_seen"] += tag in vocab._tagset |
| cov["form_in_lex"] += key in vocab.lex_f |
| if key in vocab.lex_f: |
| cov["lemma_in_lex"] += t.lemma in vocab.lex_f[key] |
|
|
| g = max(cov["greek"], 1) |
| print(f"dev greek tokens={cov['greek']} nongreek={cov['nongreek']} " |
| f"(rule-correct {cov['nongreek_rule_ok']}/{cov['nongreek']})") |
| print(f"SCRIPT COVERAGE = {cov['script_seen']/g:.4f} (gate >= 0.98)") |
| print(f"ATTESTED-TAG CEILING = {cov['tag_seen']/g:.4f}") |
| print(f"form in lexicon = {cov['form_in_lex']/g:.4f}") |
| print(f" ...and gold lemma among its candidates = {cov['lemma_in_lex']/max(cov['form_in_lex'],1):.4f}") |
|
|