[NLP] 워드 임베딩 (Word Embedding) 개요

이 글은 희소 표현, 밀집 표현, 그리고 워드 임베딩(Word Embedding)에 관한 기록입니다.

1. 희소 표현 (Sparse Representation)

희소 표현(Sparse Representation)은 벡터 또는 행렬의 값이 대부분 0으로 표현되는 방법을 말합니다. 원-핫 인코딩을 통해서 나온 원-핫 벡터는 표현하고자 하는 단어의 인덱스 값만 1이고 나머지 인덱스 값은 모두 0으로 표현되는 벡터 표현 방법입니다. 즉 원-핫 인코딩은 희소 표현(Sparse Representation) 이고, 원-핫 벡터는 희소 벡터(sparse vector)라고 할 수 있습니다.

이러한 희소 벡터의 문제점은 단어의 개수가 늘어나면 벡터의 차원이 한없이 커진다는 점입니다. 원-핫 인코딩을 통해 단어를 표현할 경우, 코퍼스에 존재하는 단어가 10000개라면 벡터의 차원 또한 10000이 되는데, 심지어 그 중에서 단어의 인덱스에 해당되는 부분만 1이고 나머지는 0의 값을 가지게 됩니다. 다시 말해 원-핫 인코딩의 경우 단어 집합이 클수록 고차원의 벡터가 됩니다. 예를 들어 단어가 10000개 있고 강아지라는 단어의 인덱스는 5였다면 원-핫 벡터는 이렇게 표현됩니다.

강아지 = [ 0 0 0 0 1 0 0 0 0 0 0 0 ... 중략 ... 0] # 이 때 1 뒤의 0의 수는 9995개

이러한 벡터 표현은 공간적 낭비를 불러일으킵니다. 공간적 낭비를 일으키는 것은 원-핫 벡터 뿐만 아니라 DTM 또한 마찬가지입니다. 희소 표현의 일종인 DTM에서도 특정 문서에 여러 단어가 다수 등장하였으나, 다른 많은 문서에서는 해당 특정 문서에 등장했던 단어들이 전부 등장하지 않는다면 역시나 행렬의 많은 값이 0이 되면서 공간적 낭비를 일으킵니다.

원-핫 벡터는 단어의 의미를 담지 못하여 단어 벡터 간 유사도를 표현할 수 없다는 문제점도 가지고 있습니다. 예를 들어 dog, cat, computer, netbook, book 5개의 단어에 대해서 원-핫 인코딩을 한다고 가정해봅시다. 우선 이 단어들에 0, 1, 2, 3, 4라는 고유한 정수를 부여합다. 그리고 나서 단어의 개수가 5개이므로 벡터의 차원으로 5로 하고 부여된 각 고유한 정수를 인덱스로 하여 해당 인덱스에는 1, 나머지는 0의 값을 채워넣습니다. 이를 코드로 표현하면 아래와 같습니다.

import torch
# 원-핫 벡터 생성
dog = torch.FloatTensor([1, 0, 0, 0, 0])
cat = torch.FloatTensor([0, 1, 0, 0, 0])
computer = torch.FloatTensor([0, 0, 1, 0, 0])
netbook = torch.FloatTensor([0, 0, 0, 1, 0])
book = torch.FloatTensor([0, 0, 0, 0, 1])
# 유사도 출력
print(torch.cosine_similarity(dog, cat, dim=0))
print(torch.cosine_similarity(cat, computer, dim=0))
print(torch.cosine_similarity(computer, netbook, dim=0))
print(torch.cosine_similarity(netbook, book, dim=0))
tensor(0.)
tensor(0.)
tensor(0.)
tensor(0.)

사람이 생각하기에, 강아지와 고양이라는 단어의 유사도는 고양이와 컴퓨터라는 단어의 유사도보다 높을 것이고, 컴퓨터와 넷북이라는 단어의 유사도는 넷북과 책이라는 단어의 유사도보다 높을 것입니다. 하지만 위에서 확인할 수 있듯이 어떠한 단어들을 선택하여 코사인 유사도를 구하더라도 이들 간의 유사도는 전부 동일합니다. 이렇게 단어 간 의미적 유사도를 반영할 수 없다는 점은 자연어 처리에서 치명적인 단점으로 작용합니다.

2. 밀집 표현(Dense Representation)

이러한 희소 표현(Sparse Representation)과 반대되는 표현으로 밀집 표현(Dense Representation)이 있습니다. 단어 집합의 크기가 벡터의 차원이 되는 희소 표현과 달리, 밀집 표현에서는 사용자가 설정한 값으로 벡터의 차원을 맞출 수 있습니다. 또한 이 과정에서 더 이상 0과 1만을 값으로 갖는 것이 아니라 실수를 값으로 갖게 됩니다.

예를 들어, 10000개의 단어가 있을 때 강아지라는 단어를 표현한다고 가정해봅시다. 이를 희소 표현으로 나타내면 다음과 같습니다.

강아지 = [ 0 0 0 0 1 0 0 0 0 0 0 0 ... 중략 ... 0] # 이 때 1 뒤의 0의 수는 9995개, 차원은 10000

한편 사용자가 밀집 표현의 차원을 128로 설정하고 강아지라는 단어를 밀집 표현으로 나타내면 다음과 같습니다.

강아지 = [0.2 1.8 1.1 -2.1 1.1 2.8 ... 중략 ...] # 차원은 128

벡터의 차원이 128로 바뀌면서 모든 값이 실수가 되는 것을 확인할 수 있습니다. 이때 벡터의 차원이 조밀해졌다고 하여 이를 밀집 벡터(dense vector)라고 합니다.

3. 워드 임베딩 (Word Embedding)

워드 임베딩 개념

워드 임베딩(Word Embedding)은 단어를 밀집 벡터(dense vector)의 형태로 표현하는 방법을 말합니다. 이때 이 밀집 벡터를 워드 임베딩을 통해 나온 결과라고 하여 임베딩 벡터(embedding vector)라고 합니다.

원-핫 벡터와 임베딩 벡터의 차이점

  원-핫 벡터 임베딩 벡터
차원 고차원 (단어 집합의 크기) 저차원 (사용자 설정)
다른 표현 희소 벡터의 일종 밀집 벡터의 일종
표현 방법 수동 훈련 데이터로부터 학습
1과 0 실수

워드 임베딩 방법론

워드 임베딩 방법론으로는 LSA, Word2Vec, FastText, Glove 등이 있습니다. 파이토치의 nn.Embedding()은 단어를 랜덤한 값을 가지는 밀집 벡터로 변환한 후 인공신경망의 가중치를 학습하는 것과 같은 방식으로 단어 벡터를 학습하는 방법을 사용합니다.

댓글남기기