Word2Vec는 단어간 유사도를 반영하도록 단어의 의미를 벡터화하는 방법이며, CBOW와 Skip-Gram이 있다. CBOW는 주변의 단어를 통해 중간 단어를 예측하고 Skip-Gram은 중간 단어로 주변 단어를 예측한다. (Word2Vec의 입력은 원-핫 벡터)
간소화된 형태
중심 단어(center word): 예측할 단어
주변 단어(context word): 예측에 사용되는 단어
윈도우(window): 중심 단어를 예측하기 위해 앞, 뒤로 몇 개의 단어를 보는 범위
윈도우 크기가 n이면 실제 중심 단어를 예측하기 위해 참고하는 주변 단어의 개수는 2n(앞에서 n개, 뒤에서 n개)이다.
위의 그림 중 왼쪽 그림은 윈도우 크기가 2일때 슬라이딩 윈도우가 어떤 식으로 이루어지면서 데이터 셋을 만드는지를, 오른쪽 그림은 중심 단어와 주변 단어를 어떻게 선택했을 때 어떤 원-핫 벡터가 되는지를 보여준다.
[CBOW의 인공 신경망]입력층의 입력으로 윈도우 크기 범위 안의 주변 단어들의 원-핫 벡터가 들어가고 출력층에서 예측하고자 하는 중간 단어의 원-핫 벡터가 필요하다.
Word2Vec은 입력층과 출력층 사이에 하나의 은닉층만 존재하므로 딥러닝 모델이 아니다. 이처럼 은닉층이 1개인 경우는 얕은 신경망(shallow Neural Network)이라고 한다. Word2Vec의 은닉층은 룩업 테이블이라는 연산을 담당하는 투사층(projection layer)이다. (활성화 함수 없음)
위의 그림에서 주목할 부분은 두 가지이다. 첫째, CBOW에서 투사층의 크기 M은 임베딩한 후의 벡터의 차원와 같다. 둘째, 입력층과 투사층 사이의 가중치 W는 V x M 행렬이고 입력층과 투사층 사이의 가중치 W는 V × M 행렬이며, 투사층에서 출력층사이의 가중치 W'는 M × V 행렬이다. 여기서 V는 단어 집합의 크기이며, 두 가중치 행렬은 서로 다른 행렬이다. 가중치 행렬 W와 W'는 대게 굉장히 작은 랜덤 값을 가지며 주변 단어로 중심 단어를 더 정확히 맞추기 위해 계속해서 이 W와 W'를 학습해 간다.
입력인 주변 단어의 원-핫 벡터와 가중치 W 행렬의 곱은 W 행렬의 i번째 행을 그대로 읽어오는 것(lookup)이다. (이 과정이 룩업 테이블) 즉 lookup한 W의 각 행벡터가 Word2Vec을 수행한 후의 각 단어의 M차원의 크기를 갖는 임베딩 벡터이다. 따라서 가중치 행렬을 잘 훈련시키면 중심 단어를 더 정확히 맞출 수 있다.
주변 단어의 원-핫 벡터에 대해 가중치 W를 곱해서 얻은 벡터들은 투사층에서 이 벡터들의 평균 벡터를 구한다. 만약 윈도우 크기가 2라면 4개의 결과 벡터에 대해 평균을 구한다. (Skip-Gram과의 차이점)
위에서 구해진 평균 벡터는 두 번째 가중치 행렬 W'와 곱해지고 그 결과 원-핫 벡터와 차원이 V로 동일한 벡터가 나온다. 이 벡터에 소프트맥스 함수를 취해 스코어 벡터를 구한다. (소프트맥스 함수로 인한 출력값은 0~1 사이의 실수, 각 원소의 총합은 1)
스코어 벡터의 j번째 인덱스가 가진 0과 1 사이의 값은 j번째 단어가 중심 단어일 확률이다. 이 스코어 벡터와 중심 단어 원-핫 벡터(target word) 사이의 오차를 줄이기 위해 손실 함수로 cross-entropy 함수를 사용하고, 이 값을 최소화하는 방향으로 학습한다. 역전파를 수행해 W와 W'를 학습하고, 학습을 다한 후에 M차원의 크기를 갖는 W의 행이나 W'의 열로부터 어떤 것을 임베딩 벡터로 사용할지 결정한다. 때로 W와 W'의 평균치로 임베딩 벡터를 선택하기도 한다.
CBOW와 메커니즘은 동일하다. Skip-gram은 중심 단어에서 주변 단어를 예측한다. 윈도우 크기가 2일 때 데이터셋의 구성은 아래와 같다.
[Skip-gram의 인공 신경망]중심 단어에서 주변 단어를 예측하므로 투사층에서 벡터들의 평균을 구하는 과정은 없다. 논리적으로 CBOW가 더 좋아보이지만 실제에서는 Skip-gram이 더 성능이 좋다.
페이스북에서 개발한 단어를 벡터로 만드는 방법이며 매커니즘은 Word2Vec의 확장이다. 그러나 Word2Vec와 달리 FastText는 하나의 단어 안에 있는 내부 단어(subword)를 고려한다.
각 단어는 글자 단위 n-gram의 구성이다. n의 크기에 따라 내부 단어의 수가 결정된다. 어휘를 구성하는 n-gram마다 임베딩 벡터를 할당하고, 어휘를 구성하는 모든 n-gram 벡터의 평균 벡터를 어휘 임베딩으로 본다.
아래와 같이 시작과 끝을 의미하는 <, >을 도입하고 5개의 n-gram으로 쪼갠다. 5개의 내부 단어 토큰을 벡터로 만든다. 여기에 기존 단어에 <와 >를 붙인 특별 토큰을 벡터화킨다.
# n = 3인 경우
<ap, app, ppl, ple, le>, <apple>
여기서 내부 단어를 벡터화한다는 의미는 위의 단어들에 대해 Word2Vec을 수행한다는 의미이다. 내부 단어의 벡터값을 얻었다면 단어 apple의 벡터값은 위에서 구한 벡터값의 총 합이다.
apple = <ap + app + ppl + ppl + le> + <app + appl + pple + ple> + <appl + pple> + , ..., +<apple>
이런 방식을 사용하면 어휘 안에 포함된 다양한 요소를 n-gram 수준에서 학습하므로 동일한 의미를 갖는 어휘의 변화하는 패턴을 학습하기 쉽다.