textmachine/eval/exp13/exp13_gates.py

62 lines
2.9 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
"""exp13 — гейты на выходах армов (пре-рег §1.3): эхо-rate / refusal / объём-коридор / полнота.
Читает diag/arms13/<ARM>/<ch>_<ci>.txt + diag/chunks.json (исходники zh). $0 (детерминированно).
Выход: diag/arms13/gates.json + печать таблицы.
"""
from __future__ import annotations
import json, re
from pathlib import Path
DIAG = Path("/home/ubuntu/books/gu-zhenren/diag")
OUT = DIAG / "arms13"
TARGETS = [(5, 0), (5, 1), (7, 0), (7, 1), (14, 0), (14, 1)]
LEN_BOUNDS = (2.2, 4.2) # zh→ru приёмки
REFUSAL = re.compile(r"(?i)\b(я не могу|не буду переводить|as an ai|i cannot|i'm sorry|извините, но я|не могу выполнить|против правил)\b")
HAN = re.compile(r"[一-鿿㐀-䶿]")
def han_ratio(t: str) -> float:
ns = [c for c in t if not c.isspace()]
if not ns:
return 1.0
return sum(1 for c in ns if HAN.match(c)) / len(ns)
def main() -> None:
chunks = json.loads((DIAG / "chunks.json").read_text(encoding="utf-8"))
arms = sorted([p.name for p in OUT.iterdir() if p.is_dir()])
rows, per_arm = [], {}
for arm in arms:
agg = {"arm": arm, "n": 0, "echo": 0, "refusal": 0, "vol_bad": 0, "empty": 0,
"han_sum": 0.0, "vol_sum": 0.0}
for ch, ci in TARGETS:
key = f"{ch}/{ci}"
p = OUT / arm / f"{ch}_{ci}.txt"
src = chunks[key]["source"]
if not p.exists() or not p.read_text(encoding="utf-8").strip():
agg["empty"] += 1; agg["n"] += 1; continue
t = p.read_text(encoding="utf-8").strip()
hr = han_ratio(t)
vr = len(t) / max(1, len(src))
echo = hr > 0.10
ref = bool(REFUSAL.search(t))
volbad = not (LEN_BOUNDS[0] <= vr <= LEN_BOUNDS[1])
agg["n"] += 1; agg["han_sum"] += hr; agg["vol_sum"] += vr
agg["echo"] += echo; agg["refusal"] += ref; agg["vol_bad"] += volbad
rows.append({"arm": arm, "chunk": key, "han": round(hr, 4), "vol": round(vr, 2),
"echo": echo, "refusal": ref, "vol_bad": volbad, "chars": len(t)})
n = max(1, agg["n"] - agg["empty"])
agg["han_avg"] = round(agg["han_sum"] / n, 4)
agg["vol_avg"] = round(agg["vol_sum"] / n, 2)
agg["echo_rate"] = round(agg["echo"] / max(1, agg["n"]), 3)
per_arm[arm] = agg
(OUT / "gates.json").write_text(json.dumps({"per_arm": per_arm, "rows": rows}, ensure_ascii=False, indent=1), encoding="utf-8")
print(f"{'arm':<5} {'n':>2} {'echo':>5} {'refus':>5} {'volBad':>6} {'empty':>5} {'han_avg':>8} {'vol_avg':>7}")
for arm in arms:
a = per_arm[arm]
print(f"{arm:<5} {a['n']:>2} {a['echo']:>5} {a['refusal']:>5} {a['vol_bad']:>6} {a['empty']:>5} {a['han_avg']:>8} {a['vol_avg']:>7} echo_rate={a['echo_rate']}")
if __name__ == "__main__":
main()