解析詞向量 4 word2vec的本質和Glove

這篇文章講的是:

  • 從現象看本質 - word2vec也是PMI矩陣分解
  • Glove - 從另外的角度思考

從現象看本質 - word2vec也是PMI矩陣分解
word2vecl取得很不錯的效果,使得大家很好奇,神經網絡到底提取了什麽,學到了什麽,導致能得到如此好的結果?這個模型得到的向量,背後的本質是什麽?
Neural Word Embedding as Implicit Matrix Factorization - 這篇論文有一個很好的分析

我們用最具代表性的 Skip-gram和Negative Sampling這一組合作爲Word2Vec的模型
回想一下,大致要學的是這樣的東西:

https://slideplayer.com/slide/11177114/

使得將中心詞預測上下文詞機率最大,同時從中心詞預測上下文抽樣的詞機率最小。
從前文也知道,word2vec的訓練,最終會得到兩個矩陣,一個是中心詞的矩陣,另一個則是上下文詞的矩陣。
我們也可以把word2vec的訓練看成矩陣化簡,從一個大矩陣化簡出以上的兩個矩陣。
那個大矩陣所學到的,按照word2vec的想法是詞與詞之間的關係,這個關係是建立在上下文詞之上。也就是說,在中心詞附近會是由比較親密的關係,不在中心詞附近的,關係會比較疏遠。

在中心詞的附近,越常出現就越容易得到接近1的分數。這個跟我們之前談到的PMI是不是很有有殊途同歸的感覺。PMI建立起 是否一起出現跟獨立無關 的一個比值,跟word2vec所做的很像。

經過論文的推導,也果然如此:

從word2vec的目標函數可以化簡得出:

這個也就是PMI,再根據之前提到的兩個矩陣,最終可以有:

也就是說,word2vec是在做PMI的化簡!

word2vec是基於上下文的詞,這個上下文的範圍也叫Windows size,Windows size以外的詞在模型中會被當成負樣本。也就是說,在Windows size之外,跟中心詞相關的詞有可能被排除。

Glove - 從另外的角度思考
那麽能不能將Windows size設置到全局大小,同時複雜度不會上升太誇張?
Glove提供了另外的思路。

Glove的整個思路總結在這張圖中:

首先看第一個row,跟ice相關的字,在條件概率下,值會越大
\(P(water|ice) > P(solid|ice) > P(gas|ice) > P(fashion|ice)\)
第二個row,也是同理
\(P(water|steam) > P(gas|steam) > P(solid|steam) > P(fashion|steam)\)

拿這些條件概率的比值,可以將其差距擴大。
推廣到所有的詞,我們可以得到:\(\frac{P(k|i)}{P(k|j)}\)

  • k跟i相關,值會大於1
  • k跟j相關,值會遠小於1
  • k跟i,j關係不大,值會接近1

利用這個關係,建立詞與詞的全局矩陣,然後用矩陣化簡的方式化簡。這個就是Glove的做法~
可是我們以上的矩陣涉及到三個詞,建立全局矩陣,複雜度會是\(N^3\),太高了,因此需要化簡:

我們的目標是建立一個模型,輸入三個詞的向量,得到
\(\frac{P(k|i)}{P(k|j)}\)
也就是
\(Glove(v_{i},v_{j},v_{k}) = \frac{P(k|i)}{P(k|j)}\)

考慮到目標是k在不同前設下的比值,而比值是爲了放大差異,也可以換成向量間的差
\(Glove((v_{i} - v_{j})^{T},v_{k}) = \frac{P(k|i)}{P(k|j)}\)

我們最終的結果是一個數字,在矩陣的情況,很自然想到dot product
\(Glove((v_{i} - v_{j})^{T} \cdot v_{k}) = Glove(v_{i}^{T} \cdot v_{k} - v_{j}^{T} \cdot v_{k}) = \frac{P(k|i)}{P(k|j)}\)

我們可以推測一下Glove這個function將會做什麽:
Dot product 是 \(a \cdot b = |a| \times |b| \times cos(\Theta)\),cos 的範圍是 1 到 -1,而最終結果是機率,因此要把負值去掉
Glove的想法是變成 \(e^X\),再加一個偏置項使得x是正數,結果也可以在0-1之間

https://www.youtube.com/watch?v=Y1dT58oJ1JQ

因此可以得出
\(e^{(v_{i}^{T} \cdot v_{k} - v_{j}^{T} \cdot v_{k})} = \frac{P(k|i)}{P(k|j)}\)
對調一下
\(v_{i}^{T} \cdot v_{j} = ln(P_{i,j})\)

Loss Function就會是最小化
\((v_{i}^{T} \cdot v_{j} - ln(P_{i,j}))^2\)

但是,當i,j調轉,也就是中心詞互換的時候,不會相等:
\(v_{j}^{T} \cdot v_{i} = ln(P_{j,i}) \neq ln(P_{i,j})\)

這裏的trick就是加一個bias,使得他們相等,而這個bias交由網絡去尋找:
Loss Function會變成
\((v_{i}^{T} \cdot v_{j}+b_{i}+b_{j} - ln(P_{i,j}))^2\)

在詞與詞之間怎麽樣也可以得到一個值,我們關注的重點會是詞頻大的常見詞,減少那些罕見詞的影響,因此就多加了一項權重
\(f(Xij) (v_{i}^{T} \cdot v_{j}+b_{i}+b_{j} - ln(P_{i,j}))^2\)

\(v_{i},v_{j}\)跟word2vec一樣,被當成是兩套不一樣的詞向量,因此loss function會是
\(f(Xij) (v_{i}^{T} \cdot \tilde{v_{j}}+b_{i}+\tilde{b_{j}} - ln(P_{i,j}))^2\)

Glove和word2vec的本質都是對於詞共現的建模,相比word2vec,glove另闢蹊徑建立全局詞共現模型,在論文中得出不錯的結果。
在實際應用上,還有考慮到工具使用的難易程度,數據預處理的方式,參數的調節等,往往沒有唯一最好的方法。
個人經驗而言,詞向量的效果更多取決於前處理,而不是哪一個方法或參數XD

Reference
https://nlp.stanford.edu/pubs/glove.pdf