[CS224d] Lecture2. Word Vectors

How do we represent the meaning of a word?

“단어의 의미를 어떻게 표현해야 할까?”에 대한 고민은 예전부터 지속되어 왔다. 결국 사람이 단어나 몸짓으로 표현하는 것은 쉽지만 컴퓨터가 이를 이해하기는 어렵다. 마찬가지로 글쓰기, 미술 등으로 표현하는 것 또한 마찬가지이다.

과거에는 WordNet과 같은 방법을 사용했다. WordNet이란, 각 단어끼리의 관계(상위단어, 동의어) 가 나타나 있는 트리구조의 그래프 모형이다. 물론 이를 구축하기 위한 작업은 전부 사람이 했다. 그러다보니 주관적이고 유지하는데 있어 많은 노동이 필요하다는 한계가 존재했다.

Problems with this discrete representation

기존의 discrete representation에는 다음과 같은 문제점들이 존재한다. 우선, 아까와 같은 경우 리소스로는 충분하지만 뉘앙스가 부족하다. 비슷한 예로 동의어 문제가 있다. he's good / he's very proficient 와 같은 문장을 비교해보면, proficient는 보통 말을 능숙하게 하는 사람을 표현하듯이 문맥에 따라 의미가 달라질 것이다.

두번째 이유는 매번 신조어가 나타나는데 이를 최신화하기 어렵다. wicked, badass, ninjia… (미국에서 쓰는 신조어인듯 싶다.)

세번째 이유는 주관적이고 유지하는데 사람의 노동이 필요하다. 사람들이 직접 구축한 것이기 때문에 주관적이다. 특히 WordNet은 영어 이외의 언어에서 잘 구축된 경우가 별로 없다. (국내의 몇몇 대학원에서 구축된 것이 있지만 절대 공개하지 않는다…)

네번째, 단어 간의 유사도를 계산하기 어렵다. 어떤 단어가 어느정도 동의어인지 아닌지 계산하기도 어렵다는 말이다.

그래서 보통 Rule-based 와 통계적 NLP를 사용하는 모델들은 단어를 atomic symbol로써 사용한다. 예를 들어, 2만 개의 단어 중에 hotel 이라는 단어를 vector space로 나타낸다면, [0, 0, 0, 0, 0, 0, ..., 0, 0, 1, 0, 0, 0] 이런 식이다. (2만 개의 차원) 이러한 경우, motel 이라는 단어와 AND operation을 통해 유사도를 계산한다면 무조건 0이 나오게 될 것이다. (별로 좋지 않다)

이러한 벡터를 One-Hot Vector 라고 부르며, 이러한 NLP 방법론을 Bag of Words Representation 이라고 부른다.

Distributional similarity based representations

이 방법은 현대 통계적 NLP 방법론 중에서 가장 좋게 평가받는 모델 중 하나이다.

distributional

위 그림을 예로 들면, banking 이라는 단어를 표현할 때, 단어의 왼쪽과 오른쪽으로부터 banking이라는 단어의 정보를 얻는다. (dept, crises…) 이러한 방법을 통해 문맥으로부터 뭔가 더 얻을 수 있지 않을까? 라는 생각에서 출발한 모델이다.

How to make neighbors represent words?

그렇다면 어떻게 이웃된 정보를 표현할 수 있을까? cooccurrence matrix X를 통해 표현한다. 여기에는 2가지 옵션이 있는데 full document 와 window 이다.

  1. Full document matrix

    전체 문서의 matrix X를 통해 일반적인 토픽을 얻는다. 예를 들면, swimming / wet / boat / ship 은 문맥에 의해 어떤 하나의 공통된 토픽을 갖게 될 것이다. 대표적으로 Latent Semantic Analysis 와 같은 모델이 있다. (이 강의에서는 크게 다루지 않음)

  2. Window based matrix

    이 방법은 Window의 길이 (일반적으로 5 - 10) 에 따라 대칭적으로 이동하면서 확인하는 방법이다.

    • I like deep learning.
    • Iike NLP.
    • I enjoy flying

    위와 같은 corpus가 있을 때, 이를 matrix로 표현하면 다음과 같다. 간단히 보면 각 단어의 빈도 수를 체크한 것이다.

    matrix

Problems with simple cooccurrence vectors

이 방법의 문제점은 단어의 크기가 커지면 matrix의 차원이 엄청나게 커진다는 점이다. 여기에서 sparsity matrix란, 행렬의 요소가 대부분이 0인 행렬을 말한다. 이 문제를 해결하는 방법은 Low dimensional vector를 사용하는 것이다.

Method 1: Dimensionality Reduction on X

그렇다면 차원은 어떻게 낮출 수 있을까? 이에 대한 방법을 소개한다.

Singular Value Decomposition (SVD)

svd

​ SVD는 원래의 matrix X를 3개의 matrix로 분해한다. ​ 여기에서 n보다 훨씬 작은 값 k를 설정해서 top - k만 가져가고, ​ 그 이상의 차원은 날려버리는 방법으로 차원 축소를 해버린다. ​ 보통 이러한 decomposition 방식을 행렬 내의 dependancy를 풀어주기 위한 방법이라고 이해하면 쉽다. ​ dense matrix란, 앞에서 언급했던 sparse matrix와 반대되는 개념이다. (가득찬, 꽉찬)

몇 가지 질문을 통해 나온 내용을 정리하자면, SVD의 dimension은 실험을 통해 최적의 값을 찾아야 한다. 어떤 데이터셋이냐에 따라 다르다. 일반적으로 25에서 1000 사이의 차원으로 축소한다.

Hacks to X

아직 몇 가지 문제가 남아있다. function words (the, he, has)가 너무 빈번하게 나타나는데, 실제로는 이러한 단어가 큰 의미를 갖지 않는다. 하지만, count를 세게 되면 위와 같은 단어가 큰 영향을 미친다.

이를 해결하기 위한 방법은 다음과 같다.

  • corpus 자체에서 저런 단어를 모두 지운다.
  • min(X, t), with t~100 : min을 씌워 빈번하게 발생하는 단어의 영향력을 낮춘다. (100번이 넘으면 무조건 100으로 고정)
  • Ramped windows : window가 맞물려 있을 때 가까운 단어에 더 가중치를 준다.
  • Pearson correlations

Problems with SVD

SVD는 다음과 같은 문제가 있다. 우선 O() 의 복잡도를 갖기 때문에 Computational cost가 심하다. 따라서, 수 백만의 단어나 문서를 사용하는 경우 좋지 않다. 그리고 새로운 단어를 새로 적용하기가 어렵다. 매번 새로 돌려야 하며, 다른 딥러닝 모델과 학습체계가 다르다.

Word2Vec

Word2Vec은 처음부터 바로 낮은 차원의 word vectors를 학습시키자! 라는 아이디어에서 출발한다. 이전에는 cooccurrence를 직접 count 했다면, Word2Vec은 모든 단어에 대해 주변의 단어를 예측한다. 더 빠르고 쉽게 새로운 문장과 어울리며, 새로운 단어를 추가할 수도 있다. Word2Vec과 GloVe는 상당히 유사한데, Word2Vec은 구글에서 GloVe는 스탠포드에서 만들었다. 특히 강의자가 논문에 참여했기 때문에 강의 중간에 자랑이 많이 나온다.

초기논문 참고 : “Pennington 2014, Glove : Global Vectors for Word Representation”

window 크기만큼 양옆으로 확장해가며 sliding 방식으로 이동해서 전체 단어로 확장한다. Objective Function : 중심단어를 기준으로 log probability가 최대가 되도록 한다. wt가 나왔을 때, wt 주변의 단어가 나올 확률이 얼마나 되는지가 J(0)이다.

word2vec cost

  • window length : n
  • T token의 아주 큰 corpus
  • m만큼 좌우를 확인
  • 하나의 중심 단어로 주변의 단어를 찾는 probability를 최대화하는 것이 목표

word2vec cost

  • o : outside word id
  • c : center word id
  • u : outside vectors of o
  • v : center vectors of c

내적한 값은 단어 간의 유사도를 말하며, 분자가 최대한 높고 분모가 최대한 작은 것이 좋다. 항상 두개의 벡터가 나오는데 하나의 벡터는 outside word를 표현하고, 다른 하나의 벡터는 outside words를 예측하는데 사용한다.

50분부터 Chain Rule에 대한 설명 참조, 59분부터 log probability를 적용한 설명 참조

Negative Sampling

추가로 중간에 빼먹은 내용 (Slide 29) 중에 잠깐 Negative Sampling에 대한 내용이 나온다. 간단히 짚고 넘어가자면, 전체 데이터에서 샘플링 했을 떄 어차피 대부분은 연관이 없고(negative), 확실히 연관이 있는 것(positive)은 적다. 그래서 negative는 버리고 positive만 골라서 해도 비슷한 결과가 나온다. 실제로 속도는 빠르고 성능도 괜찮다고 한다.

Linear Relationships in word2vec

이러한 표현 방식은 유사도를 계산하는데 아주 좋은 결과를 보인다. 단순히 vector subtraction으로도 연산 가능하다.

한국어 word2vec 데모 : http://w.elnn.kr/search/

Count based vs Direct prediction

  1. Count based
  • LSA, HAL, COALS, PCA
  • Training 속도가 빠름
  • 통계기법을 효율적으로 사용
  • (단점) 단어의 유사도를 계산하는데만 사용 (Relationship 계산 불가)
  • (단점) count가 큰 경우에 불균등한 중요성이 주어짐 (?)

  1. Direct prediction
  • NNLM, HLBL, RNN, Skip-gram/CBOW
  • (단점) 말뭉치의 크기에 따라 Scale 가능
  • (단점) 통계기법을 활용하지 않음
  • 대부분의 영역에서 좋은 성능을 내는 모델 생성
  • 단어 유사도에 대해 복잡한 패턴도 잡아냄