Books/한국어 임베딩

[Books] 행렬 분해 기반 언어 모델 (LSA, GloVe, Swivel)

언킴 2022. 3. 24. 20:31
반응형

Contents

    행렬 분해는 단어-문서 행렬이나 TF-IDF 행렬 등의 행렬 구조에 차원 축소 방법을 적용해 차원의 수를 줄여 계산 효율성을 키우고, 행간에 숨어 있는 잠재 의미를 파악하는 것이 목표다. 언어 모델이 가질 수 있는 행렬은 단어-문서 행렬, TF-IDF 행렬, 단어-문맥 행렬, 점별 상호 정보량(PMI) 등이 존재하는데, 이번 글에서는 PMI 행렬의 특수한 버전인 PPMI 행렬에 대해서 다루어볼 것이다. 

     

    PMI는 두 확률변수 사이의 상관성을 계량화한 지표이며, 두 단어의 등장이 독립을 가정했을 때 대비 얼마나 자주 같이 등장하는지를 수치화한 것이고, 수식은 다음과 같다. 

    \[ \text{PMI}(A,B) = \log \frac{\text{P}(A,B)}{\text{P}(A) \times \text{P}(B)} \] 

    $\text{P}(A) \times \text{P}(B)$는 두 단어가 독립이라고 가정했을 때의 조건부 확률이며, $\text{PMI}$가 음수가 될 경우 두 단어가 독립일 때보다 더 적은 빈도로 동시에 등장한다는 것을 의미한다. 하지만 보통 corpus에서의 단어 하나가 등장할 확률을 0.001 이하로 매우 작은 편인데, 두 단어가 동시에 나타날 확률은 엄청나게 작아야 한다. 또한 A,B가 단 한 번도 같이 등장하지 않을 경우 0의 값을 가지는데, $\log(0)$은 정의할 수 없기에 값을 구할 수 없다. 

     

    이와 같은 문제로 인해 자연어처리에서는 PMI 대신 PPMI(Positive Pointwise Mutual information)을 사용한다. PPMI는 0보다 작은 값은 전부 0으로 치환해 무시하는 방법이며, 수식은 다음과 같다. 

    \[ \text{PPMI}(A,B) = \max(\text{PMI}(A,B),0) \] 

    그 외 Shifted PMI(SPMI)도 있는데, 이는 $\text{PMI}$에서 $\log k$를 빼준 값을 의미하며, $^{\forall} k \in \mathbb{R}^+$이다. $\text{Shifted} \ \text{PMI}$는 $\text{Word2Vec}$과도 깊은 연관이 있다는 논문도 존재하며, $\text{SPMI}$의 수식은 다음과 같다. 

    \[ \text{SPMI}(A,B) = \text{PMI}(A, B) - \log k \] 

     

    LSA는 truncatedSVD로 차원을 축소해 분석을 수행할 수 있다. truncatedSVD는 특이값 가운데 가장 큰 d개의 특이값을 가지고 원래 행렬을 근사하는 방식이다. SVD에 대한 내용은 여기를 참고하면 보다 자세히 설명하고 있다. 

     

    SPMI, Word2Vec

    Levy and Goldbert는 네거티브 샘플링 기법으로 학습된 SGNS(Skip-gram with Negative Sampling) 모델의 학습은 SPMI 행렬을 $\text{U}$와 $\text{V}$로 분해하는 것과 같다는 것을 증명해 주목을 받았다.[논문] 다음과 같은 관계도가 존재한다. 

    \[ \text{A}^{\mathsf{SGNS}}_{ij} = \text{U}_i \cdot \text{V}_j = \text{PMI}(i,j) -\log k \] 

    여기서 $k$는 Skip-gram 모델의 네거티브 샘플 수를 의미한다. 네거티브 샘플 수가 1인 경우 Skip-gram은 PMI 행렬을 분해하는 것과 동일하다고 언급한다. 단어 $i$와 단어 $j$가 의미상 얼마나 관련이 있는지 정도가 $\text{U}_i$와 $\text{V}_j$ 내적 값으로 나타나며 관련성이 높을수록 당연히 내적의 값은 커지게 된다. 

     

    GloVe

    GloVe는 여기에 보다 상세기 작성해두었으니 참고하길 바란다. 간략히 설명하자면, 임베딩된 두 단어 벡터의 내적이 말뭉치 전체에서의 동시 출현 빈도의 로그 값이 되도록 목적 함수(Object Function)을 정의했다. 임베딩된 단어 벡터 간 유사도 측정을 수월하게 하면서도 말뭉치 전체의 통계 정보를 잘 반영하자는 목표를 지향한다. 

    \[ \mathcal{J} = \sum^{|V|}_{i,j=1} f(\text{A}_{ij})(\text{U}_i \cdot \text{V}_j + \text{b}_i + \text{b}_j -\log \text{A}_{ij})^2 \] 

    $\text{b}$와 $f(\text{A}_{ij})$는 임베딩 품질을 높이기 위해 고안된 장치이다. 동시 출현 빈도의 로그 값을 구하기 위해서는 먼저 동시 출현 빈도 행렬을 구축해야 한다. 처음에는 $\text{U}$와 $\text{V}$를 랜덤으로 초기화한 후 목적 함수를 최소화하는 방향으로 학습해 나간다. 이외에 $\text{U} + \text{V}^T$, $\text{U}$와 $\text{V}^T$를 이어 붙여 임베딩으로 사용하기도 한다. 

     

     

    Swivel

    Swivel (Submatrix-Wise Vector Embedding Learner)은 구글에서 2016년 발표한 행렬 분해 기반 임베딩 기법이다. $\text{PMI}$ 행렬을 $\text{U}$와 $\text{V}$로 분해하고, 학습이 완료되면 $\text{U}$를 단어 임베딩으로 사용할 수 있다. 이처럼 단어-문맥 행렬이 아닌 PMI 행렬을 분해한다는 점에서 GloVe와는 다른 방법이다. 

    \[ \mathcal{J} = \frac{1}{2} f(x_{ij})(\text{U}_i \cdot \text{V}_j - \text{PMI}(i,j))^2 \] 

    하지만 $\text{PPMI}$ 행렬이 아닌 $\text{PMI}$ 행렬은 두 단어가 한 번도 동시에 등장하지 않았을 때 $\text{PMI}$는 음의 무한대로 발산하기에 이와 같은 케이스에 한해 다음과 같이 목적함수를 별도로 설정했다. 

    \[ \mathcal{J} = \log(1+ \exp(\text{U}_i \cdot \text{V}_j - \text{PMI}^*(i,j))) \] 

    \[ \begin{equation} \begin{split} \text{PMI}(i,j) & = \log \frac{\text{P}(i,j)}{\text{P}(i) \times \text{P}(j)} \\ \\ & = \log \frac{\text{A}_{ij} /|D| }{\text{A}_{i*}/|D| \times \text{A}_{*j}/|D|} \\ \\ & = \log \frac{\text{A}_{ij} \times |D| }{\text{A}_{i*} \times \text{A}_{*j}} \\ \\ & = \log \text{A}_{ij} + \log |D| - \log \text{A}_{i*} - \log \text{A}_{*j} \end{split} \end{equation} \] 

    $|D|$는 corpus의 길이를 의미하고, $\text{A}_{i*}, \text{A}_{*j}$는 각각 $i$의 단독 빈도, $j$의 단독 빈도를 의미한다. $\text{P}(i,j)$는 $i$와 $j$가 동시에 출현할 확률을 의미하기에 $\text{A}_{ij}$와 $|D|$로 표현할 수 있을 것이며, 나머지 확률도 동일하게 구할 수 있다. 위 수식을 목적함수에 대입하면 다음과 같다. 

    \[ \mathcal{J} = \log(1 + \exp(\text{U}_i \cdot \text{V}_j - \log|D| + \log \text{A}_{i*} + \log \text{A}_{*j})) \]

    본 논문에서는 학습하기에 앞서 다음과 같은 두 가지 가정을 가지고 학습을 수행한다. 

     

    1. $i,j$가 각각의 빈도 수는 높지만, 동시 출현 빈도 수가 0이라면 두 단어는 의미상 무관계한 단어일 것이다.

    2. $i,j$가 각각의 빈도 수가 낮고, 동시 출현 빈도 수가 0이라면 두 단어는 의미상 관계가 일부 존재할 것이다.

     

    첫 번째의 경우 직관적으로 이해할 수 있다. 두 번째의 경우에는 두 단어의 빈도 수가 적은 것이 우리의 데이터 확보가 적기 때문에 빈도 수가 적게 나타난 것 일수도 있기에 일부 관계가 있다고 판단해 학습을 할 때 약간 크게 되도록 학습을 수행한다. 

     

    LSA와 GloVe, Swivel의 코드는 여기를 참고하면 된다.