요약 항목도 같은 서식으로 준비한다. 정답셋이 없어 수치는 채울 수 없으므로
서식과 시현 절차만 확정하고, 결과 자리는 자리표시자로 둔다.
eval_rouge.py: 성적서 '4. 결과' 형식 JSON 출력(--out 으로 저장). 보고 대상이
ROUGE-1 recall 임을 reported_metric 으로 명시한다. 계획서 수식 분모가 참조
n-gram 수인데 전 차수 코드는 f1 을 반환해 정의가 어긋나 있었다.
show_summary_samples.py: 전 차수 '1. 데이터 준비' 의 {index, original} 형식
출력. 정답셋이 없으면 그 사실과 참조 문서를 알리고 종료한다.
시험방법 수정 두 곳 — 1,000건에서 300건으로(사람 작성 정답이 필요해 1,000건은
구축 비용 과다), 지표를 ROUGE-1 recall 로 명시.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
96 lines
3.6 KiB
Python
96 lines
3.6 KiB
Python
"""성능지표 #7 요약 정답셋 예시를 성적서 형식으로 출력한다.
|
|
|
|
전 차수 성적서(GERI `GERIR.CE.2511-02.009`) 3.2.3.3 "1. 데이터 준비" 는
|
|
원문을 `{index, original}` 형태로 앞뒤 몇 건만 싣고 중간을 `...` 로 생략한 뒤
|
|
총 건수를 적는다. 그 형식으로 낸다.
|
|
|
|
입력은 `scripts/eval_rouge.py` 와 같은 JSONL 이다.
|
|
{"text": "원문 ...", "reference": "사람 작성 요약 ..."}
|
|
{"text": "원문 ...", "references": ["정답 1 ...", "정답 2 ..."]}
|
|
|
|
`--with-reference` 를 주면 정답 요약도 함께 싣는다.
|
|
|
|
사용:
|
|
python scripts/show_summary_samples.py data/eval/summary.jsonl
|
|
python scripts/show_summary_samples.py data/eval/summary.jsonl --head 2 --tail 2
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import json
|
|
from pathlib import Path
|
|
|
|
|
|
def record(index: int, row: dict, max_chars: int | None,
|
|
with_reference: bool) -> list[str]:
|
|
def clean(value: str) -> str:
|
|
body = " ".join(value.split())
|
|
if max_chars and len(body) > max_chars:
|
|
body = body[:max_chars] + " …"
|
|
return body
|
|
|
|
lines = [" {", ' "index": %d,' % index,
|
|
' "original": "%s",' % clean(row.get("text", ""))]
|
|
if with_reference:
|
|
raw = row.get("references") or row.get("reference", "")
|
|
references = [raw] if isinstance(raw, str) else list(raw)
|
|
if len(references) == 1:
|
|
lines.append(' "reference": "%s",' % clean(references[0]))
|
|
else:
|
|
lines.append(' "references": [')
|
|
for n, reference in enumerate(references):
|
|
comma = "," if n < len(references) - 1 else ""
|
|
lines.append(' "%s"%s' % (clean(reference), comma))
|
|
lines.append(" ],")
|
|
lines.append(" },")
|
|
return lines
|
|
|
|
|
|
def main() -> int:
|
|
parser = argparse.ArgumentParser(description=__doc__)
|
|
parser.add_argument("dataset", type=Path, help="JSONL 정답셋")
|
|
parser.add_argument("--head", type=int, default=2, help="앞에서 N건")
|
|
parser.add_argument("--tail", type=int, default=2, help="뒤에서 N건")
|
|
parser.add_argument("--max-chars", type=int, default=None,
|
|
help="본문 길이 제한 (미지정 시 전문)")
|
|
parser.add_argument("--with-reference", action="store_true",
|
|
help="정답 요약도 함께 출력")
|
|
parser.add_argument("--out", help="파일로 저장")
|
|
args = parser.parse_args()
|
|
|
|
if not args.dataset.exists():
|
|
raise SystemExit(
|
|
"정답셋이 없습니다: %s\n"
|
|
"성능지표 #7 은 요약 정답셋 구축 후 측정 가능하다. "
|
|
"docs/TEST_PLAN_2026_PHASE2.md 부록 E 참조." % args.dataset)
|
|
|
|
rows = [json.loads(line) for line
|
|
in args.dataset.read_text(encoding="utf-8").splitlines() if line.strip()]
|
|
total = len(rows)
|
|
|
|
indices = list(range(min(args.head, total)))
|
|
tail_start = max(len(indices), total - args.tail)
|
|
indices += list(range(tail_start, total))
|
|
|
|
lines = ["1. 데이터 준비"]
|
|
previous = -1
|
|
for i in indices:
|
|
if previous >= 0 and i != previous + 1:
|
|
lines.append("...")
|
|
lines.extend(record(i + 1, rows[i], args.max_chars, args.with_reference))
|
|
previous = i
|
|
lines.append("")
|
|
lines.append("총 데이터 %d건" % total)
|
|
|
|
text = "\n".join(lines)
|
|
if args.out:
|
|
Path(args.out).write_text(text + "\n", encoding="utf-8")
|
|
print("%s 에 기록" % args.out)
|
|
else:
|
|
print(text)
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|