MedPlain commited on
Commit ·
c8da949
1
Parent(s): 5edda8d
Add jargon-sensitive readability (Dale-Chall, jargon rate, word familiarity); fix tooltip source term to match the edit
Browse files- engine.py +36 -2
- static/app.js +3 -0
engine.py
CHANGED
|
@@ -56,6 +56,30 @@ def _read_key(*candidates: Path) -> str:
|
|
| 56 |
return ""
|
| 57 |
|
| 58 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 59 |
# --------------------------------------------------------------------------
|
| 60 |
# Configuration knobs (overridable via environment before first import).
|
| 61 |
# Mirrors run_local.py's CONFIG block.
|
|
@@ -580,6 +604,8 @@ class Engine:
|
|
| 580 |
m.update(cs)
|
| 581 |
except Exception:
|
| 582 |
pass
|
|
|
|
|
|
|
| 583 |
# reference-based edit/replacement F1 (benchmark mode only)
|
| 584 |
if refs:
|
| 585 |
try:
|
|
@@ -748,6 +774,13 @@ def _segment_tagged(tagged: str, rat_by_key: Dict, op_by_key: Dict) -> List[Dict
|
|
| 748 |
seg["attribution_weight"] = gt.get("top_attribution_weight")
|
| 749 |
seg["src_features"] = gt.get("src_features")
|
| 750 |
seg["tgt_features"] = gt.get("tgt_features")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 751 |
if op:
|
| 752 |
cc = op.get("contextcite") or {}
|
| 753 |
seg["cc_lds"] = cc.get("lds")
|
|
@@ -763,11 +796,12 @@ def _segment_tagged(tagged: str, rat_by_key: Dict, op_by_key: Dict) -> List[Dict
|
|
| 763 |
"passage": (ts.get("passage") or ts.get("text") or "")[:200],
|
| 764 |
})
|
| 765 |
seg["ranked_sources"] = ranked
|
|
|
|
| 766 |
if "source_label" not in seg and ranked:
|
| 767 |
seg["source_short"] = ranked[0]["source"]
|
| 768 |
seg["source_passage"] = ranked[0]["passage"]
|
| 769 |
-
|
| 770 |
-
|
| 771 |
segments.append(seg)
|
| 772 |
last = m.end()
|
| 773 |
if last < len(tagged):
|
|
|
|
| 56 |
return ""
|
| 57 |
|
| 58 |
|
| 59 |
+
# Lexical-familiarity metrics: unlike FKGL (syllable-based, blind to jargon),
|
| 60 |
+
# these reward replacing rare technical words with common everyday ones.
|
| 61 |
+
def _lexical(text: str) -> Dict[str, Any]:
|
| 62 |
+
out: Dict[str, Any] = {"dale_chall": None, "jargon_rate": None, "zipf_mean": None}
|
| 63 |
+
t = (text or "").strip()
|
| 64 |
+
if not t:
|
| 65 |
+
return out
|
| 66 |
+
try:
|
| 67 |
+
import textstat as _ts
|
| 68 |
+
out["dale_chall"] = round(_ts.dale_chall_readability_score(t), 2)
|
| 69 |
+
except Exception:
|
| 70 |
+
pass
|
| 71 |
+
try:
|
| 72 |
+
from wordfreq import zipf_frequency as _zf
|
| 73 |
+
words = re.findall(r"[A-Za-z]+", t.lower())
|
| 74 |
+
if words:
|
| 75 |
+
zs = [_zf(w, "en") for w in words]
|
| 76 |
+
out["zipf_mean"] = round(sum(zs) / len(zs), 2)
|
| 77 |
+
out["jargon_rate"] = round(sum(1 for z in zs if z < 3.0) / len(words), 4)
|
| 78 |
+
except Exception:
|
| 79 |
+
pass
|
| 80 |
+
return out
|
| 81 |
+
|
| 82 |
+
|
| 83 |
# --------------------------------------------------------------------------
|
| 84 |
# Configuration knobs (overridable via environment before first import).
|
| 85 |
# Mirrors run_local.py's CONFIG block.
|
|
|
|
| 604 |
m.update(cs)
|
| 605 |
except Exception:
|
| 606 |
pass
|
| 607 |
+
# lexical familiarity (captures jargon removal FKGL is blind to)
|
| 608 |
+
m.update(_lexical(sys_out))
|
| 609 |
# reference-based edit/replacement F1 (benchmark mode only)
|
| 610 |
if refs:
|
| 611 |
try:
|
|
|
|
| 774 |
seg["attribution_weight"] = gt.get("top_attribution_weight")
|
| 775 |
seg["src_features"] = gt.get("src_features")
|
| 776 |
seg["tgt_features"] = gt.get("tgt_features")
|
| 777 |
+
# The rationale's source_label is "source (term)" from pick_top_source
|
| 778 |
+
# (the edit's ACTUAL glossary source) — use its term, not ContextCite's
|
| 779 |
+
# noisy top-ranked one, so the tooltip source matches the edit.
|
| 780 |
+
_lbl = gt.get("source_label") or ""
|
| 781 |
+
_mt = re.search(r"\((.*)\)\s*$", _lbl)
|
| 782 |
+
if _mt:
|
| 783 |
+
seg["source_term"] = _mt.group(1).strip()
|
| 784 |
if op:
|
| 785 |
cc = op.get("contextcite") or {}
|
| 786 |
seg["cc_lds"] = cc.get("lds")
|
|
|
|
| 796 |
"passage": (ts.get("passage") or ts.get("text") or "")[:200],
|
| 797 |
})
|
| 798 |
seg["ranked_sources"] = ranked
|
| 799 |
+
# Only fall back to ContextCite's source if the rationale gave none.
|
| 800 |
if "source_label" not in seg and ranked:
|
| 801 |
seg["source_short"] = ranked[0]["source"]
|
| 802 |
seg["source_passage"] = ranked[0]["passage"]
|
| 803 |
+
if not seg.get("source_term"):
|
| 804 |
+
seg["source_term"] = ranked[0]["term"]
|
| 805 |
segments.append(seg)
|
| 806 |
last = m.end()
|
| 807 |
if last < len(tagged):
|
static/app.js
CHANGED
|
@@ -300,6 +300,9 @@
|
|
| 300 |
{ key: "fre", label: "Reading ease (FRE)", desc: "0-100 scale", aim: "higher is easier, aim above 60", better: "higher", fmt: n1 },
|
| 301 |
{ key: "smog", label: "SMOG index", desc: "health-literacy grade", aim: "lower is better", better: "lower", fmt: n1 },
|
| 302 |
{ key: "coleman_liau", label: "Coleman-Liau", desc: "character-based grade", aim: "lower is better", better: "lower", fmt: n1 },
|
|
|
|
|
|
|
|
|
|
| 303 |
{ key: "mepr", label: "Entity preservation", desc: "medical facts kept (MEPR)", aim: "higher is better, keep the facts", better: "higher", fmt: pct, bar01: true },
|
| 304 |
{ key: "nli_faith", label: "NLI faithfulness", desc: "no hallucination vs input", aim: "higher is better, no made-up facts", better: "higher", fmt: pct, bar01: true },
|
| 305 |
{ key: "critical_error", label: "Critical safety error", desc: "lost negation / number / side", aim: "lower is better, 0 is safe", better: "lower", fmt: pct },
|
|
|
|
| 300 |
{ key: "fre", label: "Reading ease (FRE)", desc: "0-100 scale", aim: "higher is easier, aim above 60", better: "higher", fmt: n1 },
|
| 301 |
{ key: "smog", label: "SMOG index", desc: "health-literacy grade", aim: "lower is better", better: "lower", fmt: n1 },
|
| 302 |
{ key: "coleman_liau", label: "Coleman-Liau", desc: "character-based grade", aim: "lower is better", better: "lower", fmt: n1 },
|
| 303 |
+
{ key: "dale_chall", label: "Dale-Chall grade", desc: "word-familiarity readability (jargon-sensitive)", aim: "lower is better, aim for grade 6", better: "lower", fmt: n1 },
|
| 304 |
+
{ key: "jargon_rate", label: "Jargon words", desc: "share of rare/technical words", aim: "lower is better, 0 = none left", better: "lower", fmt: pct, bar01: true },
|
| 305 |
+
{ key: "zipf_mean", label: "Word familiarity", desc: "average word commonness (Zipf)", aim: "higher is better, everyday words", better: "higher", fmt: n1 },
|
| 306 |
{ key: "mepr", label: "Entity preservation", desc: "medical facts kept (MEPR)", aim: "higher is better, keep the facts", better: "higher", fmt: pct, bar01: true },
|
| 307 |
{ key: "nli_faith", label: "NLI faithfulness", desc: "no hallucination vs input", aim: "higher is better, no made-up facts", better: "higher", fmt: pct, bar01: true },
|
| 308 |
{ key: "critical_error", label: "Critical safety error", desc: "lost negation / number / side", aim: "lower is better, 0 is safe", better: "lower", fmt: pct },
|