# 들어가며

지금부터 언어 모델의 개념을 간략히 살펴봅니다.

## 언어 모델 소개

지금까지 단어 또는 문장을 입력으로 받아 특정 값 또는 클래스로 분류하는 방법을 살펴봤습니다. 그 값을 통해 해당 단어 또는 문장을 분류하기도 하고 군집을 형성clustering할 수도 있었습니다. 이들 역시 쓰임새가 매우 많고 중요한 방법이지만, 여기서 한 발 더 나아가 신경망으로 하여금 필요에 따라 자연스러운 문장을 만들어내도록 하는 방법을 다뤄보겠습니다.

언어 모델language model(LM)은 문장의 확률을 나타내는 모델입니다. 즉, 우리는 언어 모델을 통해 문장 자체의 출현 확률을 예측하거나, 이전 단어들이 주어졌을 때 다음 단어를 예측할 수 있으며, 결과적으로 주어진 문장이 얼마나 자연스럽고 유창한fluent 표현인지 계산할 수 있습니다. 예를 들어 우리는 다음과 같은 문장이 주어졌을 때 빈칸을 어렵지 않게 메울 수 있습니다.

|  번호 | 버스 정류장에서 방금 버스를 _**\_**_. |
| :-: | :-----------------------: |
|  1  |            사랑해            |
|  2  |            고양이            |
|  3  |            놓쳤다            |
|  4  |            사고남            |

우리는 정답이 3번이라고 쉽게 맞출 수 있습니다. 4번 '사고남'의 경우에는 앞 단어가 '버스를'이 아닌 '버스가' 였다면 정답이 될 수도 있었습니다. 처음부터 4번을 정답이라고 할 경우, 뜻을 전달하는 데는 큰 무리가 없겠지만 뭔가 어색함이 느껴지는 문장이 될 겁니다.

이번에는 다음과 같은 두 문장이 주어졌다고 가정합니다. 살아가면서 1번 문장을 접할 기회는 2번 문장을 접할 기회보다 훨씬 많을 겁니다. 세상에는 수많은 단어가 있고, 그 단어들 간의 조합은 더 많습니다. 그러한 조합들은 동등한 확률을 갖기보다는 자주 나타나는 단어나 표현(단어의 조합)이 훨씬 높은 확률로 나타날 겁니다.

| 번호 | 문장                         |
| -- | -------------------------- |
| 1  | 저는 어제 점심을 먹었습니다.           |
| 2  | 저는 2015년 3월 18일 점심을 먹었습니다. |

우리는 살아오면서 수많은 문장을 접해왔고, 머릿속에는 단어와 단어 사이의 확률이 자신도 모르게 학습되어 있습니다. 덕분에 누군가와 대화하다가 몇 단어 정도 완벽하게 알아듣지 못한다 해도 대화 자체에는 큰 지장이 없습니다. 여기에는 물론 문맥 정보를 이용하는 것도 큰 도움이 됩니다. 이처럼 꼭 자연어 처리 분야가 아니더라도 음성 인식speech recognition이나 광학 문자 인식optical character recognition(OCR)에 있어서도 언어 모델은 큰 역할을 수행합니다.

언어 모델을 학습하고 구성하기 위해 우리는 인터넷이나 책을 통해 (대개 수십만에서 수억 개에 이르는) 많은 문장을 수집하고 단어와 단어 사이의 출현 빈도를 세어 확률을 계산합니다. 이 과정의 궁극적인 목표는 일상 생활에서 사용하는 실제 언어(문장)의 분포를 정확하게 근사하는 것입니다. 또한, 만약 의료 분야의 음성 인식인식기 제작과 같은 특정한 목표가 있다면, 해당 영역domain의 문장 분포를 파악하기 위해 그 분야의 코퍼스를 수집하기도 합니다.

## 다시, 지옥불 난도의 한국어

우리는 언어들의 구조적 특징에 따라 여러 갈래로 언어를 분류합니다. 이전 장에서 이미 다루었듯이 한국어는 대표적인 교착어입니다. 영어는 고립어(+굴절어)의 특징을 띠며, 중국어는 고립어로 분류합니다. 교착어의 특징상 단어의 의미 또는 역할은 어순에 의해 결정되기보다는 단어에 부착되는 어미와 같은 접사 또는 조사에 의해 결정됩니다. 따라서 같은 의미의 단어라 할지라도 붙는 접사나 조사에 따라 단어의 형태가 달라지거나 단어의 수가 늘어납니다. 예를 들어 '버스+가', '버스+를', '버스+에', '버스+로' 등 같이, 똑같은 '버스'라도 뒤에 붙는 조사에 따라 다른 형태가 됩니다. 즉, 단어의 어순이 중요하지 않기 때문에(또는 생략 가능하기 때문에) 단어와 단어 사이의 확률을 계산하는 데 불리하게 작용할 수 있습니다.

| 번호 | 문장                    |
| -- | --------------------- |
| 1  | 나는 학교에 갑니다 버스를 타고 .   |
| 2  | 나는 버스를 타고 학교에 갑니다 .   |
| 3  | 버스를 타고 나는 학교에 갑니다 .   |
| 4  | (나는) 버스를 타고 학교에 갑니다 . |

앞의 네 문장 모두 같은 의미의 표현이고 사용된 단어들도 같지만, 어순이 다르므로 단어와 단어 사이의 확률을 정의할 때 혼란이 가중됩니다. 같은 의미의 문장을 표현하기 위해 '타고' 다음에 나타날 수 있는 단어들은 '.', '학교에', '나는'의 3개이기 때문에, 확률이 쉽게 말해 '퍼지는' 현상이 생깁니다. 즉, 다음 단어를 예측할(또는 찍을) 때 헷갈릴 가능성이 훨씬 높아질 것입니다. 이에 반해 영어나 기타 라틴어 기반 언어들은 어순이 더 규칙적이므로 유리합니다.

게다가 한국어는 교착어의 특징상 접사와 조사가 붙어 단어의 의미와 역할이 결정되기 때문에 똑같은 '과학'이라는 단어에 '과학+도', '과학+자', '과학+관', '과학+실'과 같이 접사가 붙거나 '학교'라는 단어가 '학교+에', '학교+로', '학교+를', '학교+가'와 같이 조사가 붙어 수많은 단어로 파생될 수 있습니다. 따라서 어미를 분리해주지 않으면 어휘의 수가 기하급수적으로 늘어나 희소성이 높아져 문제 해결이 더 어려워질 수 있습니다.

## 문장의 확률 표현

주어진 문장에 대해 어떻게 확률을 구할 수 있을까요? $w\_1,w\_2$ 라는 2개의 단어가 한 문장안에 순서대로 나타났을 때, 이 문장의 확률은 다음과 같이 표현할 수 있습니다.

$$P(w_1, w_2)$$

이 수식을 베이즈 정리에 따라 조건부 확률로 표현하면 다음과 같습니다.

$$\begin{gathered} P(w_1, w_2)=P(w_1)P(w_2|w_1), \\ \text{because }P(w_2|w_1)=\frac{P(w_1,w_2)}{P(w_1)}. \end{gathered}$$

나아가 연쇄법칙chain rule을 통해 여러 단어가 나타날 확률을 다음과 같이 분리하여 표현할 수 있습니다.

> 여기서 연쇄법칙은 역전파 알고리즘의 연쇄법칙과 다릅니다.

$$P(w_1,w_2,\cdots,w_n)=P(w_1)P(w_2|w_1)P(w_3|w_1, w_2)\cdots P(w_n|w_1,w_2,\cdots,w_{n-1})$$

여기서 연쇄법칙이란, 조건부 확률을 사용하여 결합 확률을 계산하는 방법으로 다음과 같이 유도할 수 있습니다.

$$\begin{aligned} P(A,B,C,D)&=P(D|A,B,C)P(A,B,C) \\ &=P(D|A,B,C)P(C|A,B)P(A,B) \\ &=P(D|A,B,C)P(C|A,B)P(B|A)P(A) \end{aligned}$$

n개의 단어가 주어졌을 때 문장의 확률을 나타낸 수식으로 다시 돌아가보겠습니다. 여기서 우항을 해석해보면, $&#x77;_&#x31;$ 이 나타날 확률과 $w\_1$ 이 주어졌을 때 $w\_2$ 가 나타날 확률, $w\_1,w\_2$ 가 주어졌을 때 $w\_3$ 가 주어졌을 확률, $w\_1,w\_2,\cdots,w_{n-1}$ 이 주어졌을 때 $w\_n$ 이 나타날 확률을 곱하는 것을 알 수 있습니다. 이로써 우리는 언어 모델을 활용하여 문장에 대한 확률뿐만 아니라 단어와 단어 사이의 확률도 정의할 수 있습니다. 앞의 수식을 일반화하면 다음과 같이 표현할 수 있습니다.

$$P(w_1,w_2,\cdots,w_n)=\prod_{i=1}^{n}{P(w_i|w_{<i})}$$

또는 로그 확률로 표현하여 곱셈 대신 덧셈으로 표현할 수 있습니다. 참고로, 문장이 길어지면 당연히 확률에 대한 곱셈이 거듭되면서 확률이 매우 낮아져 정확한 계산 또는 표현이 어려워집니다. 또한 곱셈 연산보다는 덧셈 연산이 빠릅니다. 따라서 우리는 로그를 취하여 덧셈으로 바꿔 더 나은 조건을 취할 수 있습니다.

$$\log{P(w_1,w_2,\cdots,w_n)}=\sum_{i=1}^{n}{\log{P(w_i|w_{<i})}}$$

실제 예제를 통해 살펴보겠습니다. 코퍼스 $\mathcal{C}={s\_1,s\_2,\cdots,s\_n}$ 에서 $i$ 번째 문장 $s\_i = {\text{BOS}, \text{나는}, \text{학교에}, \text{갑니다}, \text{EOS\}}$ 에 대한 확률을 연쇄법칙을 통해 표현하면 다음과 같습니다.

$$P(\text{BOS},\text{나는},\text{학교에},\text{갑니다},\text{EOS})=P(\text{BOS})P(\text{나는}|\text{BOS})P(\text{학교에}|\text{BOS},\text{나는})P(\text{갑니다}|\text{BOS},\text{나는},\text{학교에})P(\text{EOS}|\text{BOS},\cdots,\text{갑니다})$$

여기서 BOS는 '문장의 시작(Beginning of Sentence)'을, EOS는 '문장의 종료(End of sentence)'를 의미하는 토큰입니다. $P(\text{BOS})$ 의 경우에는 항상 문장의 시작에 오므로 상수가 될 것입니다. $P(\text{나는}|\text{BOS})$ 의 경우에는 문장의 시작 후 첫 단어로 '나는'이 올 확률을 나타냅니다.

문장을 어떻게 확률로 나타내는지 알았으니, 확률을 직접 구하는 방법을 살펴보겠습니다. 우리는 앞 장에서 문장을 수집하는 방법을 논의했습니다. 수집한 말뭉치 내에서 직접 단어들의 출현 빈도를 계산함으로써 원하는 확률을 추정할 수 있습니다. 예를 들어 다음의 사후 확률posterior probability은 각 단어 조합의 출현 빈도를 세어 추정할 수 있습니다.

$$P(\text{갑니다}|\text{BOS},\text{나는},\text{학교에})\approx\frac{\text{Count}(\text{BOS},\text{나는},\text{학교에},\text{갑니다})}{\text{Count}(\text{BOS},\text{나는},\text{학교에})}$$
