@@ -827,3 +827,208 @@ and commit NC-SA-derived content. Numbers documented here only.
827827Round-8 benchmark + bundled table remain as committed; nothing more planned);
828828PROIEL-derived content stays out of the repo regardless. Record migrated from
829829todo.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