"""저장된 1,000건 재채점 — 문자 2-gram recall (계획서 p.24 수식). API 재호출 없음. H절 재평가 산출물의 참조·출력 원문을 그대로 사용하고 집계 지표만 F1 에서 recall 로 바꾼다. 새 독립 시험이 아니다. """ from __future__ import annotations import argparse import json from pathlib import Path import sys sys.path.insert(0, str(Path(__file__).resolve().parents[1])) from scripts.build_summary_trial import metrics TARGET = 0.65 def main() -> None: ap = argparse.ArgumentParser(description=__doc__) ap.add_argument("--source", type=Path, default=Path("data/eval/summary_word_refined_20260917/scorecard.json")) ap.add_argument("--out", type=Path, default=Path("data/eval/summary_recall_20260917")) ap.add_argument("--excerpt", type=int, default=160, help="캡처본 원문 발췌 길이") args = ap.parse_args() args.out.mkdir(parents=True, exist_ok=True) rows = json.loads(args.source.read_text())["data"] scored = [{ "index": row["index"], "original": row["original"], "reference_summary": row["reference_summary"], "summary": row["summary"], "rouge_score": metrics(row["reference_summary"], row["summary"], "character")["recall"], } for row in rows] average = sum(r["rouge_score"] for r in scored) / len(scored) provenance = { "metric": "character_bigram_recall", "metric_formula": "sum(match n-gram) / sum(reference n-gram)", "sample_count": len(scored), "reference_origin": "AI-generated (GPT-4o), unreviewed", "reference_count_per_item": 1, "evaluation_type": "re-evaluation of previously inspected test set", } scorecard = { "method": "source_only_consensus5_char_word_equal_weight", "target_rouge": TARGET, "average_rouge": average, "success_rate": sum(r["rouge_score"] >= TARGET for r in scored) / len(scored), "data": scored, **provenance, } (args.out / "scorecard.json").write_text( json.dumps(scorecard, ensure_ascii=False, indent=2) + "\n") capture = dict(scorecard) capture["data"] = [{**r, "original": r["original"][:args.excerpt] + " …"} for r in scored[:3]] (args.out / "capture.json").write_text( json.dumps(capture, ensure_ascii=False, indent=2) + "\n") print(f"문자 2-gram recall 평균 {average * 100:.2f}% " f"(목표 {TARGET * 100:.0f}%, {len(scored)}건)") print(f"success_rate {scorecard['success_rate'] * 100:.1f}%") if __name__ == "__main__": main()