[NLP]언어 모델을 위한 평가지표 3. 혼잡도(Perplexity)

Date:     Updated:

카테고리:

Perplexity의 개념

Perplexity는 언어 모델의 성능을 평가하는 데 중요한 역할을 하는 지표이다. 이를 통해 모델이 주어진 텍스트 데이터를 얼마나 잘 예측할 수 있는지를 수치화할 수 있다. Perplexity가 낮을수록 모델의 예측 성능이 좋다는 것을 의미하며, Perplexity가 높을수록 예측 성능이 떨어진다는 것을 의미한다.

Perplexity는 주어진 단어 시퀀스 \(W = w_1, w_2, \dots, w_N\)에 대해, 모델이 해당 시퀀스를 얼마나 잘 예측하는지를 나타낸다. Perplexity는 두 가지 방법으로 표현 가능하며, 첫 번째 방법은 다음과 같이 정의된다. 이 수식은 시퀀스 전체의 확률의 역수를 \(N\)으로 나누어 줌으로써 모델의 예측 성능을 평가한다.

$$\text{Perplexity} = P(W)^{-\frac{1}{N}} = \left(\prod_{i=1}^{N} P(w_i | w_1, w_2, \dots, w_{i-1})\right)^{-\frac{1}{N}}$$

이 수식에서의 Notation은 다음과 같다.

  • \(P(W)\)는 전체 시퀀스 \(W\)에 대한 확률.
  • \(N\)은 시퀀스에 포함된 단어의 수.
  • \(P(w_i \vert w_1, w_2, \dots, w_{i-1})\)는 단어 \(w_i\)가 앞선 단어들 \(w_1, w_2, \dots, w_{i-1}\)를 기반으로 발생할(=생성할) 확률.

두 번째 방법은 첫 번째 수식을 로그 스케일로 변환한 것이다. 확률의 곱셈을 로그 값의 합으로 변환하면, 계산이 더 간단해지고, 매우 작은 확률 값들로 인한 수치적 문제를 피할 수 있다. 이 방법은 특히 컴퓨터에서 수치 계산을 할 때 더 안정적이다.

$$\text{Perplexity} = 2^{-\frac{1}{N} \sum_{i=1}^{N} \log_2 P(w_i | w_1, w_2, \dots, w_{i-1})}$$

첫 번째 식에서 로그 스케일을 사용하여 확률의 곱셈을 더하기로 변환하기 때문에 계산이 더 간단해지고, 작은 확률 값을 다룰 때 발생할 수 있는 언더플로우 문제를 피할 수 있다.



Perplexity의 의미

  • Perplexity가 1일 경우: 모델이 주어진 모든 단어 시퀀스를 완벽하게 예측한다는 것을 의미한다. 이는 모델이 시퀀스의 모든 단어를 정확히 예측할 수 있음을 나타낸다.
  • Perplexity가 높을 경우: 모델의 예측이 부정확하거나 랜덤에 가까움을 나타낸다. 이는 모델이 텍스트 데이터를 잘 이해하지 못하고 있음을 의미한다.
  • Perplexity의 비교: 서로 다른 모델들의 Perplexity 값을 비교함으로써 어떤 모델이 주어진 텍스트 데이터를 더 잘 예측하는지를 평가할 수 있다. 일반적으로 Perplexity가 낮은 모델이 더 나은 성능을 가진다고 판단한다.

Python 구현 예시

import math
from collections import Counter

def calculate_ngram_probabilities(corpus, n):
    ngrams = []
    for sentence in corpus:
        tokens = sentence.split()
        sentence_ngrams = list(zip(*[tokens[i:] for i in range(n)]))
        ngrams.extend(sentence_ngrams)
    
    ngram_counts = Counter(ngrams)
    context_counts = Counter([ngram[:-1] for ngram in ngrams])

    probabilities = {}
    for ngram in ngram_counts:
        context = ngram[:-1]
        probabilities[ngram] = ngram_counts[ngram] / context_counts[context]
    
    return probabilities

def calculate_perplexity(corpus, probabilities, n):
    log_prob_sum = 0
    token_count = 0
    
    for sentence in corpus:
        tokens = sentence.split()
        sentence_ngrams = list(zip(*[tokens[i:] for i in range(n)]))
        for ngram in sentence_ngrams:
            if ngram in probabilities:
                log_prob_sum += math.log(probabilities[ngram])
            else:
                # If ngram is not in the training data, assign a very small probability
                log_prob_sum += math.log(1e-6)
            token_count += 1
    
    # Calculate perplexity
    perplexity = math.exp(-log_prob_sum / token_count)
    return perplexity

# Example usage
corpus = ["The cat chased the mouse under the table",
       "The mouse found a piece of cheese",
        "The dog barked at the cat loudly"]

n = 2  # Bigram model
probabilities = calculate_ngram_probabilities(corpus, n)
perplexity = calculate_perplexity(corpus, probabilities, n)

print(f"Perplexity: {perplexity}")
Perplexity: 1.6369846454305215

NLP 카테고리 내 다른 글 보러가기

댓글 남기기