[딥러닝]BLEU Score란?
카테고리: DeepLearning
Bilingual Evaluation Understudy(BLEU)
딥러닝의 발달로 최근 ChatGPT를 포함한 Text generation model이 인기이다. Generative Model은 챗봇, 문서 요약등 다양한 분야에서 사용된다. 이러한 생성 모델을 평가하는 기준으로 얼마나 정확하게 문장을 생성해내는지에 대한 Evaluation metric으로 크게 BLEU와 ROUGE방식이 있다.
생성 모델은 주로 Supervised Learning방식으로 정답이 되는 Reference Sentece가 있다. 그리고 이를 기반으로 생성 모델이 생성하는 문장을 Generative Sentence라고 한다.
- if
- Reference Sentece의 단어가 Generated Sentece에 포함되는 정도 → ROUGE
- Generated Sentence의 단어가 Reference Sentence에 포함되는 정도 → BLEU
각각을 수식화하면 다음과 같다.
이 때 BLUE Score를 좀 더 직관적으로 나타내면 다음과 같다.
예를 들어서, 모델이 생성한 문장이 “I was generated by the model”이었고 실제 정답은 “I was referenced by human”이라고 한다면 “I”, “was”, “by”는 두 문장에 공통으로 들어있게 된다. 따라서 BLEU와 ROUGE는 다음과 같다.
BLEU값은 0이 가장 작고, 1이 가장 큰 값이다. ROUGE score는 주로 Text Summarization에서 사용되고 BLEU Score는 일반적으로 Machine Translation에서 사용된다. Reference가 되는 문장은 하나가 아니라 여러 개일 수 있다. 예를 들어서, “I was happy” 라는 문장을 번역하는 모델이 있을 때, 정답에 “나는 행복했다.”, “나는 행복했었다.”, “행복했다,, 나는” 이라고 여러 개의 정답이 있을 수 있다. 따라서 BLEU를 계산할 때는, 이러한 중복된 Reference에 대해서 고려해줘야 합니다. BLEU는 단어가 Reference 중에 한 곳에라도 포함된다면 정답인 걸로 센다.
Clipping
이 때, 하나의 단어가 예측문장에 여러번 등장하여 중복계산될 수 있기 때문에, Clipping 작업을 통해 해당단어가 카운팅 되는 횟수는 정답문장에서 등장하는 횟수를 넘지 못하게 한다.
ex)Clipping
- 정답문장: “an apple is on the desk”
- 예측문장: “an an an an apple “
- ‘an’은 정답문장에서 1회 등장 –> 1회 카운팅
- before Clipping : 겹치는 횟수 : 5
- after Clipping : 겹치는 횟수 : 2
ex)1-gram precision
- Clipping 유무에 따른 1-gram precision의 예시입니다.
- 정답문장: “한화는 10년 안에 우승 할 것이다.”
- 예측문장: “한화는 한화는 한화는 한화는 10년 안에 준우승 할 것이다.”
- 1-gram precision(Clipping X) = \(\frac{일치하는 \; 1-gram \; 수}{모든 \; 1-gram \; 수} \; = \; \frac{8}{9}\)
- 1-gram precision(Clipping O) = \(\frac{일치하는 \; 1-gram \; 수}{모든 \; 1-gram \; 수} \; = \; \frac{5}{9}\)
Brevity Penalty
또한 \(min(1, \frac{output \; length(\; 예측 \; 문장 \;)}{reference \; length(\; 정답 \; 문장 \;)})\) 부분은 문장길이에 대한 과적합을 보정해 준다. 비교적 짧은 문장은 결과에 있어 우위를 가져다 줄 수 있다. 이러한 과정을 통하여 BLEU score가 계산된다. 요약하면 BLEU는 문장의 길이와 단어의 중복을 고려하여 정답문장과 예측문장 사이의 겹치는 정도를 계산하는 지표이다.
Python 구현
nltk
라이브러리를 사용하면 BLEU를 쉽게 계산할 수 있다.
from nltk.translate.bleu_score import sentence_bleu
Ex1)
첫 번째 예시는 Reference 문장이 Generated 된 문장과 완벽하게 일치하는 경우이다. 이 경우 BLEU score는 가장 높은 값인 1.0 이 나온다.
reference = [["this", "is", "the", "sample"]]
candidate = ['this', "is", "the", "sample"]
score1 = sentence_bleu(reference, candidate, weights=(1, 0, 0, 0)) # 1.0
Ex2)
두 번째 예시는 Generated 문장에서 일치하는 단어가 각각 다른 Reference에 있는 경우이다. 이 경우에도 BLEU score는 가장 높은 값인 1.0 이 나온다.
reference = [["this", "is", "the", "good", "choice"],
["it", "is", "a", "sample"]]
candidate = ['this', "is", "the", "sample"]
score2 = sentence_bleu(reference, candidate, weights=(1, 0, 0, 0)) # 1.0
Ex3)
마지막은 Generated 문장의 단어가 Reference에 포함되지 않은 경우이다. 이 경우는 a 하나가 reference에 들어있지 않기 때문에 4/5가 나온다.
reference = [["this", "is", "the", "sample"],
["this", "is", "the", "good","sample"]]
candidate = ['this', "is", "a", "good", "sample"]
score3 = sentence_bleu(reference, candidate, weights=(1, 0, 0, 0)) # 0.8
print(" Exact Match :" , score1) # 1.0
print(" Two References:" , score2) # 1.0
print("Not included word : ", score3) # 0.8
따라서 Reference가 많다면 BLEU score는 높아질 수밖에 없다.
Ex4)
만일 문장 하나가 아니라 여러 개의 문장(코퍼스 Corpus)에 대해서 한 번에 계산하고 싶다면 다음 코들 이용하면 된다.
from nltk.translate.bleu_score import corpus_bleu
reference = [[["this", "is", "a", "sample"]],
[["another", "sentence"], ["other", "sentence"]]]
candidate = [['this', "is", "a", "sample"],
['just', "another", "sentence"]]
score4 = corpus_bleu(reference, candidate, weights=(1, 0, 0, 0))
print("Multiple Sentence : ", score4) # 0.85
코드를 자세히 보면 weights=(1,0,0,0) 으로 표시된 부분을 확인할 수 있다. BLEU를 계산할 때, 단순히 단어의 등장으로 센다면, 단어의 순서에 관계없게 동일한 BLEU를 가지게 된다. 실제로 아무 의미 없는 문장인 “I happy was” 가 “I was happy” 와 동일한 값을 가지게 된다. 그래서 BLEU에서는 단어 1개인 1-gram 방식을 넘어서, 2,3,4-gram 방식을 모두 사용해서 값을 구하는 방식을 취한다. 여기서 weight는 각 n-gram에 대한 가중치를 나타낸다.
만일 1,2,3,4-gram에 대해서 동일한 가중치를 두고 싶다면, weights=(0.25, 0.25, 0.25, 0.25) 로 설정해주시면 된다.
Reference
BLEU Score의 소개와 계산하는 방법 (Python)
BLEU score : bilingual Evaluation Understudy
댓글 남기기