자연어 처리는 크게 4가지(텍스트 분류, 텍스트 유사도, 텍스트 생성, 기계 이해)에 따라 어떻게 처리를 할지 달라진다.
이번 챕터에서는 자연어 처리를 통해 어떤 문제를 해결할 수 있고, 어떤 방식으로 해결하는지에 대해 알아본다.
먼저, 위에서 언급한 4가지를 알아보기 전에 단어 표현이라는 것에 대해 알아보자.
[ 단어 표현 ]
자연어 처리란, 컴퓨터가 인간의 언어를 이해하고 분석 가능한 모든 분야를 말한다.
즉, 자연어 처리의 가장 기본적인 문제는 '어떻게 자연어를 컴퓨터에게 인식시킬 수 있을까?'가 된다.
컴퓨터는 모든 값을 이진화된 값으로 받아들이는데, 텍스트는 그중 "유니코드" 또는 "아스키 코드"라는 방식을 통해 인식한다.
이런 이진화된 방식을 자연어 처리에 그대로 사용하기에는 언어적 특성이 전혀 없기 때문에 자연어 처리를 위해 만드는 모델에 적용하기에는 부적합하다.
이러한 문제를 해결하기 위해 나온 분야가 "단어 표현(Word Representation)"이다.
단어 표현이란, 텍스트를 자연어 처리를 위한 모델에 적용할 수 있도록 언어적인 특성을 반영해서 단어를 수치화하는 방법을 찾는 것이다.
그리고 이렇게 단어를 수치화할 때는 단어를 주로 벡터로 표현한다. 그래서 단어 표현을 "단어 임베딩(word embedding)" 또는 "단어 벡터(word vector)"로 표현하기도 한다.
단어 표현에는 다양한 방법이 있으며 아직까지도 계속 연구되는 분야이기 때문에 정답이 있는 것은 아니지만 많이 사용되는 위주로 알아보자.
▶ 원-핫 인코딩(on-hot encoding)
원-핫 인코딩(on-hot encoding)은 단어 표현의 가장 기본적인 방식으로 단어를 하나의 벡터(vector)로 표현하는 방법이다. 각 단어는 0과 1 값만 가지는 벡터로 표현되는데, 이름에서 알 수 있듯이 벡터 값 가운데 하나만 1이라는 값을 가지고 나머지는 모두 0값을 가지는 방식이다. 여기서 1은 각 단어가 어떤 단어인지 알려주는 인덱스가 된다.
예를 들어, 6개의 단어(남자, 여자, 아빠, 엄마, 삼촌, 이모)를 알려줘야 한다고 했을 때 이를 원-핫 인코딩 방식으로 표현하면 다음과 같다.
즉, 원-핫 인코딩 방식은 각 단어의 인덱스를 정한 후 각 단어의 벡터를 그 단어에 해당하는 인덱스의 값을 1로 표현하는 방식이다.
이 방법의 장단점은 다음과 같다.
- 장점
- 매우 간단하고 이해하기 쉽다. - 단점
- 실제 자연어처리에서는 단어가 많아 벡터의 크기가 너무 커지기 때문에 공간을 너무 많이 사용하며,
사용하는 공간에 비해 실제 사용하는 값은 1이 되는 값 하나뿐이므로 비효율적이다.
- 벡터값 자체의 단어 의미나 특성이 표현되지 않는다.
따라서 이러한 단점을 보완하기 위해 다른 인코딩 방법들이 제안되었다.
제안된 방법은 벡터의 크기가 작으면서도 벡터가 단어의 의미를 표현할 수 있는 방법으로 분포 가설(Distributed hypothesis)을 기반으로 한다.
분포 가설이란, "같은 문맥의 단어, 즉 비슷한 위치에 나오는 단어는 비슷한 의미를 가진다." 라는 개념이다.
따라서 비슷한 위치에 존재하는 단어는 단어간의 유사도가 높다고 판단하는 방법인데 크게 카운트 기반 방법과 예측 방법으로 나뉜다.
▶ 카운트 기반 방법
카운트 기반 방법은 특정 문맥 안에서 단어들이 동시에 등장하는 횟수를 직접 세는 방법이다.
여기서 동시에 등장하는 횟수를 동시 출현 혹은 공기라고 부르며 영어로는 Co-occurrence라고 한다.
카운트 기반 방법에서는 기본적으로 동시 등장 횟수를 하나의 행렬로 나타낸 뒤 그 행렬을 수치화해서 단어 벡터로 만드는 방법을 사용하는데, 다음과 같은 방법들이 있다.
- 특이값 분해(Singular Value Decomposition, SVD)
- 잠재의미분석(Latent Semantic Analysis, LSA)
- Hyperspace Analogue to Language(HAL)
- Hellinger PCA(Principal Component Analysis)
위의 방법은 모두 동시 출현 행렬(Co-occurrence Matrix)을 만들고 그 행렬들을 변형하는 방식이다.
단어의 동시 출현 행렬은 행과 열을 전체 단어 집합의 단어들로 구성하고, i 단어의 윈도우 크기(Window Size) 내에서 k 단어가 등장한 횟수를 i행 k열에 기재한 행렬을 말한다. 예시를 통해 다음 방법들을 이해해보자.
- 성진과 창욱은 야구장에 갔다.
- 성진과 태균은 도서관에 갔다.
- 성진과 창욱은 공부를 좋아한다.
위의 문장들을 가지고 윈도우 크기가 1인 동시 출현 행렬을 만들려면 좌, 우로 단어가 같이 출현한 횟수를 센 후 행렬을 만든다.
이렇게 만들어진 동시 출현 행렬을 토대로 위의 방식들을 사용하여 벡터를 만든다.
이러한 카운트 기반 방법의 장점은 만들어야 할 벡터가 많아질수록 소요되는 시간이 적어진다는 것이다.
또한 예측 방법에 비해 이전에 만들어진 방법이지만 데이터가 많을 경우 단어가 잘 표현되고 효율적이어서 아직까지도 많이 활용되고 있다.
▶ 예측 방법
예측 방법이란 신경망 구조 혹은 어떠한 모델을 사용해 특정 문맥에서 어떤 단어가 나올지를 예측하면서 단어를 벡터로 만드는 방식이다.
예측 방법의 종류는 다음과 같다.
- Word2vec
- NNLM(Neural Network Language Model)
- RNNLM(Recurrent Neural Network Language Model)
여러 예측 기반 방법 중에서 단어 표현 방법으로 가장 많이 사용되는 방법은 Word2vec으로, 이 방법에 대해 자세히 알아보자.
먼저, Word2vec의 개념에 대해서 재미있게 설명된 홈페이지가 있는데 참고하면 좋을 듯 하다.
참고 링크: http://w.elnn.kr/search/
위 사이트는 한국어 단어에 대해 벡터 연산을 해볼 수 있는 사이트로 더하기 빼기 연산이 가능하다.
예를 들어, '고양이 + 애교' 를 입력하면 '강아지'가 출력되는 것을 확인할 수 있다.
Word2vec는 CBOW(Continuous Bag of Words)와 Skip-Gram이라는 두 가지 모델로 나뉜다.
CBOW는 어떤 단어를 예측하기 위해 문맥 안의 주변 단어들을 이용하고,
Skip-Gram은 주변 단어들을 예측하기 위해 어떤 단어를 이용한다.
예시를 통해 비교해보자. 다음과 같은 문장이 있다고 하자.
- 창욱은 냉장고에서 음식을 꺼내서 먹었다.
이때 CBOW는 다음 문장의 빈칸을 채우는 모델이라고 생각하면 된다.
- 창욱은 냉장고에서 ______ 꺼내서 먹었다.
반대로 Skip-Gram은 다음 문장에서 빈칸을 채운다고 생각하면 된다.
- ______ _________ 음식을 ________ _______
두 모델은 위와 같이 단어들을 예측하면서 단어 벡터를 계속해서 학습하며, 모델의 전체적인 구조는 다음과 같다.
CBow모델의 학습 순서는 다음과 같다.
- 각 주변 단어들을 원-핫 벡터로 만들어 입력값으로 사용한다(입력층 벡터).
- 가중치 행렬(weight matrix)을 각 원-핫 벡터에 곱해서 n-차원 벡터를 만든다(N-차원 은닉층).
- 만들어진 n-차원 벡터를 모두 더한 후 개수로 나눠 평균 n-차원 벡터를 만든다(출력층 벡터).
- n-차원 벡터에 다시 가중치 행렬을 곱해서 원-핫 벡터와 같은 차원의 벡터로 만든다.
- 만들어진 벡터를 실제 예측하려고 하는 단어의 원-핫 벡터와 비교해서 학습한다.
Skip-Gram모델의 학습 순서는 다음과 같다.
- 하나의 단어를 원-핫 벡터로 만들어 입력값으로 사용한다(입력층 벡터).
- 가중치 행렬(weight matrix)을 원-핫 벡터에 곱해서 n-차원 벡터를 만든다(N-차원 은닉층).
- n-차원 벡터에 다시 가중치 행렬을 곱해서 원-핫 벡터와 같은 차원의 벡터로 만든다(출력층 벡터).
- 만들어진 벡터를 실제 예측하려고 하는 주변 단어들 각각의 원-핫 벡터와 비교해서 학습한다.
위의 학습 과정을 모두 끝낸 후 가중치 행렬의 각 행을 단어 벡터로 사용한다.
이처럼 Word2vec의 두 모델은 여러 가지 장점이 있는데, 정리해보면 다음과 같다.
- 카운트 기반 방법보다 단어 간의 유사도를 잘 측정한다.
- 단어들의 복잡한 특징들도 잘 잡아낸다.
- 단어 벡터끼리의 유의미한 관계가 측정 가능하다.
마지막 3번을 조금 더 보충 설명하자면 다음과 같다.
예를 들어 엄마, 아빠, 남자, 여자를 Word2vec 방식을 사용해 단어 벡터로 만들었을 때, 각 단어 벡터 사이의 거리를 보면 다음과 같이 계산된다.
그림을 보면 '엄마'와 '아빠'라는 단어 사이의 벡터 거리와 '여자'와 '남자'라는 단어의 벡터 사이의 거리가 같게 나온다.
Word2vec의 CBow와 Skip-Gram 모델 중에서는 보통 Skip-Gram이 성능이 좋아 일반적인 경우 Skip-Gram을 사용한다.
하지만 절대적으로 좋은 것은 아니니 두 가지 모두 고려하도록 하자.
이처럼 카운트 기반 방법과 예측 기반 방법을 통해 단어 벡터를 표현하는데, 보통의 경우 예측 기반 방법이 성능이 좋아 주로 예측 기반 방법을 사용한다. 그리고 두 가지 방법을 모두 포함하는 "Glove"라는 단어 표현 방법 또한 자주 사용한다.
단어 표현은 모든 자연어 처리 문제를 해결하는 데 기반이 되는 가장 근본적인 내용이므로 정확하게 이해해야 하며 항상 가장 좋은 성능을 내는 유일한 방법이 있는 것이 아니니 각 방법 간에 어떤 차이점이 있는지 항상 염두에 두고 상황에 맞게 사용하는 것이 중요하다.
'정리 > 텐서플로와 머신러닝으로 시작하는 자연어처리' 카테고리의 다른 글
Chap03. 자연어처리 개요_데이터 이해하기 (0) | 2021.07.13 |
---|---|
Chap03. 자연어처리 개요_텍스트 분류 및 유사도 (0) | 2021.07.07 |
chap02. 자연어 처리 개발 준비_numpy, pandas, matplotlib, Re, Beautiful Soup (0) | 2021.07.05 |
chap02. 자연어 처리 개발 준비_전처리 라이브러리 (0) | 2021.07.05 |
chap02. 자연어 처리 개발 준비_사이킷런(Scikit-learn) (0) | 2021.07.01 |