성능지표 #4(표절 판별 정밀도) 를 공인시험에서 재현할 수 있게 시험셋 생성기, 평가 실행기, python 3.9 평가 컨테이너, 시험절차서를 둔다. 시험셋은 작성자 단위로 코퍼스를 나눠 만든다. 비표절 시료를 참조 코퍼스에서 뽑으면 인덱스가 자기 자신을 찾아 전부 오탐이 되므로, 인덱스에 없는 작성자의 글만 쓴다. 무관한 글만 넣으면 정밀도가 부풀려져 주제 근접 시료 150건을 따로 섞는다. 실제 오탐이 나는 유형이 그것이다. 대필(인칭 전환)은 제외한다. 원문이 그대로 남지만 표절 여부가 계약·동의로 갈려 텍스트만으로 판정할 수 없다. 자체 측정 결과 정밀도 0.9840 (TP=493 FP=8 TN=492 FN=7). 목표 0.97 을 넘고, 오탐 8건 중 7건이 주제 근접 시료에서 나와 난이도가 운영 조건을 반영한다. 시험셋에는 자서전 원문이 들어가므로 저장소에 두지 않는다. 시드가 manifest 에 고정돼 있어 생성기로 동일하게 재생성된다. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
157 lines
6.7 KiB
Markdown
157 lines
6.7 KiB
Markdown
# 성능지표 #4 정밀도 시험 절차서
|
|
|
|
> 표절 여부 판별 정밀도(precision). 계획서 p.23 성능지표 4번.
|
|
> 2-1년차 목표 **97%**. 1-2년차(2025-11-19, GERI `GERIR.CE.2511-02.009`)에서
|
|
> 95% 목표를 95.2% 로 통과한 항목의 후속 시험.
|
|
|
|
## 0. 시험 당일 준비 (전날까지 끝낼 것)
|
|
|
|
```bash
|
|
cd /mnt/data2/demo/o2o-plagiarism-ai # 시험 서버 기준
|
|
git pull # 최신 판정 규칙 반영
|
|
docker build -f Dockerfile.eval -t o2o-plagia-eval:py39 .
|
|
```
|
|
|
|
평가환경은 계획서가 **Ubuntu 22.04 / python 3.9 / GPU 불필요** 로 못박아 두었다.
|
|
서버 시스템 파이썬은 3.6.9 이므로 **반드시 컨테이너로 실행한다.**
|
|
|
|
준비물 확인:
|
|
|
|
| 항목 | 경로 | 확인 |
|
|
|---|---|---|
|
|
| 시험셋 | `data/eval/testset_v2/pairs.jsonl` | 1,000줄 |
|
|
| 참조 코퍼스 | `data/eval/testset_v2/index.jsonl` | 4,033줄 |
|
|
| 구성 명세 | `data/eval/testset_v2/manifest.json` | 시드·비율 기록 |
|
|
| 평가 스크립트 | `scripts/run_precision_eval.py` | — |
|
|
|
|
```bash
|
|
wc -l data/eval/testset_v2/pairs.jsonl data/eval/testset_v2/index.jsonl
|
|
cat data/eval/testset_v2/manifest.json
|
|
```
|
|
|
|
## 1. 시험 데이터 설명 (시험관에게 먼저 보여줄 것)
|
|
|
|
GERI 시험방법 ① "모델이 학습하지 않은, 자체 제작된 표절 글 데이터" 요건을
|
|
작성자 단위 분리로 충족한다.
|
|
|
|
```
|
|
전체 작성자 290명
|
|
├─ 203명 → 참조 코퍼스(인덱스)에 적재
|
|
└─ 87명 → 시험 질의로만 사용 (인덱스에 없음)
|
|
```
|
|
|
|
| 라벨 | 건수 | 구성 |
|
|
|---|---|---|
|
|
| 표절 | 500 | 참조 코퍼스의 글을 변형. verbatim 100 / partial 100 / sentence_shuffle 100 / lexical_swap 150 / compress 50 |
|
|
| 비표절 | 500 | 인덱스에 없는 작성자의 글 원문. **하드 네거티브 150** + 일반 350 |
|
|
|
|
**하드 네거티브**는 참조 코퍼스와 어휘가 많이 겹치는 글을 골라 넣었다. 실제
|
|
오탐이 나는 유형이기 때문이다(현장 검토에서 오탐 판정된 31건이 이 유형이었다).
|
|
|
|
**대필(인칭 전환)은 시험셋에서 제외**했다. 같은 사건을 당사자와 대필자가 각각
|
|
기술한 글은 원문이 그대로 남지만, 표절 여부는 계약·동의로 갈려 텍스트만으로
|
|
판정할 수 없다. 판정 기준이 서면 별도 유형으로 추가한다.
|
|
|
|
재현성: `manifest.json` 에 난수 시드(20260908)와 비율이 기록돼 있어 같은
|
|
시험셋을 다시 만들 수 있다.
|
|
|
|
```bash
|
|
# 시험관 요청 시 시험셋 재생성 시연
|
|
python scripts/build_plagiarism_testset.py \
|
|
--excerpts-jsonl reports/excerpts_20260902.jsonl \
|
|
--hash-map <hash_map.json> \
|
|
--out-dir /tmp/testset_reproduce
|
|
diff <(cut -c1-80 /tmp/testset_reproduce/pairs.jsonl) \
|
|
<(cut -c1-80 data/eval/testset_v2/pairs.jsonl) && echo "동일"
|
|
```
|
|
|
|
## 2. 판정 기준 설명
|
|
|
|
세 조건 중 **①과 ②를 함께** 요구한다. `require_exact_span_evidence=true`.
|
|
|
|
| 조건 | 기준값 | 설정 키 |
|
|
|---|---|---|
|
|
| ① 결합유사도 | ≥ 0.65 | `persistent_similarity_threshold` |
|
|
| ② **최장 연속 일치** | **≥ 35자 (9어절)** | `persistent_min_exact_span` |
|
|
| ③ 문서 커버리지 | ≥ 0.30 | `persistent_min_coverage` |
|
|
|
|
②는 필수다. 유사도만 높고 그대로 겹친 구간이 없는 후보는 채택하지 않는다.
|
|
같은 주제를 다룬 글은 임베딩 유사도가 함께 오르기 때문이다.
|
|
|
|
35자의 근거는 실측이다. 어절 3~9 스윕과 문서쌍 148,240 쌍 전수 대조 결과,
|
|
4어절 이하는 임의 조합의 99% 이상이 겹쳐 신호가 되지 못하고, 9어절부터 남는
|
|
겹침은 실제 유사 원고였다. 상세는 결과보고 워크북 `어절 기준 비교` 시트.
|
|
|
|
```bash
|
|
# 기준값 확인 시연
|
|
python -c "from app.core.config import Settings; s=Settings(); \
|
|
print(s.persistent_similarity_threshold, s.persistent_min_exact_span, \
|
|
s.persistent_min_coverage, s.require_exact_span_evidence)"
|
|
```
|
|
|
|
## 3. 평가 실행 — 이 한 줄
|
|
|
|
```bash
|
|
docker run --rm -v $PWD:/app -w /app o2o-plagia-eval:py39 \
|
|
python scripts/run_precision_eval.py --testset data/eval/testset_v2
|
|
```
|
|
|
|
소요 약 10분(1,000건). 진행률이 100건 단위로 출력된다.
|
|
|
|
출력 형식:
|
|
|
|
```
|
|
시험 코퍼스: 문서 203개 / 세그먼트 4033개
|
|
시험 인덱스 구축 완료: data/eval/testset_v2/runtime/index
|
|
판정 기준: 유사도>=0.65 | 연속일치>=35자 | 커버리지>=0.30 | 연속일치 필수=True
|
|
진행 1000/1000
|
|
|
|
==============================================================
|
|
표절 여부 판별 정밀도 (precision) : 0.9xxx [목표 0.97]
|
|
재현율 (recall) : 0.9xxx
|
|
F1 : 0.9xxx
|
|
TP=xxx FP=xx TN=xxx FN=xx
|
|
|
|
[변형 유형별]
|
|
verbatim n= 100 P=x.xxx R=x.xxx TP=.. FP=.. TN=.. FN=..
|
|
...
|
|
```
|
|
|
|
정밀도 = TP / (TP + FP). 목표 0.97 이면 예측 양성 500건 기준 **오탐 15건까지**
|
|
허용된다.
|
|
|
|
결과는 `data/eval/testset_v2/result.json` 에 기록된다. 성적서 첨부용으로 쓴다.
|
|
|
|
## 4. 시험관이 물을 만한 것
|
|
|
|
**"시험셋을 직접 만들었으면 유리하게 만든 것 아닌가"**
|
|
→ 구성 비율·시드가 `manifest.json` 에 사전 기록돼 있고 재생성으로 동일 결과가
|
|
나온다. 하드 네거티브 150건을 일부러 섞어 난이도를 높였다.
|
|
|
|
**"변형이 원문과 얼마나 다른가"**
|
|
→ 문자 일치율과 최장 연속 일치를 유형별로 계측해 두었다. `lexical_swap` 은
|
|
어절의 35% 를 실제로 치환해 최장 연속 일치가 48자 수준이다(판정 기준 35자).
|
|
|
|
**"연속 일치를 필수로 하면 재현율이 떨어지지 않나"**
|
|
→ 실데이터 7,680건 재판정 결과 새로 놓치는 건은 0건이었다. 정밀도 지표이므로
|
|
계획서도 "재현율을 희생해서라도 오탐을 줄이는 쪽" 으로 잡도록 적고 있다
|
|
(`docs/SCOPE_AND_METRICS.md`).
|
|
|
|
**"원문이 외부로 나가는가"**
|
|
→ 나가지 않는다. `USE_LLM_LEGAL_JUDGE=false`, 시험셋 변형도 전부 규칙 기반이며
|
|
외부 API 를 쓰지 않는다.
|
|
|
|
## 5. 성적서 게재용 예시
|
|
|
|
성적서에는 시험 데이터 원문 예시가 인쇄된다(작년 성적서 9페이지 참조).
|
|
자서전은 본문에 실명이 남아 있으므로, **게재 예시는 익명화가 끝난 생활수기에서
|
|
뽑아 제출한다.** 접수 시 시험기관에 함께 요청할 것.
|
|
|
|
## 6. 실패 시 대응
|
|
|
|
| 증상 | 조치 |
|
|
|---|---|
|
|
| 정밀도 < 0.97 | `result.json` 의 `by_transformation` 에서 FP 가 몰린 유형 확인. 하드 네거티브에서 나오면 `persistent_min_exact_span` 을 40~45자로 올려 재실행 |
|
|
| 인덱스 구축 실패 | `data/eval/testset_v2/runtime` 삭제 후 재실행 |
|
|
| 재현율 급락 | 기준을 과하게 올린 것. 35자로 되돌리고 유사도 임계값만 조정 |
|