본문 바로가기

데이터 사이언스/머신러닝

[Embedding] 단어 임베딩

컴퓨터는 자연어를 처리할 수 없기에, 숫자나 벡터 형태로 변환해 컴퓨터가 처리할 수 있게 해주어야 한다. 이 과정을 자연어 처리 분야에서는 임베딩(Embedding)이라고 한다.

단어 임베딩은 개별 단어를 벡터로 표현하는 방법이다. 문장 임베딩에 비해 학습 방법이 간단하지만, 동음이의어에 대한 구분을 하지 않기에 의미가 다르더라도 단어의 형태가 같다면 동일한 벡터값으로 표현되는 단점이 있다.

 

1. 원-핫 인코딩(one-hot encoding)

단어를 숫자 벡터로 변환하는 가장 기본적인 방법이다.

요소들 중 단 하나의 값만 1, 나머지는 0인 인코딩을 의미하며, 전체 요소 중 단 하나의 값만 1이기 때문에 희소 벡터라고 한다.

또한 원-핫 인코딩의 결과를 원-핫 벡터라 한다.

 

원-핫 인코딩 과정

원-핫 인코딩을 하기 위해서는 단어 집합이라 불리는 사전을 먼저 만들어야 한다. 이 떄의 사전은, 텍스트에서 나오는 서로 다른 모든 단어의 집합을 의미한다.

단어 사전 내의 단어들은 위의 그림처럼 각각 고유한 원-핫 인코딩 벡터를 가진다.

 

from konlpy.tag import Okt
import numpy as np

okt = Okt()
text = '나는 자연어 처리를 배운다'

nouns = okt.nouns(text)
print(nouns)

# 단어 사전 생성 및 인덱스 부여
dics = {}
for word in nouns:
    if word not in dics.keys():
        dics[word] = len(dics)
print(dics)

# 원-핫 인코딩
# 원-핫 벡터 차원의 크기 결정 > 단어 사전의 크기가 원-핫 벡터의 크기가 되기 떄문
targets = list(dics.values())
one_hot_targets = np.eye(len(dics))[targets]
print(one_hot_targets)

 

결과

['나', '자연어', '처리']
{'나': 0, '자연어': 1, '처리': 2}
[[1. 0. 0.]
 [0. 1. 0.]
 [0. 0. 1.]]

 

+) 위 코드는 konlpy의 Okt로 진행을 했지만, Komorand으로 진행을 할 경우 '자연어'와 '처리'만 사전 구축이 된다.

 

원-핫 벡터의 경우, 구현 방법은 단순하다. 하지만 단어의 순서에 의한 인덱스값을 기반으로 인코딩된 값이기 때문에 단어의 의미나 유사한 단어와의 관계를 담고 있지 않다. 또한 사전의 크기가 커짐에 따라 원-핫 벡터의 차원도 커져, 메모리 낭비와 계산의 복잡도가 우려되며, 대부분의 요소가 0이기 때문에 비효율적이다.


2. Word2Vec

2013년 구글에서 발표한 Word2Vec은 가장 많이 사용하고 있는 단어 임베딩 모델이다. Word2Vec 모델은 CBOW(Continuous Bag-Of-Words)와 skip-gram 두 가지의 모델로 제안되었다.

 

2.1. CBOW

맥락이라고 표현되는 주변 단어들을 이용해 타깃 단어를 예측하는 신경망 모델이다. 신경망의 입력을 주변 단어들로 구성하고 출력은 타깃 단어로 설정해 학습된 가중치 데이터를 임베딩 벡터로 활용한다. 이 모델은 타깃 단어의 손실만 계산하면 되기 때문에 학습 속도가 빠르다는 장점이 있다.

 


2.2. skip-gram

CBOW 모델과는 반대로 하나의 타깃 단어를 이용해 주변 단어들을 예측하는 신경망 모델이다. 입출력이 CBOW 모델과 반대로 되어 있어, CBOW 모델에 비해 예측해야 하는 맥락이 많아진다. 때문에 단어 분산 표현력이 우수해 CBOW 모델에 비해 임베딩 품질이 우수하다. 

두 모델의 비교

위 그림을 보면 CBOW 모델은 타깃 단어를 예측하기 위해 앞뒤 단어를 확인한다. 이때 앞뒤로 몇 개의 단어까지 확인할지 결정하는 것이 윈도우며, 범위라고 보면 된다. 

 

 

 

+) 아직 배우는 단계라 내용이 많이 허술하다. 차차 내용을 추가 및 보완하겠다.