📋

태스크별 평가 치트시트 — 어떤 지표를 써야 하는지 한눈에

분류→Accuracy/F1, 생성→BLEU/ROUGE, OCR→CER/WER, 분리→SDR — 코드 포함

전부 pip install evaluate로 설치. 코드 3줄.

분류 (감정 분석, 이미지 분류, 스팸 필터 등)

from evaluate import load

# Accuracy — 맞은 비율
metric = load("accuracy")
result = metric.compute(predictions=[1,0,1,1], references=[1,0,0,1])
# → {'accuracy': 0.75}

# F1 — 불균형 데이터에서 더 정확
metric = load("f1")
result = metric.compute(predictions=[1,0,1,1], references=[1,0,0,1], average="binary")
# → {'f1': 0.80}

언제 뭘 쓰나:

  • 데이터가 균형적 (긍정 50%, 부정 50%) → Accuracy면 충분

  • 데이터가 불균형 (스팸 5%, 정상 95%) → F1 필수

번역

metric = load("bleu")
result = metric.compute(
    predictions=["The cat is on the mat"],
    references=[["The cat sat on the mat"]]
)
# → {'bleu': 0.61}  (0~1, 높을수록 좋음)

BLEU는 n-gram(연속 단어 조합) 겹침을 측정한다. "The cat" "cat is" "is on" 같은 2-gram이 정답에 얼마나 있는지.

요약

metric = load("rouge")
result = metric.compute(
    predictions=["The cat sat on a mat"],
    references=["The cat sat on the mat in the room"]
)
# → {'rouge1': 0.86, 'rouge2': 0.71, 'rougeL': 0.86}

ROUGE는 BLEU의 반대 방향 — 정답의 n-gram이 생성 결과에 얼마나 포함되었는지.

  • BLEU: "생성 결과가 정답과 비슷한가?" (정밀도 관점)

  • ROUGE: "정답의 내용이 생성에 포함되었는가?" (재현율 관점)

OCR / 음성 인식(STT)

# CER — 글자 단위 오류율
metric = load("cer")
result = metric.compute(
    predictions=["賃料は月額150,000円とすろ"],  # ろ가 오류
    references=["賃料は月額150,000円とする"]
)
# → 0.0588  (5.88% 오류, 17글자 중 1글자)

# WER — 단어 단위 오류율
metric = load("wer")
result = metric.compute(
    predictions=["hello how are you"],
    references=["hello how old are you"]
)
# → 0.20  (20% 오류, 5단어 중 1단어)

CER vs WER:

  • 일본어/중국어(띄어쓰기 없음) → CER

  • 영어/한국어(띄어쓰기 있음) → WER 또는 CER 둘 다

음원 분리

import mir_eval
import numpy as np

reference = np.random.randn(44100)  # 원본 보컬
estimated = reference + 0.1 * np.random.randn(44100)  # 분리 결과

sdr, _, _, _ = mir_eval.separation.bss_eval_sources(
    reference[np.newaxis, :], estimated[np.newaxis, :]
)
# → SDR: 20.0 dB (높을수록 좋음, 10+ dB가 양호)

텍스트 유사도 (의미 기반)

metric = load("bertscore")
result = metric.compute(
    predictions=["The weather is nice today"],
    references=["It's a beautiful day"],
    lang="en"
)
# → {'f1': [0.92]}  (단어가 다르지만 의미가 비슷 → 높은 점수)

BLEU는 단어 겹침만 본다. BERTScore는 의미적 유사도를 본다. "날씨가 좋다"와 "화창한 날이다"는 BLEU는 낮지만 BERTScore는 높다.

LLM 출력 평가 (정답이 없는 경우)

LLM 생성 결과는 "정답"이 여러 개일 수 있다. 이때:

# 1. LLM-as-Judge — 다른 LLM이 평가
# (GPT-4에게 "이 답변을 1~5점으로 평가해줘")

# 2. Human Evaluation — 사람이 직접 평가
# (가장 정확하지만 비용이 높음)

# 3. Embedding 유사도 — 의미적으로 비슷한지
from sentence_transformers import SentenceTransformer, util
model = SentenceTransformer("all-MiniLM-L6-v2")
sim = util.cos_sim(
    model.encode("AI가 생성한 답변"),
    model.encode("기대하는 답변")
).item()
print(f"유사도: {sim:.2f}")  # 0~1

치트시트

태스크 주 지표 보조 지표 좋은 수준 evaluate
감정 분석 Accuracy F1 85%+ accuracy, f1
번역 BLEU BERTScore 0.3+ bleu, bertscore
요약 ROUGE-L ROUGE-1,2 0.4+ rouge
OCR CER WER 3% 이하 cer, wer
STT WER CER 10% 이하 wer, cer
음원 분리 SDR SIR, SAR 10+ dB mir_eval
텍스트 생성 BERTScore BLEU 0.85+ bertscore
LLM 출력 LLM-Judge Human 4+/5점 (커스텀)

핵심 개념

1

분류 → load(\"accuracy\"), load(\"f1\")

2

번역/요약 → load(\"bleu\"), load(\"rouge\")

3

OCR/STT → load(\"cer\"), load(\"wer\")

4

의미 유사도 → load(\"bertscore\")

5

음원 분리 → mir_eval.separation.bss_eval_sources()

사용 사례

파인튜닝 모니터링 — Trainer의 compute_metrics로 에폭마다 자동 평가 모델 선택 — 같은 데이터로 TrOCR vs EasyOCR vs PaddleOCR의 CER 비교 프로덕션 기준 — \"CER 3% 이하, BLEU 0.4 이상이면 배포\" 같은 품질 게이트