워드 임베딩(Word Embedding)은 단어를 벡터로 표현하는 방법으로, 단어를 밀집 표현으로 변환한다.
원-핫 인코딩을 통해서 나온 원-핫 벡터들은 표현하고자 하는 단어의 인덱스의 값만 1이고, 나머지 인덱스에는 전부 0으로 표현되는 벡터 표현 방법이다.
강아지 [1,0,0]
고양이 [0,1,0]
말 [0,0,1]
벡터 또는 matrix의 값이 대부분이 0으로 표현되는 방법을 희소 표현이라고 한다. 원-핫 벡터는 희소 벡터이다. 이러한 희소 벡터의 문제점은 단어의 개수가 늘어나면 벡터의 차원이 한없이 커진다는 점이다. 원-핫 벡터로 표현할 때 코퍼스에 단어가 10,000개이면 벡터의 차원은 10,000이어야한다. 심단어의 인덱스에 해당되는 부분만 1이고 나머지는 0이다. 단어 집합이 클수록 고차원의 벡터가 된다. 아래가 예시이다.
# 1 뒤의 0의 수는 9995개
강아지 = [ 0 0 0 0 1 0 0 0 0 0 0 0 ... 0]
이것은 공간적 낭비를 불러일으킨다. 원-핫 벡터와 같은 희소 벡터의 문제점은 단어의 의미를 표현하지 못한다는 점이다.
희소 표현과 반대되는 표현으로 밀집 표현이 있다. 밀집 표현은 벡터의 차원을 단어 집합의 크기로 잡지 않는다. 사용자가 설정한 값으로 모든 단어의 벡터 표현의 차원을 맞춘다. 이 과정에서 더 이상 0과 1만 가진 값이 아니라 실수값을 가지게 된다.
# 1 뒤의 0의 수는 9995개. 차원은 10,000
강아지 = [ 0 0 0 0 1 0 0 0 0 0 0 0 ... 0]
10,000개의 단어가 있을 때 강아지란 단어를 표현하기 위해서는 위와 같은 표현을 사용했다. 하지만 밀집 표현을 사용면 사용자가 차원을 128로 설정한다면, 모든 단어의 벡터 표현의 차원은 128로 바뀌면서 모든 값이 실수가 된다. 이 경우 벡터의 차원이 조밀해졌다고 하여 밀집 벡터라고 한다.
# 차원은 128
Ex) 강아지 = [0.2 1.8 1.1 -2.1 1.1 2.8 ...]
단어를 밀집 벡터의 형태로 표현하는 것을 워드 임베딩이라고 한다. 밀집 벡터를 워드 임베딩 과정을 통해 나온 결과라고 하여 임베딩 벡터라고도 한다. 워드 임베딩 방법론으로는 LSA, Word2Vec, FastText, Glove 등이 있다. 케라스에서 제공하는 도구인 Embedding()는 앞서 언급한 방법들을 사용하지는 않지만, 단어를 랜덤한 값을 가지는 밀집 벡터로 변환한 뒤에, 인공 신경망의 가중치를 학습하는 것과 같은 방식으로 단어 벡터를 학습하는 방법을 사용한다.
단어 벡터 간 유의미한 유사도를 반영할 수 있도록 단어의 의미를 수치화 할 수 있는 방법이 워드투벡터(Word2Vec)이다.
분산 표현은 기본적으로 분포 가설에서 만들어진 표현 방법이다. 이 가정은 '비슷한 문맥에서 등장하는 단어들은 비슷한 의미를 가진다' 이다. 강아지란 단어는 귀엽다, 예쁘다, 애교 등의 단어가 주로 함께 등장한다. 따라서 해당 내용을 가진 텍스트의 단어들을 벡터화한다면 해당 단어 벡터들은 유사한 벡터값을 가진다. 분산 표현은 분포 가설을 이용하여 텍스트를 학습하고, 단어의 의미를 벡터의 여러 차원에 분산하여 표현한다.
이렇게 표현된 벡터들은 원-핫 벡터처럼 벡터의 차원이 단어 집합(vocabulary)의 크기일 필요가 없으므로, 벡터의 차원이 상대적으로 저차원으로 줄어듭니다.
요약하면, 희소 표현이 고차원에 각 차원이 분리된 표현 방법이면, 분산 표현은 저차원에 단어의 의미를 여러 차원에다가 분산하여 표현한다. 이런 표현 방법을 사용하면 단어 벡터 간 유의미한 유사도를 계산할 수 있다. 대표적인 학습 방법이 Word2Vec이다. Word2Vec의 학습 방식에는 CBOW(Continuous Bag of Words)와 Skip-Gram 두 가지 방식이 있다.
CBOW는 주변에 있는 단어들을 입력으로 중간에 있는 단어들을 예측하는 방법이다.
"The fat cat sat on the mat"
위와 같은 예문이 있다고 하자. ['The', 'fat', 'cat', 'on', 'the', 'mat'] 으로부터 sat을 예측하는 것은 CBOW가 하는 일이다. 이때 예측해야하는 단어 sat을 중심 단어(center word)라고 하고, 예측에 사용되는 단어들을 주변 단어(context word)라고 한다. 중심 단어를 예측하기 위해서 앞, 뒤로 몇 개의 단어를 볼지를 결정해야 하는데 이 범위를 윈도우(window)라고 한다. 예를 들어 윈도우 크기가 2이고, 예측하고자 하는 중심 단어가 sat이라고 한다면, 앞의 두 단어인 fat와 cat, 그리고 뒤의 두 단어인 on, the를 입력으로 사용한다. 윈도우 크기가 n이라고 한다면, 실제 중심 단어를 예측하기 위해 참고하려고 하는 주변 단어의 개수는 2n이다.
윈도우 크기가 정해지면 윈도우를 옆으로 움직여서 주변 단어와 중심 단어의 선택을 변경해가며 학습을 위한 데이터 셋을 만드는데 이 방법을 슬라이딩 윈도우(sliding window)라고 한다.
위 그림에서 좌측의 중심 단어와 주변 단어의 변화는 윈도우 크기가 2일때, 슬라이딩 윈도우가 어떤 식으로 이루어지면서 데이터 셋을 만드는지 보여준다. Word2Vec에서 입력은 모두 원-핫 벡터가 되어야 한다. 표는 중심 단어와 주변 단어를 어떻게 선택했을 때에 따라서 각각 어떤 원-핫 벡터가 되는지를 보여준다.
위 그림은 CBOW의 인공 신경망입니다. Input layer의 입력으로서 앞, 뒤로 사용자가 정한 윈도우 크기 범위 안에 있는 주변 단어들의 원-핫 벡터가 들어가게 되고, Output layer에서는 예측하고자 하는 중간 단어의 원-핫 벡터가 레이블이 나온다.
Skip-Gram은 중간에 있는 단어들을 입력으로 주변 단어들을 예측하는 방법이다. 예시로 윈도우 크기가 2일때를 보겠습니다.
인공 신경망은 다음과 같다. 중심 단어에 대해서 주변 단어를 예측하므로 투사층에서 벡터들의 평균을 구하는 과정은 없다. 전반적으로 Skip-gram이 CBOW보다 성능이 좋다고 알려져 있다.
임베딩 된 중심 단어와 주변 단어 벡터의 내적이 전체 코퍼스에서의 동시 등장 확률이 되도록 만드는 것
글로브(Global Vectors for Word Representation, GloVe)는 카운트 기반과 예측 기반을 모두 사용하는 방법론이다. 기존의 카운트 기반의 LSA(Latent Semantic Analysis)와 예측 기반의 Word2Vec의 단점을 보완한다는 목적으로 나왔다. 실제로도 Word2Vec만큼 뛰어난 성능을 보여준다. 단정적으로 Word2Vec와 GloVe 중에서 어떤 것이 더 뛰어나다고 말할 수는 없고, 두 가지 전부를 사용해보고 성능이 더 좋은 것을 사용하는 것이 바람직하다.
단어의 동시 등장 행렬은 행과 열을 전체 단어 집합의 단어들로 구성하고, i 단어의 윈도우 크기(Window Size) 내에서 k 단어가 등장한 횟수를 i행 k열에 기재한 행렬을 말합니다. 예제를 보면 어렵지 않습니다. 아래와 같은 3개 문서로 구성된 텍스트 데이터가 있다고 해봅시다.
윈도우 크기가 N일 때는 좌, 우에 존재하는 N개의 단어만 참고하게 됩니다. 윈도우 크기가 1일 때, 위의 텍스트를 가지고 구성한 동시 등장 행렬은 다음과 같습니다.
(작성중)
두 가지에 대해서 간혹 헷갈려 하는 사람들이 있다. 개념과 예시를 들면서 어떻게 다른지 알아보도록 하겠다.
word embedding을 수행하기 전에 어떠한 말뭉치데이터(Corpus)들을 다양한 기준을 가지고 분류 하는 행위를 토큰화(Tokenization)라고 하며 토큰화를 해주는 것을 Tokenizer라고 한다. 본 글에서는 word embedding에 대해서 집중적으로 다루고 있으니 자세한 설명은 생략하도록 한다.
컴퓨터가 자연어를 학습할 수 있도록 수치화하는 것을 워드 임베딩(word embedding)이라고 한다.