o2o-plagiarism-ai/tests/test_case_coverage.py
hbyang 0472ae1f8a 2단계 고도화 선행 작업: 군집화·요약·평가환경·데이터 스펙 (데이터 수령 전)
컴북스 데이터 수령 전 가능한 작업을 선행 구현. 데이터 도착 즉시
학습·검증에 착수할 수 있도록 알고리즘·평가 하니스·문서를 준비.

알고리즘/파이프라인:
- engine/clustering.py: 군집화 기반 부분 표절(요소 교체) 판별,
  detect 응답에 partial_signal 필드 노출 (계획서 2단계 표절검출 고도화)
- engine/summarizer.py + POST /v1/summary: TextRank 추출적 요약 +
  통합(LLM) 골격 (과제2 ② 스토리 요약/분석)
- engine/preference.py + scripts/build_preference_dataset.py:
  Human Feedback 선호학습(DPO) 데이터 파이프라인 골격

평가 하니스 (정답셋 도착 즉시 측정):
- engine/rouge.py + scripts/eval_rouge.py: 요약 ROUGE (지표 No.7)
- engine/metadata_eval.py + scripts/eval_metadata_f1.py: 메타 추출 F1
  (지표 No.3, KLUE NER 호환)
- engine/case_coverage.py + scripts/analyze_case_coverage.py:
  39 케이스 갭 분석 → 컴북스 데이터 요청 목록 (정밀도 97% 근거)

문서:
- docs/DATA_REQUEST_SPEC.md: 요청 데이터 스펙 + 요약 정답셋/HF 라벨 가이드
- docs/INTEGRATION_INTERFACE.md: 2단계 통합 인터페이스
- docs/SW_COPYRIGHT_REGISTRATION.md: SW 저작권 등록 준비
- docs/PHASE2_PROGRESS.md, docs/CASE_COVERAGE.md

테스트 31 → 67건 전부 통과.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 13:16:07 +09:00

44 lines
1.1 KiB
Python

"""39 케이스 커버리지 갭 분석 단위테스트."""
from __future__ import annotations
from dataclasses import dataclass
from app.engine.case_coverage import analyze_coverage
@dataclass
class _Case:
case_id: str
subgroup: str
actor: str
detectable_internal: bool
_CASES = [
_Case("A1", "A-1", "저자(가해)", True),
_Case("A2", "A-1", "저자(가해)", True),
_Case("C1", "C", "플랫폼", False), # 탐지 범위 밖
]
def test_no_data_all_detectable_need_data():
rep = analyze_coverage(_CASES, None)
assert rep["detectable_cases"] == 2
assert rep["need_data_cases"] == 2
assert rep["covered_cases"] == 0
assert rep["coverage_ratio"] == 0.0
def test_with_samples_marks_covered():
rep = analyze_coverage(_CASES, {"A1": 10})
assert rep["covered_cases"] == 1
assert rep["need_data_cases"] == 1
assert rep["coverage_ratio"] == 0.5
def test_out_of_scope_excluded_from_request():
rep = analyze_coverage(_CASES, {"A1": 5, "A2": 5})
ids = {x["case_id"] for x in rep["data_request_list"]}
assert "C1" not in ids
assert rep["need_data_cases"] == 0