Machine Learning

Word2Vec

뚜둔뚜둔 2020. 7. 13. 21:44

Word2Vec의 학습 방식

 단어 임베딩(embedding) 방법론인 Word2Vec

Word2Vec은 말 그대로 단어를 벡터로 바꿔주는 알고리즘입니다. Neural Network Language Model(NNLM)을 계승하면서도 학습 속도와 성능을 비약적으로 끌어올려 주목을 받고 있음.

 

Word2Vec의 Skip-Gram(중심단어로 주변단어 예측)

https://ratsgo.github.io/from%20frequency%20to%20semantics/2017/03/30/word2vec/

 

Word2Vec의 학습 방식 · ratsgo's blog

이번 포스팅에서는 최근 인기를 끌고 있는 단어 임베딩(embedding) 방법론인 Word2Vec에 대해 살펴보고자 합니다. Word2Vec은 말 그대로 단어를 벡터로 바꿔주는 알고리즘입니다. Neural Network Language Model(

ratsgo.github.io

주변단어로 중심단어를 예측하는 CBOW에 비해 Skip-gram의 성능이 좋은 이유가 바로 여기에 있습니다. 언뜻 생각하기에는 주변의 네 개 단어(윈도우=2인 경우)를 가지고 중심단어를 맞추는 것이 성능이 좋아보일 수 있습니다. 그러나 CBOW의 경우 중심단어(벡터)는 단 한번의 업데이트 기회만 갖습니다.

반면 윈도우 크기가 2인 Skip-gram의 경우 중심단어는 업데이트 기회를 4번이나 확보할 수 있습니다. 말뭉치 크기가 동일하더라도 학습량이 네 배 차이난다는 이야기이죠. 이 때문에 요즘은 Word2Vec을 수행할 때 Skip-gram으로 대동단결하는 분위기입니다.

 

Word2Vec은 중심단어와 주변단어 벡터의 내적이 코사인 유사도가 되도록 단어벡터를 벡터공간에 임베딩합니다. 학습 말뭉치를 만드는 방식이나 subsampling, negative sampling 등의 기법을 통해 성능은 끌어올리고 계산복잡성은 낮추었습니다. 은닉층이 하나인 뉴럴네트워크 구조이나 하이퍼볼릭탄젠트, 시그모이드 등 비선형 활성함수를 사용하지 않아서 사실상 선형모델인 점도 눈여겨볼 점인 것 같습니다. 성능과 계산복잡성 두 마리 토끼를 모두 잡는 데 성공했기 때문에 요즘 들어 많은 관심을 받고 있다고 생각합니다.

 

Word2Vec으로 문장 분류하기

Word2Vec의 효과는 놀랍습니다. 단어를 벡터화할 때 단어의 문맥적 의미를 보존하기 때문이죠. 위의 그림처럼 MAN과 WOMAN 사이의 거리는 KING과 QUEEN 거리와 유사합니다. 벡터로 바뀐 단어들은 ‘유클리디안 거리’니, ‘코사인 유사도’니 하는 방식들로 그 거리를 잴 수 있고 그 거리가 가까울(작을) 경우 의미가 비슷한 단어라고 해석할 수 있게 됩니다.

 

네거티브 샘플링(Negative Sampling)

대체적으로 Word2Vec를 사용한다고 하면 SGNS(Skip-Gram with Negative Sampling)을 사용합니다. Skip-gram을 사용하는데, 네거티브 샘플링(Negative Sampling)이란 방법까지 추가로 사용한다는 겁니다.

 

위에서 배운 Word2Vec 모델에는 한 가지 문제점이 있습니다. 바로 속도입니다. Word2Vec의 마지막 단계를 주목해봅시다. 출력층에 있는 소프트맥스 함수는 단어 집합 크기의 벡터 내의 모든 값을 0과 1사이의 값이면서 모두 더하면 1이 되도록 바꾸는 작업을 수행합니다. 그리고 이에 대한 오차를 구하고 모든 단어에 대한 임베딩을 조정합니다. 그 단어가 중심 단어나 주변 단어와 전혀 상관없는 단어라도 마찬가지 입니다. 그런데 만약 단어 집합의 크기가 수백만에 달한다면 이 작업은 굉장히 무거운 작업입니다.

여기서 중요한 건 Word2Vec이 모든 단어 집합에 대해서 소프트맥스 함수를 수행하고, 역전파를 수행하므로 주변 단어와 상관 없는 모든 단어까지의 워드 임베딩 조정 작업을 수행한다는 겁니다. 만약 마지막 단계에서 '강아지'와 '고양이'와 같은 단어에 집중하고 있다면, Word2Vec은 사실 '돈가스'나 '컴퓨터'와 같은 연관 관계가 없는 수많은 단어의 임베딩을 조정할 필요가 없습니다.

이를 조금 더 효율적으로 할 수 있는 방법이 없을까요? 전체 단어 집합이 아니라 일부 단어 집합에 대해서만 고려하면 안 될까요? 이렇게 일부 단어 집합을 만들어봅시다. '강아지', '고양이', '애교'와 같은 주변 단어들을 가져옵니다. 그리고 여기에 '돈가스', '컴퓨터', '회의실'과 같은 랜덤으로 선택된 주변 단어가 아닌 상관없는 단어들을 일부만 갖고옵니다. 이렇게 전체 단어 집합보다 훨씬 작은 단어 집합을 만들어놓고 마지막 단계를 이진 분류 문제로 바꿔버리는 겁니다. 즉, Word2Vec은 주변 단어들을 긍정(positive)으로 두고 랜덤으로 샘플링 된 단어들을 부정(negative)으로 둔 다음에 이진 분류 문제를 수행합니다.

이는 기존의 다중 클래스 분류 문제를 이진 분류 문제로 바꾸면서도 연산량에 있어서 훨씬 효율적입니다.

 

 

참고: https://ratsgo.github.io/from%20frequency%20to%20semantics/2017/03/30/word2vec/

참고: https://wikidocs.net/22660

반응형

'Machine Learning' 카테고리의 다른 글

[Book][doit_2]분산 학습  (0) 2022.02.06
NLP 를 위한 CNN  (0) 2020.07.14
Bert  (0) 2020.07.13
Confusion Matrix _ PYCM  (0) 2019.07.18
t-sne  (0) 2019.07.18