LLM Day 16 - RAG (Retrieval-Augmented Generation) 시스템의 정량적 평가 지표

Soyee Sung·2025년 2월 26일
0

LLM

목록 보기
20/34

🔍 학습 목표:

Retrieval-Augmented Generation (RAG) 시스템의 정량적 평가 지표를 이해하고, 실제 데이터를 분석하여 성능을 측정하는 방법을 학습합니다.

1️⃣ RAG란 무엇인가?

📌 RAG (Retrieval-Augmented Generation) 개념
Retrieval (검색): 외부 데이터베이스나 문서에서 관련 정보를 검색
Generation (생성): 검색된 정보를 활용하여 사용자 질문에 대한 답변 생성
단순한 GPT 모델보다 더 정확하고 신뢰할 수 있는 응답을 생성할 수 있음

2️⃣ RAG 답변 평가 (Evaluation Metrics)

RAG 모델의 성능을 평가하기 위해, 검색 평가와 생성 평가를 수행합니다.

📌 1) 검색(Retrieval) 평가

검색된 문서가 얼마나 정확하고 관련성이 높은가?를 평가하는 지표입니다.

✅ Non-Rank Based Metrics (순위 미반영)

Accuracy: 검색된 문서 중에서 정답 문서가 포함된 비율
Precision@k: 검색된 문서 중에서 실제 정답 문서가 포함된 비율

Recall@k: 전체 정답 문서 중 몇 개가 검색되었는지 평가

✅ Rank-Based Metrics (순위 반영)

MRR (Mean Reciprocal Rank): 정답 문서가 몇 번째로 검색되었는지 평가

MAP (Mean Average Precision): 검색 결과의 순위를 고려하여 평균 Precision을 측정

✅ RAG 특화 지표

기존 검색 평가 방식의 한계를 보완하기 위해, LLM-as-Judge 방식 도입
GPT 같은 LLM을 활용하여 검색된 문서의 정확도, 관련성, 다양성, 강건성을 평가
📌 2) 생성(Generation) 평가
모델이 생성한 응답이 얼마나 정확하고 자연스러운가?를 평가하는 지표입니다.

✅ 전통적 평가 지표

ROUGE (요약 평가): 생성된 문장과 정답 문장 간의 단어 일치율을 기반으로 평가
BLEU (번역 평가): 생성된 텍스트와 참조 텍스트의 n-gram 일치율을 평가
BERTScore (의미 유사도 평가): BERT 모델을 활용해 생성된 문장과 참조 문장의 의미적 유사도를 계산

✅ LLM 기반 평가

응집성(Cohesion): 문장 간 논리적인 연결성이 높은가?
관련성(Relevance): 사용자 질문과 직접 관련 있는 응답을 생성했는가?
유창성(Fluency): 문법적으로 자연스럽고 읽기 쉬운가?
사실성(Factuality): 생성된 답변이 실제 문서에 기반하고 있는가?

✅ 다차원 평가 방식

품질(Quality), 일관성(Consistency), 사실성(Factuality), 가독성(Readability), 사용자 만족도(User Satisfaction) 등을 통합적으로 측정
상세한 프롬프트를 통해 모델이 사용자 선호도에 맞는 응답을 생성했는지 평가

3️⃣ RAG 평가 실습

Jupyter Notebook을 활용하여 RAG 모델의 성능을 측정합니다.

📌 1) 데이터 확인

업로드된 평가 데이터 (evaluation_result.csv)를 분석하여, 어떤 지표들이 포함되어 있는지 확인합니다.

import pandas as pd

# 데이터 로드
ragas_evaluation = pd.read_csv("/mnt/data/evaluation_result.csv")

# 데이터 미리보기
ragas_evaluation.head()

📌 포함된 평가 지표

context_recall → 검색된 문서가 실제 정답 문서를 포함했는지
faithfulness → 생성된 응답이 검색된 문서 내용과 얼마나 일치하는지
factual_correctness → 생성된 응답이 사실적으로 올바른지

📌 2) 검색 성능 평가 (Retrieval Metrics 계산)

def precision_at_k(retrieved_docs, relevant_docs, k):
    retrieved_k = retrieved_docs[:k]
    num_relevant = sum([1 for doc in retrieved_k if doc in relevant_docs])
    return num_relevant / k

def recall_at_k(retrieved_docs, relevant_docs, k):
    retrieved_k = retrieved_docs[:k]
    num_relevant = sum([1 for doc in retrieved_k if doc in relevant_docs])
    return num_relevant / len(relevant_docs)

Precision@k와 Recall@k를 사용해 검색된 문서가 얼마나 정확한지 평가합니다

📌 3) 생성 성능 평가 (Generation Metrics 계산)

from rouge import Rouge
from nltk.translate.bleu_score import sentence_bleu
from bert_score import score

# ROUGE 평가
def rouge_score(generated_text, reference_text):
    rouge = Rouge()
    scores = rouge.get_scores(generated_text, reference_text)
    return scores[0]

# BLEU 평가
def bleu_score(generated_text, reference_text):
    reference = [reference_text.split()]
    candidate = generated_text.split()
    return sentence_bleu(reference, candidate)

# BERTScore 평가
def bert_score(generated_text, reference_text):
    P, R, F1 = score([generated_text], [reference_text], lang="en")
    return {"Precision": P.mean().item(), "Recall": R.mean().item(), "F1": F1.mean().item()}

ROUGE, BLEU, BERTScore를 활용해 생성된 응답이 얼마나 정답과 유사한지 평가합니다.

📌 4) 평균 성능 분석 및 시각화

import matplotlib.pyplot as plt

# 평균값 계산
avg_recall = ragas_evaluation["context_recall"].mean()
avg_faithfulness = ragas_evaluation["faithfulness"].mean()
avg_factual_correctness = ragas_evaluation["factual_correctness"].mean()

# 그래프 시각화
metrics = ["Context Recall", "Faithfulness", "Factual Correctness"]
values = [avg_recall, avg_faithfulness, avg_factual_correctness]

plt.figure(figsize=(8, 5))
plt.bar(metrics, values)
plt.ylim(0, 1)
plt.title("RAG 평가 지표 평균값")
plt.ylabel("Score")
plt.show()

📊 결과 해석

Context Recall이 낮다면? → 검색된 문서가 올바른 정답을 포함하지 못함
Faithfulness가 낮다면? → 생성된 응답이 검색된 문서와 다름
Factual Correctness가 낮다면? → 생성된 응답이 사실적으로 틀림

4️⃣ 정리: RAG 평가의 핵심 포인트

✅ 검색 평가: Precision@k, Recall@k, MRR, MAP, LLM-as-Judge
✅ 생성 평가: ROUGE, BLEU, BERTScore, LLM 기반 평가 (유창성, 관련성, 사실성)
✅ 데이터 분석: 실제 평가 결과를 통해 검색 및 생성 성능을 측정하고 시각화
✅ 개선 방향: 검색 성능이 낮다면 문서 검색 모델 개선, 생성 성능이 낮다면 응답 생성 모델 개선

0개의 댓글