태스크별 평가 치트시트 — 어떤 지표를 써야 하는지 한눈에
분류→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점 | (커스텀) |
핵심 개념
분류 → load(\"accuracy\"), load(\"f1\")
번역/요약 → load(\"bleu\"), load(\"rouge\")
OCR/STT → load(\"cer\"), load(\"wer\")
의미 유사도 → load(\"bertscore\")
음원 분리 → mir_eval.separation.bss_eval_sources()