Eat Study Love

먹고 공부하고 사랑하라

Data Science/Research

English Natural Language Evaluation Matrix

eatplaylove 2025. 4. 10. 15:28

영어 문장간의 Word 또는 Semantic(문맥) 을 기준으로 일치성, 통일성, Accuracy를 비교하는 Matrix에 대한 설명이다.

SQL을 NL(Natural Language)로 변환하는 과정에서 NL이 기존 답안 NL과 비교했을 때 얼마나 정확도가 높게 반환되었는지 확인하는 지표로 사용할 수 있다.

 

물론, 프로그래밍언어와 달리 자연어 NL은 해당 지표들의 값이 높다고 무조건 정확하다고 말하기가 어렵다. 언어마다 원체 성질이 다양하다보니...

 

그래서 사실 제일 좋은 건, 특정 언어 Mother tongue 인간의 직접평가가 가장 정확하지만 그것은 현실적으로 Cost가 너무 많이 드릭에 대체재로 아래 MATRIX들을 많이 사용한다.

 

아래 코드 기준으로, 해당 Matrx들의 특징을 알아보자.

# ✅ BARTScorer 설정
bart_scorer = BARTScorer(
    device='cuda' if torch.cuda.is_available() else 'cpu',
    checkpoint='facebook/bart-large-cnn'
)

# ✅ 평가 함수
def evaluate_metrics(generated, reference):
    try:
        # BERTScore Recall
        _, R, _ = bert_score([generated], [reference], lang="en", model_type="bert-base-uncased")

        # ROUGE-L
        rouge = rouge_scorer.RougeScorer(['rougeL'], use_stemmer=True)
        rouge_l = rouge.score(reference, generated)["rougeL"].fmeasure

        # BLEU-4
        ref_tokens = word_tokenize(reference, language='english', preserve_line=True)
        gen_tokens = word_tokenize(generated, language='english', preserve_line=True)
        bleu = sentence_bleu([ref_tokens], gen_tokens, smoothing_function=SmoothingFunction().method1)

        # BARTScore (tokenize 인자 제거)
        bart = bart_scorer.score([generated], [reference])[0]

        return float(R[0]), float(rouge_l), float(bleu), float(bart)

    except Exception as e:
        print("⚠️ 평가 오류:", e)
        return 0.0, 0.0, 0.0, 0.0

 

1. BERTScore(Recall/Precision/F1-Score)

2020 ICLR 논문에서 발표된 것이다. BERT Model의 Contexutal Embedding을 활용해서 문장 간 의미적 유사도를 측정한 것이다. Zhang et al.이 제안했으며 수학적으로 검증이 많이 된 지표다.(Paper:BERTScore: Evaluating Text Generation with BERT)

 

기존의 NL 평가지표인 BLEU와 ROUGE는 n-gram 기법으로, NL간 표면적인 비교밖에 하지 못한다. 즉 두 문장 사이에 동시에 등장하는 단어/토큰에만 의존한다는 것이다.

 

BERTScore는 BERT를 통해 문장의 Contextual Embedding을 얻고 각 token 쌍마다 Cosine 유사도를 구해 평가한 뒤에 Token 별 가중치를 부여하는 방식이다.

다시 순서를 정리하자면,

a) 두 문장을 각 각 BERT에 넣어 Contextualized Embedding을 얻은 다음 layer norm을 진행한다.

b) 위 얻어진 두 Embedding pair에 대해서 Cosine Similarity를 계산한다.

c) 계산된 Similarity Matrix에서 Recall을 계산한다.

d) Matrix를 돌며 Token별로 idf score를 구한다.

※ TF-IDF(Term Frequency-Inverse Document Frequency) : 여러 문서에 등장하는 단어는 점수를 낮게, 적은 문서에만 등장하면 단어의 점수는 높게 측정된다.

이와 유사하게 만든 것이 IDF -> 모든 문장에 등장하는 TOKEN의 중요도는 낮춘다.

e) Token별로 구한 idf를 Recall/Precision 계산에 사용한다.

f) Score가 -1과 1사이로 오도록 rescaling해준다.

 

 

Python에서 BERTScore를 사용할 때 사용되는 Hyper parameter는 아래와 같다.

_, R, _ = bert_score([generated], [reference], lang="en", model_type="bert-base-uncased")

나의 경우 no IDF, no baseline을 설정했고 이것이 default Setting이다. 그리고 Evaluation 중에 내가 관심있는 Recall만을 쓰기 위해서 Output 중에 R값만 택했다.

논문용으로 요약하자면 아래와 같다.

For semantic similarity, we use BERTScore Recall [Zhang et al., 2020], computed with the bert-base-uncased model in English. We follow default hyperparameter settings (rescale_with_baseline=False, use_idf=False) and report only the Recall score to emphasize coverage of reference meaning.

 

그리고, BERTScore의 Recall / Precision / F1 Score비교

종류 정의 의미
Recall 생성문이 본문에 있는 의미를 얼마나 잘 커버 했는가(TP/(TP+FN)) 내용 충실도 중심
Precision 생성문의 내용이 본문 내용과 얼마나 일치하는가(TP/(TP+FP)) 정확성 중심
F1-Score 위 둘의 조화평균 종합적인 유사도

말이 좀 햇갈리는데, 일단 기존 문장의 Semantic을 따지려면 Recall을 보는 것이 맞다. BERTScore 논문에도 아래와 같이 나와있다.

“Recall is often more correlated with human judgments of semantic similarity than Precision.”

 

Recall은 내가 말해야할 내용을 얼마나 담았는가, Precision은 내가 말한 것들이 얼마나 정확한가?

R은 실제 True 중에 내가 True라고 한 것, P는 내가 True라고 말한 것들 중 실제 True인 것

즉, P는 내가 만든 문장 중심으로 이 말이 맞았냐 틀렸냐 -> 내가 만든 문장 중심

R은 내가 만든 문장이 기존 문장의 True를 얼마나 반영하고 있냐 -> 기존 문장 중심

 

2. ROUGE Score (Recall Oriented Understudy for Gisting Evaluation)

Rouge-score는 n-gram Recall이다. 즉 원문 n-gram이 생성문에 얼마나 포함되는지를 체크하는 것

Rouge-L 은 Longest Common Subsequence(LCS)를 기반으로 점수를 계산하기 때문에, 단어싀 순서는 중요하지만 연속성이 강제되지 않는다. 즉 아래 두 문장은 ROUGE-L 기준에선 완전히 일치하는 문장이다.

I have two apples Today I have two delicious apples and bananas
rouge = rouge_scorer.RougeScorer(['rougeL'], use_stemmer=True)
rouge_l = rouge.score(reference, generated)["rougeL"].fmeasure

 

3. BLEU Score (Bilingual Evaluation Understudy)

BLEU도 n-gram 정확도측정방법으로, 표면적인 유사도만을 따진다. Papineni et al., 2002에 제시되었고 논문 "BLEU: a Method for Automatic Evaluation of Machine Translation"에서 해당 내용을 찾아볼 수 있다.

BLEU-4는 최대 4개의 연속된 단어까지 원문과 얼마나 일치하는지를 평가하는 지표이다.

from nltk.translate.bleu_score import sentence_bleu, SmoothingFunction
from nltk.tokenize import word_tokenize

bleu = sentence_bleu(
    [word_tokenize(reference, language='english')],
    word_tokenize(generated, language='english'),
    smoothing_function=SmoothingFunction().method1
)

여기서 Smoothing이란, 아예 matching 되지 않은 경우 점수가 0이 되는 것을 방지하기위해 쓰는 Method다.

보통 BLEU-4 해석은 아래와 같이 따져볼 수 있다.

 

4. BLEU Score (Bilingual Evaluation Understudy)

비교적 최근에 소개된 논문을 참고했다(22 Jun 2021,BARTScore: Evaluating Generated Text as Text Generation).

깃헙 주소는 -> https://github.com/neulab/BARTScore

NL생성 모델의 평가지표로 쓰인다. 요지는, 생성문을 개발자들의 자체 BART - pre-trained embedding 기법을 통해서 원문을 생성할 확률을 log-likelihood를 통해 구한다. 즉, 이 점수가 높을 수록 생성문이 원문과 일치하다는 것이다.

요 친구들도 문장의 Semantic Evaluation에 쓰이는 지표이다.

BERT와 BART의 차이는 아래와 같다.


위 모든 지표에 대한 요약표는 아래와 같다.

 

'Data Science > Research' 카테고리의 다른 글

SQL2NL Prompt Engineering - KCC(3)  (0) 2025.04.14
SQL2NL Prompt Engineering - KCC(2)  (0) 2025.04.08
SQL2NL Prompt Engineering - KCC(1)  (0) 2025.04.04
PostgreSQL, LLM 연결(5)  (0) 2025.04.01
SQL2NL 용 Data set 만들기  (0) 2025.03.31