textmachine/eval/bank_autonomy/m21b.py

70 lines
3.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
"""ЗАМОR 21b: pairwise stability, batch-change proxy, series consistency, flip subclass. $0."""
from parse_common import terminologist_rows
from collections import defaultdict
import re
tr = terminologist_rows()
# src -> pass -> dst (first), and src -> pass -> chunk_idx
sp = defaultdict(dict); sc = defaultdict(dict)
for r in tr:
sp[r["src"]][r["pass"]] = r["dst"]
sc[r["src"]][r["pass"]] = r["chunk_idx"]
def pair_stability(a, b):
common = [s for s in sp if a in sp[s] and b in sp[s]]
same = [s for s in common if sp[s][a] == sp[s][b]]
return len(same), len(common)
print("=== PAIRWISE STABILITY ===")
for a,b in [(1,2),(2,3),(1,3)]:
s,c = pair_stability(a,b)
print(f" P{a}↔P{b}: {s}/{c} identical ({s/c*100:.1f}%) -> {c-s} differ")
# batch-change proxy: for src in >=2 passes, did chunk_idx change between passes?
n2 = [s for s in sp if len(sp[s])>=2]
batch_changed = [s for s in n2 if len(set(sc[s].values()))>1]
print(f"\n=== BATCH (chunk_idx) CHANGED across passes: {len(batch_changed)}/{len(n2)} ===")
# Among unstable, correlate with batch change
unstable = [s for s in n2 if len(set(sp[s].values()))>1]
u_batch = [s for s in unstable if len(set(sc[s].values()))>1]
print(f" of {len(unstable)} unstable, batch also changed in {len(u_batch)}")
# --- translate<->transliterate flip detector ---
# heuristic: a "transliterated" variant is one whose Russian tokens (lowercased) look like a
# pure Palladius syllabic rendering (no common Russian content word). Rough proxy: variant is a
# single capitalized/uncapitalized token-run with no space-separated Russian function/content word
# from a small stoplist. We instead detect FLIP by: one pass has a variant sharing a Cyrillic
# common word with a russian gloss, another pass is a compact translit token.
RU_CONTENT = set("камень море река гу мастер уровень ранг класс клан вождь глава поселение храм точка "
"открытие пробуждение винный червь свайный дом талант культивации культивация "
"истинной сущности океан бронзовое бронзовый серийный насильник великий титан "
"демонического пути жизни жизненное жизненный воспеваю сливу призыв вину матушка "
"камера зал апертура очистка очищение сокровище клад чудесных редчайших десять "
"четвёртого поколения четвёртый непредсказуемы переменчива погода небеса".split())
def has_ru_content(dst):
toks = re.findall(r"[а-яё]+", dst.lower())
return any(t in RU_CONTENT for t in toks)
def is_compact_translit(dst):
# no spaces (or hyphenated single concept) AND no russian content word
core = dst.replace("«","").replace("»","").strip()
return (not has_ru_content(core)) and (len(core.split())<=1 or "-" in core)
flips = []
for s in unstable:
variants = list(sp[s].values())
ru = [v for v in variants if has_ru_content(v)]
tl = [v for v in variants if is_compact_translit(v) and not has_ru_content(v)]
if ru and tl:
flips.append((s, {p:sp[s][p] for p in sorted(sp[s])}))
print(f"\n=== TRANSLATE↔TRANSLITERATE FLIP candidates ({len(flips)}) ===")
for s,pm in flips:
print(" ", s, "->", " | ".join(f"P{p}={pm[p]}" for p in pm))
# --- P3 series consistency: genus word of 等-series and 转-series ---
print("\n=== P3 SERIES CONSISTENCY ===")
deng = {s:sp[s].get(3) for s in sp if s.endswith("") and 3 in sp[s]}
print(" 等-series (P3):")
for s,d in sorted(deng.items()):
print(f" {s} -> {d}")