NLP教程(1) | 詞向量、SVD分解與Word2Vec

語言: CN / TW / HK

ShowMeAI研究中心


詞向量、SVD分解與Word2vec 本系列為斯坦福CS224n《自然語言處理與深度學習(Natural Language Processing with Deep Learning)》的全套學習筆記,對應的課程影片可以在 這裡 檢視。

NLP介紹與詞向量初步 ShowMeAI為CS224n課程的全部課件,做了中文翻譯和註釋,並製作成了GIF動圖!點選 這裡 檢視“第1講-NLP介紹與詞向量初步”的課件註釋與帶學解讀。更多資料獲取方式見文末。

引言

CS224n是頂級院校斯坦福出品的深度學習與自然語言處理方向專業課程,核心內容覆蓋RNN、LSTM、CNN、transformer、bert、問答、摘要、文字生成、語言模型、閱讀理解等前沿內容。

本篇筆記對應斯坦福CS224n自然語言處理專項課程的第1個知識板塊:NLP與詞向量。首先介紹了自然語言處理(NLP)的概念及其面臨的問題,進而介紹詞向量和其構建方法(包括基於共現矩陣降維和Word2Vec)。

內容要點

  • 自然語言處理/Natural Language Processing(NLP)
  • 詞向量/Word Vectors
  • SVD矩陣分解
  • Skip-gram
  • 負例取樣
  • transformer
  • CBOW
  • 層次化softmax
  • Word2Vec

1.自然語言處理介紹

1.1 自然語言處理的特別之處

人類的語言有什麼特別之處?人類語言是一個專門用來表達意義的系統,語言文字是上層抽象表徵,NLP與計算機視覺或任何其他機器學習任務都有很大的不同。

大多數單詞只是一個語言學以外的符號:單詞是一個對映到所指(signified 想法或事物)的能指(signifier)。例如,“rocket”一詞指的是火箭的概念,因此可以引申為火箭的例項。當我們使用單詞和字母來表達符號時,也會有一些例外,例如“whoompaa”的使用。

最重要的是,這些語言的符號可以被編碼成幾種形式:聲音、手勢、文字等等,然後通過連續的訊號傳輸給大腦;大腦本身似乎也能以一種連續的方式對這些訊號進行解碼。人們在語言哲學和語言學方面做了大量的工作來概念化人類語言,並將詞語與其參照、意義等區分開來。

❐ Natural language is a discrete[離散的] / symbolic[符號的] / categorical[分類的] system.

1.2 自然語言處理任務

自然語言處理有不同層次的任務,從語言處理到語義解釋再到語篇處理。自然語言處理的目標是通過設計演算法使得計算機能夠“理解”語言,從而能夠執行某些特定的任務。不同的任務的難度是不一樣的:

1) 簡單任務

  • 拼寫檢查 Spell Checking
  • 關鍵詞檢索 Keyword Search
  • 同義詞查詢 Finding Synonyms

2) 中級任務

  • 解析來自網站、文件等的資訊

3) 複雜任務

  • 機器翻譯 Machine Translation
  • 語義分析 Semantic Analysis
  • 指代消解 Coreference
  • 問答系統 Question Answering

1.3 如何表徵詞彙

在所有的NLP任務中,第一個也是可以說是最重要的共同點是我們如何將單詞表示為任何模型的輸入。在這裡我們不會討論早期的自然語言處理工作是將單詞視為原子符號 atomic symbols。

為了讓大多數的自然語言處理任務能有更好的表現,我們首先需要了解單詞之間的相似和不同。有了詞向量,我們可以很容易地將其編碼到向量本身中。

(本部分內容也可以參考ShowMeAI的對吳恩達老師課程的總結文章深度學習教程 | 自然語言處理與詞嵌入

2.詞向量

使用詞向量編碼單詞, $N$ 維空間足夠我們編碼語言的所有語義,每一維度都會編碼一些我們使用語言傳遞的資訊。

簡單的one-hot向量無法給出單詞間的相似性,我們需要將維度 $\left | V \right |$ 減少至一個低緯度的子空間,來獲得稠密的詞向量,獲得詞之間的關係。

3.基於SVD降維的詞向量

(關於降維演算法可以閱讀ShowMeAI的機器學習教程文章圖解機器學習 | 降維演算法詳解,也可以通過ShowMeAI的機器學習實戰文章機器學習實戰 | 機器學習特徵工程最全解讀關於降維的python應用方法)

基於詞共現矩陣與SVD分解是構建詞嵌入(即詞向量)的一種方法。

  • 我們首先遍歷一個很大的資料集和統計詞的共現計數矩陣 $X$
  • 然後對矩陣 $X$ 進行SVD分解得到 $USV^T$
  • 再然後我們使用 $U$ 的行來作為字典中所有詞的詞向量

接下來我們討論一下矩陣 $X$ 的幾種選擇。

3.1 詞-文件矩陣

最初的解決方案是基於詞-文件共現矩陣完成的。我們猜想相關連的單詞在同一個文件中會經常出現:

  • 例如,“banks”,“bonds”,“stocks”,“moneys”等等,出現在一起的概率會比較高
  • 但是,“banks”,“octopus”,“banana”,“hockey”不大可能會連續地出現

我們根據這個情況來建立一個Word-Document矩陣, $X$ 是按照以下方式構建:遍歷數億的文件和當詞 $i$ 出現在文件 $j$ ,我們對 $X_{ij}$ 加一。

這顯然是一個很大的矩陣 $\mathbb{R}^{ \left | V \right | \times M}$ ,它的規模是和文件數量 $M$ 成正比關係。因此我們可以嘗試更好的方法。

3.2 基於滑窗的詞共現矩陣

全文件統計是一件非常耗時耗力的事情,我們可以進行調整對一個文字窗內的資料進行統計,計算每個單詞在特定大小的視窗中出現的次數,得到共現矩陣 $X$ 。

下面為一個簡單示例,我們基於滑窗(前後長度為1)對文字進行共現矩陣的構建。

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

基於滑窗的詞共現矩陣

使用單詞共現矩陣

  • 生成維度為 $\left | V \right |\times \left | V \right |$ 的共現矩陣 $X$

  • 在 $X$ 上應用SVD從而得到 $X = USV^T$

  • 選擇 $U$ 前 $k$ 行得到 $k$ 維的詞向量

  • $\frac{\sum_{i=1}^{k} \sigma_i}{\sum_{i=1}^{ \left | V \right |} \sigma_i}$ 表示第一個 $k$ 維包含的方差量

3.3 應用SVD對共現矩陣降維

  • 我們對矩陣 $X$ 使用SVD,觀察奇異值(矩陣 $S$ 上對角線上元素),根據方差百分比截斷,留下前 $k$ 個元素:

$$ \frac{\sum_{i=1}^{k} \sigma_i}{\sum_{i=1}^{ \left | V \right |} \sigma_i} $$

  • 然後取子矩陣 $U_{1: \left | V \right |, 1:k}$ 作為詞嵌入矩陣。這就給出了詞彙表中每個詞的 $k$ 維表示。

對矩陣 $X$ 使用SVD

對矩陣 X 使用SVD

通過選擇前 $k$ 個奇異向量來降低維度

通過選擇前 k 個奇異向量來降低維度

前面提到的方法給我們提供了足夠的詞向量來編碼語義和句法(part of speech)資訊,但也帶來了一些問題:

  • 矩陣的維度會經常發生改變(經常增加新的單詞和語料庫的大小會改變)
  • 矩陣會非常的稀疏,因為很多詞不會共現
  • 矩陣維度一般會非常高 $\approx 10^6 \times 10^6$
  • 需要在 $X$ 上加入一些技巧處理來解決詞頻的極劇的不平衡

❐ 基於SVD的方法的計算複雜度很高( $m \times n$ 矩陣的計算成本是 $O({mn}^2)$ ),並且很難合併新單詞或文件。

對上述討論中存在的問題存在以下的解決方法

  • 忽略功能詞,例如“the”,“he”,“has”等等
  • 使用ramp window,即根據文件中單詞之間的距離對共現計數進行加權
  • 使用皮爾遜相關係數並將負計數設定為 $0$ ,而不是隻使用原始計數

❐ 基於計數的方法可以有效地利用統計量,但下述基於迭代的方式可以在控制複雜度的情況下有效地在大語料庫上構建詞向量。

4.迭代優化演算法 - Word2Vec

(本部分內容也可以參考ShowMeAI的對吳恩達老師課程的總結文章 深度學習教程 | 自然語言處理與詞嵌入

Word2Vec是一個迭代模型,該模型能夠根據文字進行迭代學習,並最終能夠對給定上下文的單詞的概率對詞向量進行編碼呈現,而不是計算和儲存一些大型資料集(可能是數十億個句子)的全域性資訊。

這個想法是設計一個模型,該模型的引數就是詞向量。然後根據一個目標函式訓練模型,在每次模型的迭代計算誤差,基於優化演算法調整模型引數(詞向量),減小損失函式,從而最終學習到詞向量。

大家知道在神經網路中對應的思路叫“反向傳播”,模型和任務越簡單,訓練它的速度就越快。

❐ 基於迭代的方法一次捕獲一個單詞的共現情況,而不是像SVD方法那樣直接捕獲所有的共現計數。

已經很多研究者按照這個思路測試了不同的方法。[Collobert et al., 2011] 設計的模型首先將每個單詞轉換為向量。對每個特定的任務(命名實體識別、詞性標註等等),他們不僅訓練模型的引數,同時也訓練單詞向量,計算出了非常好的詞向量的同時取得了很好的效能。

一個非常有效的方法是Word2Vec。Word2Vec是google開源的軟體包,包含以下核心內容:

  • 兩個演算法:continuous bag-of-words(CBOW)和skip-gram

    • CBOW是根據中心詞周圍的上下文單詞來預測該詞的詞向量
    • skip-gram則相反,是根據中心詞預測周圍上下文的詞的概率分佈。
  • 兩個訓練方法:negative sampling和hierarchical softmax

    • Negative sampling通過抽取負樣本來定義目標
    • hierarchical softmax通過使用一個有效的樹結構來計算所有詞的概率來定義目標

❐ Word2Vec依賴於語言學中一個非常重要的假設「分佈相似性」,即相似的詞有相似的上下文。

4.1 語言模型

我們先來了解一下語言模型。從一個例子開始:

我愛學習自然語言處理技術

一個好的語言模型會給這個句子很高的概率,因為在句法和語義上這是一個完全有效的句子。相似地,句子 自然學習愛處理語言我技術 會得到一個很低的概率,因為這是一個無意義的句子。

在數學上,我們可以稱為對給定 $n$ 個詞的序列的概率是:

$$ P(w_1, w_2, \cdots, w_n) $$

在一元語言模型方法(Unigram model)中,我們假設單詞的出現是完全獨立的,從而分解概率

$$ P(w_1, w_2, \cdots, w_n)=\prod_{i=1}^{n} P(w_i) $$

嚴謹一點說,上述假設是不合理的,因為下一個單詞是高度依賴於前面的單詞序列的。如果使用上述的語言模型,可能會讓一個無意義的句子具有很高的概率。所以我們讓序列的概率取決於序列中的單詞和其旁邊的單詞的成對概率。我們稱之為bigram模型:

$$ P(w_1, w_2, \cdots, w_n)=\prod_{i=2}^{n} P(w_i \mid w_{i-1}) $$

確實,只關心鄰近單詞還是有點簡單,大家考慮連續的n個詞共現會得到n-gram。但即使使用bigram都可以帶來相對unigram顯著的提升。考慮在詞-詞共現矩陣中,共現視窗為 $1$ ,我們基本上能得到這樣的成對的概率。但是,這又需要計算和儲存大量資料集的全域性資訊。

既然我們已經理解了如何考慮具有概率的單詞序列,那麼讓我們觀察一些能夠學習這些概率的示例模型。

4.2 CBOW連續詞袋模型

這一方法是把 {"我","愛","學習","自然語言處理","技術"} 作為上下文,希望從這些詞中能夠預測或者生成中心詞 學習。這樣的模型我們稱之為continuous bag-of-words(CBOW)模型。

❐ CBOW是從上下文中預測中心詞的方法,在這個模型中的每個單詞,我們希望學習兩個向量

  • $v$ (輸入向量,即上下文詞)
  • $u$ (輸出向量,即中心詞)

模型輸入是one-hot形式的詞向量表示。輸入的one-hot向量或者上下文我們用 $x^{(c)}$ 表示,輸出用 $y^{(c)}$ 表示。在CBOW模型中,因為我們只有一個輸出,因此我們把 $y$ 稱為是已知中心詞的的one-hot向量。

下面我們定義模型的未知引數

我們建立兩個矩陣, $\mathcal{V}\in \mathbb{R}^{n\times \left | V \right |}$ 和 $\mathcal{U}\in \mathbb{R}^{ \left | V \right |\times n}$ 。其中:

  • $n$ 是嵌入空間的任意維度大小

  • $\mathcal{V}$ 是輸入詞矩陣,使得當其為模型的輸入時, $\mathcal{V}$ 的第 $i$ 列是詞 $w_i$ 的 $n$ 維嵌入向量,定義這個 $n \times 1$ 的向量為 $v_i$

  • 相似地, $\mathcal{U}$ 是輸出詞矩陣。當其為模型的輸入時, $\mathcal{U}$ 的第j行是詞 $w_{j}$ 的 $n$ 維嵌入向量。我們定義 $\mathcal{U}$ 的這行為 $u_j$

  • 注意實際上對每個詞 $w_i$ 我們需要學習兩個詞向量(即輸入詞向量 $v_i$ 和輸出詞向量 $u_i$ )。

❐ 首先我們對CBOW模型作出以下定義

  • $w_i$ :詞彙表 $V$ 中的單詞 $i$
  • $\mathcal{V}\in \mathbb{R}^{n\times \left | V \right |}$ :輸入詞矩陣
  • $v_i$ : $\mathcal{V}$ 的第 $i$ 列,單詞 $w_i$ 的輸入向量表示
  • $\mathcal{U}\in \mathbb{R}^{ \left | V \right |\times n}$ :輸出詞矩陣
  • $u_i$ : $\mathcal{U}$ 的第 $i$ 行,單詞 $w_i$ 的輸出向量表示

我們將這個模型分解為以下步驟

  • ① 我們為大小為 $m$ 的輸入上下文詞彙,生成one-hot詞向量 $(x^{(c-m)}, \cdots ,x^{(c-1)},x^{(c+1)}, \cdots ,x^{(c+m)}\in \mathbb{R}^{ \left | V \right |})$

  • ② 我們基於上述one-hot輸入計算得到嵌入詞向量 $(v_{c-m}=\mathcal{V}x^{(c-m)},v_{c-m+1}=\mathcal{V}x^{(c-m+1)},\cdots ,v_{c+m}=\mathcal{V}x^{(c+m)}\in \mathbb{R}^{n})$ 。

  • ③ 對上述的詞向量求平均值 $\widehat{v}=\frac{v_{c-m}+v_{c-m+1}+ \cdots +v_{c+m}}{2m}\in \mathbb{R}^{n}$ 。

  • ④ 計算分數向量 $z = \mathcal{U}\widehat{v}\in \mathbb{R}^{ \left | V \right |}$ 。相似的詞對向量的點積值大,這會令相似的詞更為靠近,從而獲得更高的分數。

  • ⑤ 將分數通過softmax轉換為概率 $\widehat{y}=softmax(z)\in \mathbb{R}^{ \left | V \right |}$ 。

  • ⑥ 我們希望生成的概率 $\widehat{y} \in \mathbb{R}^{ \left | V \right |}$ 與實際的概率 $y \in \mathbb{R}^{ \left | V \right |}$ (實際是one-hot表示)越接近越好(我們後續會構建交叉熵損失函式並對其進行迭代優化)。

這裡softmax是一個常用的函式。它將一個向量轉換為另外一個向量,其中轉換後的向量的第 $i$ 個元素是 $\frac{e^{\widehat{y}i}}{\sum{k=1}^{ \left | V \right |}e^{\widehat{y}_k}}$ 。

因為該函式是一個指數函式,所以值一定為正數。

通過除以 $\sum_{k=1}^{ \left | V \right |}e^{\widehat{y}k}$ 來歸一化向量(使得 $\sum{k=1}^{ \left | V \right |}\widehat{y}_k=1$ )得到概率。

下圖是CBOW模型的計算圖示

CBOW模型的計算圖示

如果有 $\mathcal{V}$ 和 $\mathcal{U}$ ,我們知道這個模型是如何工作的,那我們如何更新引數,學習這兩個矩陣呢?和所有的機器學習任務相似,我們會構建目標函式,這裡我們會使用交叉熵 $H(\widehat{y}, y)$ 來構建損失函式,它也是資訊理論裡提的度量兩個概率分佈的距離的方法。

(關於交叉熵可以參考ShowMeAI圖解AI數學基礎教程中文章圖解AI數學基礎 | 資訊理論

在離散情況下,使用交叉熵可以直觀地得出損失函式的公式

$$ H(\widehat{y}, y)=-\sum_{j=1}^{ \left | V \right |} y_{j} \log (\widehat{y}_{j}) $$

上面的公式中, $y$ 是one-hot向量。因此上面的損失函式可以簡化為:

$$ H(\widehat{y}, y)= - y_{j}\,log(\widehat{y}_{j}) $$

$ c $ 是正確詞的one-hot向量的索引。如果我們精準地預測$ \widehat{y}_{c}=1 $,可以計算此時$ H(\widehat{y}, y)=-1\,log(1)=0 $ 。因此,對於完全準確的預測,我們不會面臨任何懲罰或者損失。

我們考慮一個相反的情況,預測非常差並且標準答案 $\widehat{y}_{c}=0.01$ 。進行相似的計算可以得到損失函式值 $H(\widehat{y}, y)=-1\,log(0.01)=4.605$ ,這表示目前損失較大,和標準答案差距較大。

從上面的例子可以看出,對於概率分佈,交叉熵為我們提供了一個很好的距離度量。因此我們的優化目標函式公式為:

$$ \begin{aligned} minimize J &=-\log P(w_{c} \mid w_{c-m}, \cdots, w_{c-1}, w_{c+1}, \cdots, w_{c+m}) \ &=-\log P(u_{c} \mid \widehat{v}) \ &=-\log \frac{\exp (u_{c}^{T} \widehat{v})}{\sum_{j=1}^{|V|} \exp (u_{j}^{T} \widehat{v})} \ &=-u_{c}^{T} \widehat{v}+\log \sum_{j=1}^{|V|} \exp (u_{j}^{T} \widehat{v}) \end{aligned} $$

我們使用SGD(隨機梯度下降)來更新所有相關的詞向量 $u_{c}$ 和 $v_j$ 。 (關於SGD等優化演算法可以參考ShowMeAI的對吳恩達老師課程的總結文章深度學習教程 | 神經網路優化演算法

❐ 當 $\widehat{y} = y$ 時, $\widehat{y} \mapsto H(\widehat{y}, y)$ 為最小值。如果我們找到一個 $\widehat{y}$ 使得 $H(\widehat{y}, y)$ 接近最小值,那麼 $\widehat{y} \approx y$ 。這意味著我們的模型非常善於根據上下文預測中心詞!

❐ 為了學習向量(矩陣 $U$ 和 $V$ ),CBOW定義了一個損失函式,衡量它在預測中心詞方面的表現。然後,我們通過更新矩陣 $U$ 和 $V$ 隨機梯度下降來優化損失函式。

❐ SGD對一個視窗計算梯度和更新引數:

$\mathcal{U}{new} \leftarrow \mathcal{U}{old} -\alpha \nabla_{\mathcal{U}} J$

$\mathcal{V}{old} \leftarrow \mathcal{V}{old}-\alpha \nabla_{\mathcal{V}} J$

4.3 Skip-Gram模型

Skip-Gram模型與CBOW大體相同,但模型對於輸入輸出 $x$ 和 $y$ 進行了交換,即CBOW中的 $x$ 現在是 $y$ , $y$ 現在是 $x$ 。輸入的one-hot向量(中心詞)我們表示為 $x$ ,輸出向量為 $y^{(j)}$ 。我們定義的 $\mathcal{V}$ 和 $\mathcal{U}$ 是和CBOW一樣的。

Skip-Gram模型:在給定中心詞的情況下預測周圍的上下文詞。

下面我們來具體拆解一下Skip-Gram模型,首先我們定義一些符號標記

  • $w_i$ :詞彙表 $V$ 中的單詞 $i$

  • $\mathcal{V}\in \mathbb{R}^{n\times \left | V \right |}$ :輸入詞矩陣

  • $v_i$ : $\mathcal{V}$ 的第 $i$ 列,單詞 $w_i$ 的輸入向量表示

  • $\mathcal{U}\in \mathbb{R}^{ \left | V \right |\times n}$ :輸出詞矩陣

  • $u_i$ : $\mathcal{U}$ 的第 $i$ 行,單詞 $w_i$ 的輸出向量表示

Skip-Gram的工作方式可以拆解為以下步驟

  • ① 生成中心詞的one-hot向量 $x\in \mathbb{R}^{ \left | V \right |}$

  • ② 我們對中心詞計算得到詞嵌入向量 $v_{c}=\mathcal{V}x\in \mathbb{R}^{ \left | V \right |}$

  • ③ 生成分數向量 $z = \mathcal{U}v_{c}$

  • ④ 將分數向量轉化為概率, $\widehat{y}=softmax(z)$ 注意 $\widehat{y}{c-m},\cdots,\widehat{y}{c-1},\widehat{y}{c+1},\cdots,\widehat{y}{c+m}$ 是每個上下文詞出現的概率

  • ⑤ 我們希望我們生成的概率向量匹配真實概率 $y^{(c-m)}, \cdots ,y^{(c-1)},y^{(c+1)}, \cdots ,y^{(c+m)}$ ,one-hot向量是實際的輸出

和CBOW模型一樣,我們需要生成一個目標函式來評估這個模型。與CBOW模型的一個主要的不同是我們引用了一個樸素的貝葉斯假設來拆分概率。這是一個很強(樸素)的條件獨立假設。換而言之,給定中心詞,所有輸出的詞是完全獨立的(即公式1至2行)

$$ \begin{aligned} minimize J &= -\log P(w_{c-m}, \cdots, w_{c-1}, w_{c+1}, \cdots, w_{c+m} \mid w_{c}) \ &=-\log \prod_{j=0, j \neq m}^{2 m} P(w_{c-m+j} \mid w_{c}) \ &=-\log \prod_{j=0, j \neq m}^{2 m} P(u_{c-m+j} \mid v_{c}) \ &=-\log \prod_{j=0, j \neq m}^{2 m} \frac{\exp (u_{c-m+j}^{T} v_{c})}{\sum_{k=1}^{ \left | V \right |} \exp (u_{k}^{T} v_{c})} \ &=-\sum_{j=0, j \neq m}^{2 m} u_{c-m+j}^{T} v_{c}+2 m \log \sum_{k=1}^{ \left | V \right |} \exp (u_{k}^{T} v_{c}) \end{aligned} $$

通過這個目標函式(損失函式),我們可以計算出與未知引數相關的梯度,並且在每次迭代中通過SGD來更新它們。

注意:

$$ J =-\sum_{j=0, j \neq m}^{2 m} \log P(u_{c-m+j} \mid v_{c}) =\sum_{j=0, j \neq m}^{2 m} H(\widehat{y}, y_{c-m+j}) $$

  • 其中 $H(\widehat{y},y_{c-m+j})$ 是向量 $\widehat{y}$ 的概率和one-hot向量 $y_{c-m+j}$ 之間的交叉熵。

❐ 只有一個概率向量 $\widehat{y}$ 是被計算的。Skip-Gram對每個上下文單詞一視同仁:該模型計算每個單詞在上下文中出現的概率,而與它到中心單詞的距離無關。

下圖為Skip-Gram模型的計算圖示

Skip-Gram模型的計算圖示

4.4 負例取樣

我們再回到需要優化的目標函式上,我們發現在詞表很大的情況下,對 $\left | V \right |$ 的求和計算量是非常大的。任何的更新或者對目標函式的評估都要花費 $O( \left | V \right |)$ 的時間複雜度。一個簡單的想法是不去直接計算,而是去求近似值。

❐ 因為softmax標準化要對對所有分數求和,CBOW和Skip Gram的損失函式J計算起來很昂貴!

在每一個訓練的時間步,我們不去遍歷整個詞彙表,而僅僅是抽取一些負樣例。我們對噪聲分佈 $P_n(w)$ “抽樣”,這個概率是和詞頻的排序相匹配的。

Mikolov在論文《Distributed Representations of Words and Phrases and their Compositionality》中提出了負取樣。雖然負取樣是基於Skip-Gram模型,但實際上是對一個不同的目標函式進行優化。

考慮一組詞對 $(w,c)$ ,這組詞對是訓練集中出現過的中心詞和上下文詞嗎?我們通過 $P(D=1\mid w,c)$ 表示 $(w,c)$ 在語料庫出現過, $P(D=0\mid w,c)$ 表示 $(w,c)$ 在語料庫中沒有出現過。

這是一個二分類問題,我們基於sigmoid函式建模:

$$ P(D=1 \mid w, c, \theta)=\sigma(v_c^{T} v_w)=\frac{1}{1+e^{(-v_c^{T} v_w)}} $$

❐ sigmoid函式是softmax的二分類版本,可用於建立概率模型: $\sigma(x)=\frac{1}{1+e^{-x}}$

sigmoid函式

現在,我們建立一個新的目標函式,如果中心詞和上下文詞確實在語料庫中,就最大化概率 $P(D=1\mid w,c)$ ,如果中心詞和上下文詞確實不在語料庫中,就最大化概率 $P(D=0\mid w,c)$ 。

(這就是邏輯迴歸對於二分類的處理思路,相關內容可以參考ShowMeAI機器學習教程文章圖解機器學習 | 邏輯迴歸演算法詳解) 我們對這兩個概率採用一個簡單的極大似然估計的方法(這裡我們把 $\theta$ 作為模型的引數,在我們的例子是 $\mathcal{V}$ 和 $\mathcal{U}$ )

$$ \begin{aligned} \theta &=\underset{\theta}{\operatorname{argmax}} \prod_{(w, c) \in D} P(D=1 \mid w, c, \theta) \prod_{(w, c) \in \widetilde{D}} P(D=0 \mid w, c, \theta) \ &=\underset{\theta}{\operatorname{argmax}} \prod_{(w, c) \in D} P(D=1 \mid w, c, \theta) \prod_{(w, c) \in \widetilde{D}}(1-P(D=1 \mid w, c, \theta)) \ &=\underset{\theta}{\operatorname{argmax}} \sum_{(w, c) \in D} \log P(D=1 \mid w, c, \theta)+\sum_{(w, c) \in \widetilde{D}} \log (1-P(D=1 \mid w, c, \theta)) \ &=\arg \max {\theta} \sum{(w, c) \in D} \log \frac{1}{1+\exp (-u_{w}^{T} v_{c})}+\sum_{(w, c) \in \widetilde{D}} \log (1-\frac{1}{1+\exp (-u_{w}^{T} v_{c})}) \ &=\arg \max {\theta} \sum{(w, c) \in D} \log \frac{1}{1+\exp (-u_{w}^{T} v_{c})}+\sum_{(w, c) \in \widetilde{D}} \log (\frac{1}{1+\exp (u_{w}^{T} v_{c})}) \end{aligned} $$

這裡最大化似然函式等同於最小化負對數似然:

$$ J=-\sum_{(w, c) \in D} \log \frac{1}{1+\exp (-u_{w}^{T} v_{c})}-\sum_{(w, c) \in \widetilde{D}} \log (\frac{1}{1+\exp (u_{w}^{T} v_{c})}) $$

注意 $\widetilde{D}$ 是“假的”或者“負的”語料。例如我們有句子類似 自然學習愛處理語言我技術,這種無意義的句子出現時會得到一個很低的概率。我們可以從語料庫中隨機抽樣詞彙構建負樣例 $\widetilde{D}$ 。

對於Skip-Gram模型,我們對給定中心詞 $c$ 來觀察的上下文單詞 $c-m+j$ 的新目標函式為

$$ -\log \sigma(u_{c-m+j}^{T} \cdot v_{c})-\sum_{k=1}^{K} \log \sigma(-\tilde{u}{k}^{T} \cdot v{c}) $$

對CBOW模型,我們對給定上下文向量 $\widehat{v}=\frac{v_{c-m}+v_{c-m+1}+ \cdots +v_{c+m}}{2m}$ 來觀察中心詞 $u_{c}$ 的新的目標函式為:

$$ -log\,\sigma(u_{c}^{T}\cdot \widehat{v})-\sum_{k=1}^{K}log\,\sigma(-\widetilde{u}_{k}^{T}\cdot \widehat{v}) $$

在上面的公式中, ${\widetilde{u}{k}\mid k=1, \cdots ,K}$ 是從 $P{n}(w)$ 中抽樣的詞彙。關於計算選擇某個詞作為負樣本的概率,可以使用隨機選擇。但論文作者給出瞭如下效果更好的公式:

$$ p(w_i) = \frac{f(w_i)^{\frac{3}{4}}}{\sum^m_{j=0}f(w_j)^{\frac{3}{4}}} $$

公式中, $f(w_i)$ 代表語料庫中單詞 $w_i$ 出現的頻率。上述公式更加平滑,能夠增加低頻詞的選取可能。

4.5 層次化Softmax

Mikolov 在論文《Distributed Representations of Words and Phrases and their Compositionality》中提出了 hierarchical softmax(層次化softmax),相比普通的softmax這是一種更有效的替代方法。在實際中,hierarchical softmax 對低頻詞往往表現得更好,負取樣對高頻詞和較低維度向量表現得更好。

Hierarchical softmax 使用一個二叉樹來表示詞表中的所有詞。樹中的每個葉結點都是一個單詞,而且只有一條路徑從根結點到葉結點。在這個模型中,沒有詞的輸出表示。相反,圖的每個節點(根節點和葉結點除外)與模型要學習的向量相關聯。單詞作為輸出單詞的概率定義為從根隨機遊走到單詞所對應的葉的概率。計算成本變為 $O(log ( \left | V \right |))$ 而不是 $O( \left | V \right |)$ 。

在這個模型中,給定一個向量 $w_i$ 的下的單詞 $w$ 的概率 $p(w\mid w_i)$ ,等於從根結點開始到對應w的葉結點結束的隨機漫步概率。這個方法最大的優勢是計算概率的時間複雜度僅僅是 $O(log( \left | V \right |))$ ,對應著路徑的長度。

❐ 下圖是 Hierarchical softmax 的二叉樹示意圖:

Hierarchical Softmax 二叉樹示意圖

讓我們引入一些概念。令 $L(w)$ 為從根結點到葉結點 $w$ 的路徑中節點數目。例如,上圖中的 $L(w_2)$ 為3。我們定義 $n(w,i)$ 為與向量 $v_{n(w,i)}$ 相關的路徑上第 $i$ 個結點。因此 $n(w,1)$ 是根結點,而 $n(w,L(w))$ 是 $w$ 的父節點。現在對每個內部節點 $n$ ,我們任意選取一個它的子節點,定義為 $ch(n)$ (一般是左節點)。然後,我們可以計算概率為

$$ p(w \mid w_i)=\prod_{j=1}^{L(w)-1} \sigma([n(w, j+1)=ch(n(w, j))] \cdot v_{n(w, j)}^{T} v_{w_i}) $$

其中

$$ [x]=\left{\begin{array}{ll}{1} & {\text { if } x \text { is true }} \ {-1} & {\text { otherwise }}\end{array}\right. $$

這個公式看起來非常複雜,我們來展開講解一下。

  • 首先,我們將根據從根節點 $(n(w,1))$ 到葉節點 $(w)$ 的路徑的形狀(左右分支)來計算相乘的項。如果我們假設 $ch(n)$ 一直都是 $n$ 的左節點,然後當路徑往左時 $[n(w,j+1)=ch(n(w,j))]$ 的值返回1,往右則返回0。

  • 此外, $[n(w,j+1)=ch(n(w,j))]$ 提供了歸一化的作用。在節點 $n$ 處,如果我們將去往左和右節點的概率相加,對於 $v_{n}^{T}v_{w_i}$ 的任何值則可以檢查, $\sigma(v_{n}^{T} v_{w_i})+\sigma(-v_{n}^{T} v_{w_i})=1$ 。歸一化也保證了 $\sum_{w=1}^{ \left | V \right |}P(w\mid w_i)=1$ ,和普通的softmax是一樣的。

  • 最後我們計算點積來比較輸入向量 $v_{w_i}$ 對每個內部節點向量 $v_{n(w,j)}^{T}$ 的相似度。下面我們給出一個例子。以上圖中的 $w_2$ 為例,從根節點要經過兩次左邊的邊和一次右邊的邊才到達 $w_2$ ,因此

$$ \begin{aligned} p(w_2 \mid w_i) &=p(n(w_2, 1), \text {left}) \cdot p(n(w_2, 2), \text {left}) \cdot p(n(w_2, 3), \text { right }) \ &=\sigma(v_{n(w_2, 1)}^{T} v_{w_i}) \cdot \sigma(v_{n(w_2, 2)}^{T} v_{w_i}) \cdot \sigma(-v_{n(w_2, 3)}^{T} v_{w_i}) \end{aligned} $$

我們訓練模型的目標是最小化負的對數似然 $-log\,P(w\mid w_i)$ 。不是更新每個詞的輸出向量,而是更新更新二叉樹中從根結點到葉結點的路徑上的節點的向量。

該方法的速度由構建二叉樹的方式確定,並將詞分配給葉節點。Mikolov在論文《Distributed Representations of Words and Phrases and their Compositionality》中使用的是哈夫曼樹,在樹中分配高頻詞到較短的路徑。

5.基於python gensim工具庫構建詞向量

在python中可以很簡單地基於Gensim工具庫構建和使用詞向量,提供了most_similardoesnt_match等應用API。我們可以對most_similar進行封裝,輸出三元組的類比結果,程式碼如下

python model = KeyedVectors.load_word2vec_format(word2vec_glove_file) model.most_similar('banana') def analogy(x1, x2, y1): result = model.most_similar(positive=[y1, x2], negative=[x1]) return result[0][0] analogy('japan', 'japanese', 'australia') model.doesnt_match("breakfast cereal dinner lunch".split())

6.拓展閱讀

Word2Vec Tutorial - The Skip-Gram Model

6.1 任務示例

我們將訓練一個帶有單個隱藏層的簡單神經網路來執行某個任務,但是我們實際上並沒有將這個神經網路用於我們訓練它的任務。相反,目標實際上只是學習隱藏層的權重,這實際上是我們試圖學習的“單詞向量”。這一技巧也在無監督的特徵學習常用。訓練一個auto-encoder從而在隱藏層中壓縮輸入向量並在輸出層將隱藏層向量解壓縮得到輸入向量。訓練完成後,去除輸出層,只是用隱藏層。

下圖是從源文字中抽取樣本的過程

從源文字中抽取樣本的過程

下圖是網路架構圖 網路架構圖 如果兩個不同的單詞具有非常相似的“上下文”(即它們周圍可能出現的單詞是相似的),那麼我們的模型需要為這兩個單詞輸出非常相似的結果。網路為這兩個單詞輸出類似的上下文預測的一種方式是判斷單詞向量是否相似。因此,如果兩個單詞具有相似的上下文,那麼我們的網路就會為這兩個單詞學習相似的單詞向量!

  • Efficient Estimation of Word Representations in Vector Space(original word2vec paper)
  • Distributed Representations of Words and Phrases and their Compositionality (negative sampling paper)

7.參考資料

ShowMeAI系列教程推薦

NLP系列教程文章

斯坦福 CS224n 課程帶學詳解

showmeai