layout: post title: Perplexity에 대해 알아봅시다 subtitle: 언어 모델 성능 측정 지표 background: /img/posts/06.jpg published: true comments: true —
컴퓨터공학에서 자연 언어를 다루는 수업 (우리학교 같은 경우는 대화형사용자인터페이스개론이나 자연어처리개론)에서는 perplexity라는 개념에 대해서 공부하게 됩니다. 강의 자료를 보면, perplexity는
“테스트 데이터에 대한 확률의 역수를 단어 숫자로 normalized 한 것이며, 언어 모델의 성능을 측정하기 위한 척도이다”
라고 써 있고, 그렇게 외우고 시험에 나와도 저런 식으로 쓰면 답이라고 해 줍니다. Stanford에서 Dan Jurafsky 교수님 강의자료를 봐도 그렇게 나오는거 보니까 의심의 눈으로 한번 더 살펴봐도, 교과서 적인 정답이라고 여겨도 될 듯 합니다.
그럼 수식으로 보는 PPL은 어떻게 될까요 \(PPL(W) = P(w_1w_2....w_N)^{-1/N}\) 여기서 N 은 서로 다른 단어의 총 가지수를 말하고, W 는 PPL을 구하고자 하는 대상 문장을 말하며, w는 대상 문장에 존재하는 개별 단어를 말합니다.
보시다시피 크게 어려운 수식은 아닌데, 문제는
왜 언어 모델의 성능을 측정할 때 하필 저 metric을 쓰느냐?
의 의문이 남습니다. 직관적으로 생각해보면 다른 확률 모델들처럼 테스트셋의 개별적인 단어의 확률이 높게 나오면 좋은 언어 모델이라고 생각하고 넘어가도 될 것 같은데요. 왜 그런지 처음부터 짚어봅시다.
사실 컴퓨터가 언어를 이해한다는 건 생각보다 비효율적인 경우가 많습니다. 사람이 이해할 때, 머릿속에서 컴퓨터보다 얼마나 효율적일지는 모르겠지만, 단순한 내용도 언어로 표현하게 되면, 컴퓨터는 저희가 생각하는 것보다 많은 정보를 이용해야 합니다.
예를 한번 들어볼게요. “나 밥 먹을래” 라는 하나의 문장이 있다고 할 때, “나 밥 안 먹을래” 라는 문장과 비교 했을 때 우리가 생각하는 언어의 의미는 딱 두 개로 나눠집니다.
밥을 먹는다 - positive - 1
밥을 안 먹는다 - negative - 0
물론 언제 먹느냐 어디서 먹느냐 어떻게 먹느냐 등등의 많은 물음들이 생겨서 의미가 복잡해 질 수 있지만, 두 문장의 차이점만 비교하는 관점에서는 저 두 가지로 나누어질 수 있습니다. 그럼 저 문장을 컴퓨터로 표현했을 때, 차이는 두 가지 뿐이니, 위에 쓴 대로 0과 1로만 표현 가능할까요? 한글은 캐릭터셋에 따라 2byte냐 3byte냐가 갈리지만, 일단 2byte라고 가정하고 해 봅시다. 띄어쓰기는 1byte로 하구요
밥을 먹는다 {5(개)*2(byte) + 1(space)} *8(bits) = 88
밥을 안 먹는다 {6(개)*2(byte) + 2(space)} * 8(bits) = 112
1비트로 처리해도 괜찮은 정보가 24비트나 차이가 나 버렸습니다. 하지만 아무리 많은 비트가 사용된다 한들, 우리가 저 두 문장에서 얻고자 하는 정보는 0이냐 1이냐 둘 중 하나밖에 없어요. 그럼 단순히 bit가 아닌, 저 정보들을 0이나 1로 표현할 수 있는 metric이 필요합니다. 구글링을 해보면 그런걸 표현하는 걸 아래처럼 표현합니다.
\[I(x) = -logP(x)\]
I(x)는 아까 위에서 밥 먹냐, 안먹냐를 표현하는 정보량을 표현한 것이고, 밥 먹을 확률 P(x)에다가 음의 log를 취한 값으로 표현됩니다. 왜 음의 로그냐면요,
확률이 높은 일의 경우 새로이 얻는 정보의 양이 적다고 봅니다. (ex> 아침에 해가 뜬다, 불은 뜨겁다 등) 그러니까 극단적으로 말하면 예외 없이 당연한 일의 경우 새로운 정보가 없기 때문에 정보량이 0 이 될 것입니다. 그리고 알고 있는 정보를 ‘뺏긴다’는 개념은 없기 때문에, 항상 양수값이어야 합니다. 마지막으로, 확률을 곱셈으로 나타나는 경우 정보가 복잡해질 때, 모든 변수들이 계속 곱해지기 때문에 정보양의 변화를 파악하기가 어려워집니다.
이 모든 것을 만족하는게 음의 로그 함수입니다. 음의 로그 함수의 경우에는 값이 증가할수록 감소하고, [0,1] 구간에서는 음수가 되지 않습니다. 또한 곱셈을 덧셈으로 변화시킬 수 있습니다. 살짝 응용하자면, log의 밑이 2가 되면 정보량을 bit로 나타낼 수 있게 됩니다. (확률을 2의 정보량 승으로 바꿀 수 있기 때문입니다)
지금까지는 단일 사건에 대해서 정보량을 얻는 걸 해봤는데, 아까 예시에서도 잠깐 언급했지만, “나 밥 먹을래” 와 “나 밥 안 먹을래” 사이에는 0, 1로만 존재하지 않는 개념들이 숨겨져 있습니다. 일단 어디에서 먹느냐, 어떻게 먹느냐, 무엇을 사용해서 먹느냐 등 언급하지 않은 차이점들이 숨겨져 있구요, 그 가능성은 굉장히 많습니다. (ex> 반찬투정…) 이럴 때, 언어 모델의 성능을 높이기 위해서는 우리는 학습 자료에 있는 정보만이라도 이용해서 저 문장들에 대한 정보를 알아낼 수 있어야 합니다. (예를 들면, 저희가 적당한 수의 학습 데이터가 있다고 한다면, 언어 모델이 “나 밥 먹을래” 대신 “나 컴퓨터 먹을래”라는 문장을 생성하지는 않게 해야겠죠)
이러한 정보를 얼마나 잘 파악하고 있느냐를 결정해 보도록 합시다. 이 바닥에서는 이런 여러 사건들에 대한 정보량을 entropy 라는 개념으로 설명합니다.
\[H(X) = -\sum_{x}P(x)*logP(x) = \sum_{x}P(x)*log(1/P(x))\]위에 설명된 entropy H(X)를 설명하자면 각 사건의 정보량에 각 사건이 일어날 확률을 곱하고, 모두 더하는 것으로 표현됩니다. 즉 일어날 수 있는 다양한 사건들에 대해서 weight를 준 뒤, 모두 곱하는 거죠. 그렇게 하면 어떤 사건 X가 발생할 때, 가능한 여러 정보량들을 이용해서 나온 결과를 수치화 할 수 있게 됩니다. 저 개념은 perplexity뿐 아니라 다양하게 쓰이긴 하는데, 일단 perplexity에 필요한 최소한만 설명했습니다.
자 그럼 맨 위에 있는 perplexity 수식을 다시 가져와서 entropy를 이용해 해석해 봅시다
\[PPL(W) = P(w_1w_2....w_N)^{-1/N} = \sqrt[N]{1/P(w_1W_2...w_n)}\]이렇게 표현이 되는데요, 저희는 컴퓨터를 사용해서 언어 모델을 훈련하고 있으니, 언어 모델에 필요한 정보를 bit 단위로 계산하기 위해서 수식을 조금 더 바꿔보겠습니다.
\[\sqrt[N]{1/P(w_1W_2...w_n)} = 2^{l}\] \[l = {1 \over N}\sum_nlog_2p(w_n)\]이렇게 바뀌게 됩니다. 강의자료있던곳
엔트로피랑 비슷하지만 조금 다른 부분이 있는데, 그 이유는 여기서는 모든 단어의 발생 확률에 차이를 두지 않기 때문입니다. perplexity에서는 모든 단어의 개별 발생 확률이 같다고 가정합니다.
정리하자면, Perplexity는 주어진 모델에 대해서 테스트 문장을 넣었을 때, 그 문장이 가진 정보를 표현하는 데 필요한 비트 수 를 측정하는 것이며, 이 크기가 작을 수록 해당 테스트 문장은 “모델이 이미 알고 있는” 정보가 되고, 이는 곧 모델의 성능이 높다는 뜻으로 해석할 수 있습니다.
다른 관점에서 보자면, perplexity가 낮다고 해서(문장에 필요한 정보의 비트 수가 적다고 해서) 절대적으로 그 언어 모델이 성능이 좋다고는 볼 수 없습니다. 모델이 모든 도메인의 정보를 담고 있다는 보장이 없기 때문입니다.
짧게 하고 싶었는데 엔트로피 한다고 많이 길어졌네요. 다음엔 좀 더 다듬어 보겠습니다. 감사합니다.