Skip to content

Commit 2aea4ec

Browse files
Docs: migrate Round 9 record to completed.md; stop (no further rounds planned)
1 parent 444ea10 commit 2aea4ec

2 files changed

Lines changed: 231 additions & 196 deletions

File tree

‎completed.md‎

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -827,3 +827,208 @@ and commit NC-SA-derived content. Numbers documented here only.
827827
Round-8 benchmark + bundled table remain as committed; nothing more planned);
828828
PROIEL-derived content stays out of the repo regardless. Record migrated from
829829
todo.md; Round 9 drafted there.
830+
831+
# Round 9: classical Greek, contextual homographs, papyrus numerals ✅
832+
833+
**User approved all three items ("Do all 3"); all complete and committed**
834+
(`6f8ae3a` item 1; `2652cbf` item 2; `444ea10` item 3). Standing constraints held:
835+
no Latin work, PROIEL-derived content stays out of committed files (NC-SA), default
836+
NT behavior unchanged. Working files in `tmp/<corpus>/` (git-ignored): AGLDT clone +
837+
classical evaluator (`tmp/agldt/`, `tmp/grc/`), homograph A/B evaluator (`tmp/r9/`).
838+
839+
## Where things stand after Round 8
840+
841+
- LXX coverage 99.81% (Round 2); NT ~95% top-1; AF 99.35% / 96.6–97.4% lemma
842+
(Round 7); PapyGreek 92.9% coverage / 83.7% top-1 with PG tables (Round 8).
843+
- PROIEL cross-validation: the SBLGNT-trained table transfers **+12pp** to unseen
844+
text — ranking is robust, not convention-fitted. The stable true residual across
845+
*both* independent golds is a handful of function-word homographs: ὡς→ὅς ×455,
846+
εἰ/ἢ→εἰμί ~×650, τε→σύ ×213, ὃ/ἃ→ὁ ~×280.
847+
- AGLDT v2.1 Greek is much bigger than the Round-8 research table assumed:
848+
**557,918 words** (Homer ~230K, Thucydides, Herodotus, Sophocles ×3 vols,
849+
Aeschylus ×6, Hesiod ×3, Plato, Plutarch ×2, Athenaeus ×2, Diodorus, Polybius,
850+
Lysias ×4, Apollodorus, Aesop) — CC BY-SA 3.0 US, commit-safe.
851+
852+
## Round 9 plan (checkable; all approved)
853+
854+
1. **Classical Greek round** ✅ (see review below)
855+
- [x] Baseline: coverage / top-1 / coarse POS over AGLDT v2.1 Greek (557,918 words;
856+
per-author breakdown; epic/Ionic dialect is the stress test).
857+
- [x] Build + bundle `lemma_frequencies_grc.json` (`--format agldt`); re-measure
858+
ranked top-1.
859+
- [x] Stemlib additions: **not needed** — after the elision fix, residual misses are
860+
708 tokens of editorial fragments and one-off names (see review).
861+
- [x] Guards: AF/PG snapshots byte-identical (or known endtable noise); pytest 33/33.
862+
- [x] Independent cross-check: PROIEL Herodotus (`hdt.conll`, CC BY-NC-SA →
863+
measurement/docs only, nothing committed).
864+
2. **Contextual homograph disambiguation** ✅ (see review below)
865+
- [x] Profile the residual homographs on SBLGNT/AF/PG gold to fix the form set
866+
and context features.
867+
- [x] Train a small learned model P(lemma | form, prev POS, next POS) on
868+
commit-safe gold only (SBLGNT + AF + PG; LXX excluded — no annotated `.mlxx`
869+
gold in this workspace); bundle as data table.
870+
- [x] Wire in behind an opt-in flag (API + CLI); default path byte-identical.
871+
- [x] Verify: measured +0.6–1.6pp top-1 on SBLGNT/AF/PapyGreek (below the
872+
+2–4pp target — see review for why that is the ceiling); transfers to PROIEL
873+
greek-nt (independent gold); pytest 33/33.
874+
3. **PapyGreek numerals** ✅ (see review below)
875+
- [x] Inspect ALDT numeral gold (postag `m`): forms, lemmas, marker patterns.
876+
- [x] Build bundled papyrus-numeral table from PapyGreek gold (CC BY-SA);
877+
opt-in flag emits synthetic analyses for unanalyzed numeral tokens
878+
(`unknown_as_proper` precedent) — never silent stemlib additions.
879+
- [x] Verify: coverage +2.2pp on PapyGreek; AF/SBLGNT default paths
880+
byte-identical, PG baseline matches Round 8's snapshot; pytest 33/33.
881+
882+
## Review (Round 9, item 1: classical Greek) ✅
883+
884+
**Dataset**: AGLDT v2.1 Greek (`tmp/agldt/`, CC BY-SA 3.0 US): **469,254 word tokens**
885+
across Homer (~200K), Sophocles, Aeschylus, Athenaeus, Herodotus, Polybius,
886+
Diodorus, Thucydides, Plutarch, Hesiod, Lysias, Plato, Aesop, Homeric Hymns,
887+
Apollodorus. Evaluator: `tmp/grc/eval_grc.py` (per-author breakdown; AGLDT postag
888+
pos-1 empirically mapped — note it differs from Latin: g=particle, p=pronoun,
889+
r=preposition, l=article, m=numeral).
890+
891+
**The one systematic gap was elision-mark encoding.** Baseline coverage was 92.8%
892+
(Homer 90.3%, Sophocles 88.5%) with the top misses all word-final U+0313 (combining
893+
comma above, the classical elision mark): δ̓ ×10,778 alone = 2.3% of the corpus.
894+
`to_beta()` now maps a *word-final* U+0313 to the ASCII apostrophe Morpheus already
895+
recognizes (mid-word combining marks untouched). Every top-30 elided form was
896+
verified to resolve through existing stemlib entries — no new stems needed for them.
897+
Safety: SBLGNT/AF/PapyGreek gold contain **zero** word-final U+0313/U+0306 (scanned);
898+
LXX is beta code, so structurally impossible. Result:
899+
900+
| metric | before fix | after fix |
901+
|---|---:|---:|
902+
| coverage (ALL) | 92.8% | **99.8%** |
903+
| Homer | 90.3% | **100.0%** |
904+
| Sophocles / Aeschylus / Hesiod | 88.5 / 90.2 / 90.6% | 99.8 / 99.6 / 99.7% |
905+
906+
**Bundled table**: `data/lemma_frequencies_grc.json` (21,889 lemmas / 476,401
907+
tokens; attribution in file). Ranked results per author:
908+
909+
| author | n | coverage | top-1 raw → ranked | POS |
910+
|---|---:|---:|---|---:|
911+
| **ALL** | 469,254 | 99.8% | 79.9 → **91.4%** (+11.5pp) | 85.1% |
912+
| Homer | 200,091 | 100.0% | 78.5 → 91.2% | 88.1% |
913+
| Sophocles | 40,851 | 99.8% | 75.8 → 88.9% | 83.7% |
914+
| Aeschylus | 39,479 | 99.6% | 78.1 → 89.4% | 87.3% |
915+
| Athenaeus | 33,272 | 99.2% | 82.0 → 91.8% | 81.1% |
916+
| Herodotus | 28,791 | 100.0% | 81.8 → 91.8% | 79.1% |
917+
| Polybius | 25,528 | 100.0% | 84.1 → 93.9% | 83.4% |
918+
| Diodorus Siculus | 23,037 | 99.9% | 86.2 → **95.4%** | 84.6% |
919+
| Thucydides | 22,336 | 99.9% | 83.5 → 92.5% | 78.8% |
920+
| Plutarch | 19,386 | 99.9% | 85.3 → 93.9% | 81.6% |
921+
| Hesiod | 16,280 | 99.7% | 77.7 → 92.3% | 90.6% |
922+
923+
**No stemlib additions needed.** Residual misses: **708 tokens / 527 forms (0.15%)**
924+
— editorial fragments (τ- ×47, κ- ×40), one-off rare names (×1–6 each from
925+
Athenaeus/Plutarch/Diodorus), and <40 epic-dialectal forms (γώ/γὼ→ἐγώ, σθω/σθαι,
926+
πὶ/φὶ). Adding ~500 one-off names to the shared stemlib would be bloat for 0.1%
927+
— deliberately not done (contrast PapyGreek, where misses were systematic).
928+
929+
**Independent cross-check — PROIEL Herodotus** (`hdt.conll`, 83,819 tokens,
930+
CC BY-NC-SA → docs only): coverage **99.8%**; top-1 raw 79.9/81.5 exact/acc-insens;
931+
ranked with NT tables 86.3/87.6, with the classical grc table **90.2/91.7** — the
932+
classical table beats the Koine one by +4pp on a text it shares no words with,
933+
and Morpheus's coverage of Ionic prose matches AGLDT's (100%).
934+
935+
**Verification**: pytest 33/33; AF main-config re-run adds zero drift vs Round 8's
936+
check run (both show only the known endtable noise); PapyGreek eval byte-identical
937+
in both table configs.
938+
939+
## Review (Round 9, item 2: contextual homograph disambiguation) ✅
940+
941+
**Design.** Opt-in re-ranker (`Morpheus(use_homograph_context=True)` / CLI
942+
`--homographs`, Greek only; off by default — the table is not even loaded when off).
943+
Context = the neighbours' *frequency-ranked top-1 POS* (Morpheus's own output, not
944+
gold POS — no train/test mismatch); verse/sentence boundaries reset context.
945+
Scoring is `log1p(count)` with exact-context → marginal fallback; tokens whose form
946+
is not in the table are untouched. New module `morpheus_toolkit/homographs.py`
947+
tables by beta form and lazy-loads only when the flag is on.
948+
949+
**Training.** Commit-safe gold only: SBLGNT + Apostolic Fathers + PapyGreek (all CC
950+
BY-SA, 237,231 tokens). LXX deliberately excluded — no annotated `.mlxx` gold exists
951+
in this workspace (only Morpheus's own outputs in `tmp/lxx/`); documented as a
952+
limitation. Table: **644 forms** (`min_form=20`, `min_ctx=5`) →
953+
`data/homograph_contexts.json`; rebuild with `scripts/build_homograph_contexts.py`
954+
(idempotent; readers for all three gold formats).
955+
956+
**Result — A/B (flag off → on, gold = each corpus's own lemma):**
957+
958+
| corpus | n | top-1 | acc-insens | POS |
959+
|---|---:|---|---|---|
960+
| SBLGNT (in-domain) | 137,554 | 93.6 → **94.4** (+0.8pp) | 94.2 → 95.0 | 77.6 → 78.2 |
961+
| Apostolic Fathers | 63,222 | 89.0 → **89.7** (+0.7pp) | 89.6 → 90.3 | 75.0 → 75.5 |
962+
| PapyGreek | 36,455 | 83.8 → **85.4** (+1.6pp) | 85.3 → 86.9 | 77.3 → 78.5 |
963+
| PROIEL greek-nt (independent) | 132,366 | 92.4 → **93.0** (+0.6pp) | 93.4 → 94.0 | 82.7 → 83.1 |
964+
965+
Positive on **all four** corpora including the fully independent PROIEL gold —
966+
transfer confirmed, not memorization. But +0.6–1.6pp, not the +2–4pp target: only
967+
**42 of the 644 table forms have non-degenerate marginals (and just 13 any context
968+
split)** — Koine gold is ~95–100% one-way for most ambiguous forms, and several
969+
"splits" are accent/case annotation conventions (te→τέ/τε, ti/→τίς/τις). The famous
970+
residual families from the Round-8 cross-validation (w(s→ὡς unanimous in training,
971+
ei)→εἰ unanimous, o(\→ὅς unanimous) are inter-edition convention differences with
972+
PROIEL, not ranking errors — the model correctly doesn't chase them. Shipped as
973+
opt-in tooling; the larger residual is convention noise no ranker can fix (lesson
974+
captured in `lessons.md`).
975+
976+
**Verification**: pytest 33/33; AF default-path re-run byte-identical to Round 9's
977+
check snapshot (`tmp/af/ev2_af_r9check.txt`) — flag off is a proven no-op.
978+
979+
## Review (Round 9, item 3: PapyGreek numerals) ✅
980+
981+
**Gold profile.** The ALDT treebank has **1,454 numeral tokens** (postag `m`); **853
982+
are currently missed — all bare Greek-letter numerals** (β = 2, κθ = 90, λϛ = 36 …;
983+
the corpus stores them without a visible numeral sign), only 83 distinct forms. Of the
984+
601 "analyzed" numerals: word-numerals Morpheus handles fine (χίλιοι, δέκα — tagged N in
985+
85% of cases) plus **false hits**: short betas collide with real stems under
986+
accent-insensitive matching (κε→ἄν, ιε→εἶμι, ιη→κερατέα — 315 of 348 letter-numeral hits
987+
carry the wrong top-1). Those are deliberately NOT touched: overriding analyzed tokens
988+
would corrupt real one/two-letter particles (κε = καί) in other corpora.
989+
990+
**Feature.** `data/papyrus_numerals.json` (**50 forms**; PapyGreek numeral gold, CC BY-SA):
991+
for each form Morpheus misses, the majority-vote gold lemma keyed by beta code. Rebuild:
992+
`scripts/build_papyrus_numerals.py` (pipe annotations stripped from lemmas too; only pure
993+
letter lemmas count as reliable — a handful of decimal-annotated tokens like `Ατ→1300`
994+
are excluded). Opt-in via `Morpheus(numerals=True)` / CLI `--numerals` (new module
995+
`morpheus_toolkit/numerals.py`, Greek only): unanalyzed tokens whose beta is in the table
996+
get a synthetic analysis (POS N, `proposed=True`). Runs before `unknown_as_proper`
997+
(more specific wins); off by default — no table loaded, behavior unchanged.
998+
999+
**Result (PG evaluator + PG frequency table; flag off → on):**
1000+
1001+
| metric | off | on |
1002+
|---|---:|---:|
1003+
| coverage | 92.9% | **95.1%** (+2.2pp) |
1004+
| numerals missed | 853/1454 | **38/1454** |
1005+
| top-1 ranked (exact / acc-insens) | 83.7 / 85.1% | **85.9 / 87.2%** (+2.2pp) |
1006+
1007+
All 815 missed tokens whose beta is in the table are recovered; the residual 38 are forms
1008+
below `min_count=2` (one-off editorial variants). Recovered numerals are correct by
1009+
construction (lemma = gold letter string), so top-1 rises too — except a handful of
1010+
decimal-annotated tokens that now count as covered-but-mismatching, and **4 in-domain false
1011+
positives** (τ = ἀντί abbreviation ×3 + one editorial placeholder) get labeled numerals;
1012+
consumers can filter on `proposed=True`. The POS metric drops 81.7→79.8% purely as a
1013+
denominator artifact: that evaluator maps treebank `m` → class X and Morpheus has no numeral
1014+
tag, so every papyrus numeral counts as a POS mismatch both before and after.
1015+
1016+
**Verification**: pytest 33/33; PG baseline byte-identical to Round 8's saved snapshot;
1017+
AF re-run byte-identical (`tmp/af/ev2_af_r9check.txt`); SBLGNT flag-off A/B line identical —
1018+
default path unchanged on all three corpora.
1019+
1020+
## Not doing (standing constraints)
1021+
1022+
- Any Latin work (user direction for Round 9); the Round-8 Latin benchmark + table
1023+
remain as committed, untouched.
1024+
- PROIEL-derived content in committed files (CC BY-NC-SA; measurement/docs only).
1025+
- NT behavior changes (Round-7 direction): no stemlib edits that alter SBLGNT/NT
1026+
output to fit another edition's conventions.
1027+
1028+
**Open questions — resolution:** user chose to stop here ("Migrate, commit, push and
1029+
stop"); record migrated from todo.md; morpheus origin/master pushed. No further rounds
1030+
planned at this time. Candidate follow-ups if resumed: retrain the homograph table once
1031+
annotated LXX gold is available in the workspace (excluded — no `.mlxx` gold locally);
1032+
the 38 sub-threshold numeral forms are diminishing returns; fixing the false-hit letter
1033+
numerals (315 wrong top-1 on PapyGreek) would need stemlib entries that change default
1034+
behavior, out of scope per user direction.

0 commit comments

Comments
 (0)