자연어 처리의 4가지 단계

자연어 처리의 4가지 단계

이 포스트는 Stanford의 CS224n 강의에서 배운 내용을 바탕으로 인공지능을 이용한 자연어 처리 방법의 개요를 정리해본 내용을 담고 있습니다.

목차

  1. 자연어 처리 솔루션
  2. 자연어 처리의 4가지 단계
  3. 정리 및 요약

1. 자연어 처리 솔루션

자연어는 사람이 사용하는 언어를 말하는 것으로 프로그래밍 언어 등의 기계언어와 대비됩니다. 자연어 처리는 한국어, 영어, 중국어 등 인간의 언어를 컴퓨터가 분석하고 의미 있는 정보를 추출하여 처리하는 작업을 통칭합니다. 자연어 처리는 문서 분류, 스팸 처리, 검색어 추천, 음성 인식, 질의응답, 번역 등 다양한 분야에 사용되고 있습니다. 예를 들어 구글 번역기는 구글 신경망 번역 시스템 (Google Neural Machine Translation)을 이용해 다양한 언어를 번역합니다. 이 모델은 다양한 사용자들의 새로운 입력(input)을 받아 계속해서 학습하고 더 나은 번역 결과를 도출합니다. 또한 스팸 불리(spam bully)라는 회사에서는 베이지안 스팸 필터를 사용하여 스팸 메일에 자주 사용되는 단어나 문구를 추출하고 이를 통해 스팸 메일을 분류해냅니다.

자연어 처리 솔루션은 간단한 문서 분류에서 더 나아가 교통편 예약, 스마트홈, 헬스케어, 금융 등 다양한 분야에 적용되고 있습니다. 자연어 처리 솔루션을 이용해 자동화된 프로세스는 은행, 금융 서비스 등에서 효율성을 증진하고 오류 발생률을 낮춥니다. 대중의 스마트 기기 사용률과 고객 서비스에 대한 연구 발달이 자연어 처리 솔루션 시장 성공 요인의 큰 부분을 차지하고 있습니다.

그림 1. 자연어 처리 관련 시장 추이

2. 자연어 처리의 4가지 단계

자연어 처리 솔루션을 만들기 위한 방법론은 정말 다양하지만, 대부분의 솔루션은 아래의 4가지 단계로 구성되어 있습니다. 이 포스트에서는 각각의 솔루션에 대해 소개하기보다 각 단계에 활용되는 주요 개념들을 다루어보았습니다.

2.1. Preprocessing

대부분의 자연어 데이터에는 URL과 같은 hypertext 및 특수문자들이 섞여있습니다. 특히 웹크롤링을 통해 데이터를 수집한 경우 각 웹페이지에 있는 텍스트 데이터는 모두 html 태그들과 섞여있을 것입니다. 따라서 자연어 데이터를 머신러닝, 딥러닝과 같은 통계 기법을 이용해 바로 분석하기에 앞서, 우선 분석하고자 하는 데이터에 사람들이 일상적으로 사용하는 언어만 남아있도록 가공해주어야 합니다.

이 뿐 아니라 동일한 의미를 가지지만 축약하여 표현하여 그 형태가 달라보이거나(do not = don’t), 실제 문장의 의미 해석에 있어 크게 중요하지 않은 표현들(for, to, the) 또한 처리해주는 편이 좋습니다. 이 밖에도 정말 다양한 형태의 전처리를 수행할 수 있는데요, MBTI classification 관련 포스트에서 구체적인 예시를 찾아보실 수 있습니다.

2.2. Tokenization

데이터의 전처리가 끝나 마침내 자연어 데이터만 남았다면, 이제 문자열(string)을 다차원 벡터(vector)로 변환해주어야 합니다. 이렇게 변환한 벡터들이 위치한 공간을 임베딩(embedding)이라고 부르는데, 각 단어를 벡터로 변환하는 경우 단어 임베딩(word embedding), 각 문장을 벡터로 변환하는 경우 문장 임베딩(sentence embedding) 등으로 벡터화(vectorization)의 단위를 붙여 지칭하기도 합니다.

단어 임베딩이란 앞서 말씀드린 바와 같이 말뭉치(corpus)에 포함되어 있는 단어들이 각각 하나의 좌표를 가지도록 형성한 벡터공간을 말합니다. 여기서 단어(word)란 일반적으로 띄어쓰기나 줄바꿈과 같은 공백 문자(whitespace)로 나뉘어져 있는 문자열의 일부분을 지칭합니다.

Lorem ipsum dolor sit amet, …

즉 위의 예시에서는 띄어쓰기로 구분되어 있는 Lorem, ipsum, dolor, sit, amet이 각각 하나의 단어가 됩니다. 그러나 띄어쓰기를 활용하지 않는 언어들의 경우, 위와 같은 정의를 통해서는 문자열을 여러 단어로 잘라낼 수 없습니다.

努輸強紙暮革人士績質宿福読相理毎阪釣方新, …

이 경우 공백 문자가 아닌 형태소와 같은 의미론적 단위로 문자열을 구분하거나, 여러 말뭉치(corpus)에서 자주 등장하는 글자(character)들의 순서쌍들을 묶어서 벡터공간을 형성하기도 합니다. 이 임베딩의 단위를 토큰(token)이라고 하고, 주어진 문자열을 토큰들로 나누는 과정을 토큰화(tokenization)이라고 부릅니다. 그리고 이러한 토큰들이 위치한 벡터공간을 토큰 임베딩(token embedding)이라고 합니다.

참고로 한글 문자열의 자연어 처리에는 아래 예시와 같이 형태소(morpheme)를 이용한 임베딩을 자주 활용하고 있습니다.

대한민국은 민주공화국이다.

대한민국 + -은 + 민주공화국 + -이 + -다

2.3. Token Embedding

문자열을 단어, 형태소 등의 토큰으로 분해하는 데 성공했다면 우선 one-hot encoding을 통해 곧바로 각각의 토큰들을 벡터로 변환할 수 있습니다. One-hot encoding이란 말뭉치에 들어있는 단어들을 중복없이 순서대로 나열한 뒤, 아래 이미지에서와 같이 영벡터(zero-vector)에 해당하는 순서(index)의 요소에만 1의 값을 부여하는 방법을 말합니다. 나열한 단어들에 중복이 없으므로 각각의 단어들은 모두 고유한 벡터값을 가지게 됩니다.

그림 2. One-hot encoding 예시1

그러나 one-hot encoding을 통해 얻은 임베딩에서는 각각의 토큰들이 서로 같은 거리에 위치합니다. 즉 두 토큰이 다르다는 사실만 알려줄 뿐 두 토큰이 서로 어떠한 관계를 가지는지는 알려주지 못하는 것이죠. 토큰화 과정(tokenization)과 one-hot encoding을 통해 토큰의 순서를 정했다면 이제 유사한 의미를 가지는 토큰끼리는 서로 가까이 당기고, 관련 없는 토큰끼리는 밀어냄으로써 보다 유의미한 임베딩을 얻을 수 있습니다.

그림 3. Word2Vec 예시

두 토큰의 유사도를 정하는 방법에는 여러가지가 있는데요, Word2Vec2, SentencePiece3를 비롯한 대부분의 임베딩 알고리즘들이 분포가설(distributional hypothesis)을 기반으로 토큰의 유사도를 결정합니다. 분포가설이란 같은 문맥에 등장하는 단어들은 서로 유사한 의미를 가진다는 주장입니다. 여기서 문맥의 정의 또한 다양하게 있겠으나 앞서 말씀드린 두 알고리즘에서는 특정 단어를(center word) 중심으로 특정 단어 수 이내로 위치한 다른 단어들이 곧 같은 문맥 안에 등장하는 단어들(context words)이라 정의합니다.

그림 4. center word와 context words

위 이미지에서 파란색 상자가 center word, 흰색 상자들이 context words들을 나타냅니다. 분포가설을 활용하는 알고리즘들은 크게 2가지 방식으로 학습하는데요, center word를 보고 context words들을 맞추도록 학습하는 방식을 Skip-Gram, context words들을 통해 center word 자리에 어떤 단어가 올지를 맞추도록 학습하는 방식을 Continuous Bag-of-Words라고 부릅니다.

2.4. Document Embedding

말뭉치의 토큰들을 벡터로 만들었다면 이제 머신러닝, 딥러닝 알고리즘을 사용할 준비가 거의 다 끝났습니다. 예를 들어 한 영화에 대한 평론이 전반적으로 긍정적인 내용을 담고 있는지, 부정적인 내용을 담고 있는지 알고 싶다면 해당 평론 안에 포함되어 있는 토큰들의 임베딩을 모두 더해 평균치를 구해볼 수 있겠습니다. 분포가설에 따르면 긍정적 의미를 가진 토큰들은 마찬가지로 긍정적 의미를 가진 토큰들 근처에 위치할 것이고, 부정적 의미를 가진 토큰들은 긍정적 의미를 가진 토큰들과는 멀리 분포할 것이기에 평균치가 이들 중 어느쪽에 더 가까운지 계산해보면 됩니다.

그러나 개별 토큰들의 임베딩을 종합하는 것만으로는 해결할 수 없는 문제들도 있습니다. 한가지 예시로는 동음이의어와 다의어가 있습니다.

1) 밥을 많이 먹어 배가 부르다.

2) 사과보다 배가 더 시원하다.

1에서의 ‘배’와 2에서의 ‘배’ 모두 동일한 형태를 가지지만 서로 다른 의미를 가지고 있습니다. 1번에서의 ‘배’가 과일이 아닌 신체 부위를 뜻한다는 것을 알기 위해서는 ‘밥’, ‘먹-‘ 등의 형태소가 같은 문장 내에 위치한다는 것을 알아야 합니다.

두번째 예시로는 단어의 사전적 의미와 문맥적 의미가 다른 경우가 있겠습니다. 너무나 잘 알려진 내용이니 이미지로 설명을 대신하도록 하겠습니다.

그림 5. 사전적 의미 vs. 문맥적 의미

위와 같은 문제들이 발생하는 경우 자연어의 의미 해석은 토큰 단위에서가 아닌 문장, 문서 전체에서 이루어져야 할 것입니다. 이에 token embedding들을 모아 sentence embedding 또는 document embedding을 한번 더 학습시키곤 하는데요, 이때 주로 사용하는 것이 언어모델(language model)입니다.

언어모델이란 특정한 문자열, 즉 특정 토큰들의 배열이 등장할 확률을 알려주는 확률모형을 말합니다. 즉 토큰의 개수가 $L$인 문자열 $W = (w_1, w_2, \ldots, w_L)$가 주어지면 $P(W)$를 알려주는 함수라 볼 수 있겠습니다. 그러나 이 확률 $P(W)$를 가능한 모든 $W$에 대해서 다 기록해두는 일은 너무 어려우니 대부분의 언어모델들은 이를 여러 조건부확률로 쪼개어 학습합니다. 예를 들어 GPT의 초기버전4의 경우 문맥이 주어졌을 때 다음 토큰을 예측하는 방식으로 학습하였습니다. 즉 $n \leq L$에 대해 $P(w_n | w_1, \ldots, w_{n-1})$를 각각 학습한 뒤 이들을 전부 곱함으로써 $P(W)$를 계산하는 것이죠.

수식 1. 언어모델과 조건부확률

한편 BERT5는 문장의 일부를 다른 단어로 대체하거나 제거한 뒤(mask) 원래의 문장을 복원하는 방식으로 학습합니다. 즉 $i$번째 토큰이 <MASK>라는 토큰으로 대체되었다고 하면 $P(w_i | w_1, \ldots, w_{i-1}, w_{i + 1}, \ldots, w_{n-1})$의 값이 가장 높은 토큰을 찾아 $i$번째 토큰 자리에 다시 넣어줄 수 있도록 해당 조건부 확률을 학습하는 것입니다.

그림 6. Token Masking in BERT6

언어모델을 학습시켰다면 이를 분해한 뒤 그 속에 있는 잠재 변수를(latent variable) 꺼내어 문장 또는 문서의 임베딩으로써 활용할 수 있습니다. 만약 학습한 언어모델이 multilayer perceptron과 softmax 함수를 이용해 문자열을 확률공간으로 사영했다면 softmax의 바로 이전 layer(penultimate layer)의 출력값을 임베딩으로 사용할 수 있습니다. 또한 Transformer7와 같이 각 layer별로 latent variable이 특별한 의미를 가지는 경우 (e.g. word pair, trigram) 각 layer의 출력값을 모두 합쳐 하나의 임베딩으로 활용하기도 합니다.

그림 10. BERT의 다양한 임베딩6

이렇게 임베딩을 얻었다면 이제 마침내 풀고자 하는 문제(downstream task)에 맞추어 머신러닝 또는 딥러닝 알고리즘을 적용하면 됩니다. GPT, BERT와 같이 큰 용량의 언어모델을 활용하는 경우 언어모델의 학습 과정에서부터 딥러닝 알고리즘을 사용하므로, 임베딩을 얻은 후에도 동일한 딥러닝 알고리즘을 이용해 downstream task를 학습시키곤 합니다. 이 경우 임베딩을 얻기 위한 학습과정을 pretraining, 임베딩 이후의 추가적인 학습과정을 fine-tuning이라고 부릅니다.

3. 정리 및 요약

앞서 설명한 4가지 단계를 “영화 리뷰 감정 분석”이라는 downstream task를 예시로 들어 다시 정리해보도록 하겠습니다.

  1. 영화 리뷰에 포함되어 있는 특수문자, html tag 등을 제거해 자연어 데이터만 남겨줍니다.

  2. 자연어 데이터를 토큰(token)으로 나누어줍니다. 한국어 데이터인 경우 띄어쓰기와 형태소를 활용하여 나누어주면 좋습니다.

  3. 동일한 tokenization을 통해 pretraining이 된 token embedding을 찾아서 다운로드하거나, Word2Vec 등을 이용해 직접 token embedding을 학습시켜줍니다.

  4. 동일한 token embedding을 통해 pretraining이 된 언어모델(language model)을 찾아서 다운로드하거나, BERT 등의 언어모델을 직접 학습시켜줍니다.

  5. 언어모델의 마지막 레이어를 제거한 뒤, 감정 분석을 위해 0 ~ 1의 값을 출력하는 classifier를 마지막 레이어가 있던 자리에 넣어줍니다. sigmoid 함수를 활성화함수(activation function)으로 가지는 linear layer를 붙여주면 됩니다.

  6. 각 리뷰의 텍스트 데이터와 리뷰 점수를 각각 input data, label로 사용하는 지도학습(supervised learning)을 통해 감정 분석을 학습시켜줍니다. 언어모델도 함께 fine-tuning 해주는 것이 일반적입니다.

  7. 지도학습이 끝났다면 token embedding, 언어모델, 그리고 마지막 classifier까지 함께 저장해줍니다. 이제 새로운 리뷰 텍스트에 대해 학습과정과 동일한 토큰화, token embedding, 언어모델을 이용한 추론(inference)을 수행해주면 해당 리뷰의 예상 점수를 얻을 수 있습니다.

이상으로 자연어 처리의 개괄적인 과정을 한번 다루어보았습니다. 간결한 설명을 위해 인공지능 관련 알고리즘들에 대한 내용은 많이 생략해보았는데요, 자연어 처리를 위한 각종 딥러닝 방법론에 관심이 있으신 분들께선 저희 DIYA의 다른 포스트들에 좀 더 자세히 나와있으니 한번 읽어봐주세요 :)

DIYA의 자연어 관련 포스트들

References

1Data-oriented and Machine Learning Technologies in FinTech
2Efficient Estimation of Word Representations in Vector Space
3SentencePiece: A simple and language independent subword tokenizer and detokenizer for Neural Text Processing
4Improving Language Understanding by Generative Pre-Training
5BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding
6The Illustrated BERT, ELMo, and co. (How NLP Cracked Transfer Learning) – Jay Alammar – Visualizing machine learning one concept at a time.
7Attention Is All You Need

Written by 김영훈, 정은빈