1. 程式人生 > >詞向量技術-從word2vec到Glove到ELMo

詞向量技術-從word2vec到Glove到ELMo

詞向量word2vec VS ELMo

本文關鍵詞:NLP、詞向量、word2vec、ELMo、語言模型

0. 前言

"詞和句子的嵌入已成為所有基於深度學習的自然語言處理(NLP)系統的重要組成部分,它們在固定長度的稠密向量中編碼單詞和句子,以大幅度提高神經網路處理文字資料的能力。"

大趨勢是對通用嵌入的追求:在大型語料庫上預訓練好的嵌入,可以插入各種下游任務模型(情感分析,分類,翻譯…),通過在更大的資料集中學習一些常用的詞句表示,從而自動提高它們的效能。
這是一種遷移學習。

作為NLP領域的愛好者,在我之前的多個文章裡已經很多次提到詞向量技術了(基於TextCNN的文字分類中),它的代表技術word2vec更是“老生常談”了...

一直想寫一篇有關於word2vec的文章,一直沒有抽出時間(因為理論數學公式太多了,編輯公示太痛苦了)...

直到一次偶然的面試:被問到一個關於動態詞向量的問題(ELMo,當時懵逼了)…事後查閱了一些詞向量相關的文獻,才發現自己原來還停留在靜態詞向量的word2vec的世界裡,面試官是想考察我對最新技術的洞察力!

詞向量為文字資料提供了一種數值化的表示方法,這是文字資料能夠被計算機處理的基礎,也是機器學習技術能夠應用於文字資料處理的重要前提基礎。

1. 詞向量技術

自然語言是一套用來表達含義的複雜系統。在這套系統中,詞是表義的基本單元。顧名思義,詞向量是用來表示詞的向量,也可被認為是詞的特徵向量。

這通常需要把維數為詞典大小的高維空間嵌入到一個更低維數的連續向量空間。把詞對映為實數域上向量的技術也叫詞嵌入(word embedding)。近年來,詞向量已逐漸成為自然語言處理的基礎知識。
那麼,我們應該如何使用向量表示詞呢?

1.1詞向量的獲取方式

詞向量的獲取方式可以大體分為兩類:一類是基於統計方法(例如:基於共現矩陣、SVD),另一種是基於語言模型的。

(1).基於共現矩陣的方式

通過統計一個事先指定大小的視窗內的word共現次數,以word周邊的共現詞的次數做為當前word的vector。具體來說,我們通過從大量的語料文字中構建一個共現矩陣來定義word representation。
例如,有語料如下:

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

則其共現矩陣X如下:

矩陣定義的詞向量在一定程度上緩解了one-hot向量相似度為0的問題,但沒有解決資料稀疏性和維度災難的問題。

(2). SVD(奇異值分解)

既然基於co-occurrence矩陣得到的離散詞向量存在著高維和稀疏性的問 題,一個自然而然的解決思路是對原始詞向量進行降維,從而得到一個稠密的連續詞向量。
首先,統計一個詞語的共生矩陣X。X是一個|V|×|V| 大小的矩陣,Xij表示在所有語料中,詞彙表V中第i個詞和第j個詞同時出現的詞數,|V|為詞彙表的大小。對X做矩陣分解(如奇異值分解,Singular Value Decomposition [參考資料])得到矩陣正交矩陣U,對U進行歸一化得到矩陣,即視為所有詞的詞向量:

SVD

SVD得到了word的稠密(dense)矩陣,該矩陣具有很多良好的性質:語義相近的詞在向量空間相近,甚至可以一定程度反映word間的線性關係。


但這樣的傳統做法有很多問題:

  1. 由於很多詞沒有出現,導致矩陣極其稀疏,因此需要對詞頻做額外處理來達到好的矩陣分解效果;
  2. 矩陣非常大,維度太高
  3. 需要手動去掉停用詞(如although, a,...),不然這些頻繁出現的詞也會影響矩陣分解的效果。
(3)語言模型

在介紹詞向量模型之前,先簡單的介紹一個概念:語言模型。 語言模型旨在為語句的聯合概率函式P(w1,...,wT)
建模, 其中wi表示句子中的第i個詞。語言模型的目標是,希望模型對有意義的句子賦予大概率,對沒意義的句子賦予小概率。 這樣的模型可以應用於很多領域,如機器翻譯、語音識別、資訊檢索、詞性標註、手寫識別等,它們都希望能得到一個連續序列的概率。 以資訊檢索為例,當你在搜尋“how long is a football bame”時(bame是一個醫學名詞),搜尋引擎會提示你是否希望搜尋"how long is a football game", 這是因為根據語言模型計算出“how long is a football bame”的概率很低,而與bame近似的,可能引起錯誤的詞中,game會使該句生成的概率最大。

對語言模型的目標概率P(w1,...,wT),如果假設文字中每個詞都是相互獨立的,則整句話的聯合概率可以表示為其中所有詞語條件概率的乘積,即:

然而我們知道語句中的每個詞出現的概率都與其前面的詞緊密相關, 所以實際上通常用條件概率表示語言模型:


上面只是簡單的介紹了語言模型,推薦閱讀的關於N-gram模型以及神經概率語言模型以便於學習後續的word2vec模型。

N-gram

2.代表技術之一 word2vec

2013年,Google團隊發表了word2vec工具 [1]。word2vec工具主要包含兩個模型:跳字模型(skip-gram)和連續詞袋模型(continuous bag of words,簡稱CBOW),以及兩種近似訓練法:負取樣(negative sampling)和層序softmax(hierarchical softmax)。值得一提的是,word2vec的詞向量可以較好地表達不同詞之間的相似和類比關係。

word2vec自提出後被廣泛應用在自然語言處理任務中。它的模型和訓練方法也啟發了很多後續的詞嵌入模型。本節將重點介紹word2vec的模型和訓練方法。

Skip-gram模型(跳字模型):

Skip-gram

在跳字模型中,我們用一個詞來預測它在文字序列周圍的詞。

舉個例子,假設文字序列是:

“I love you very much”

跳字模型所關心的是,給定“you”生成鄰近詞“I”、“love”、“very”和“much”的條件概率。

在這個例子中,“you”叫中心詞,“I”、“love”、“very”和“much”叫背景詞。

由於“you”只生成與它距離不超過2的背景詞,該時間視窗的大小為2[與N-gram類似]。

我們來描述一下跳字模型[用最大似然估計的思想]:

假設詞典索引集V的大小為|V|,且{0,1,…,|V|−1}。給定一個長度為T的文字序列中,文字序列中第t的詞為w(t)。當時間視窗大小為m時,跳字模型需要最大化給定任一中心詞生成所有背景詞的概率:

上式的最大似然估計最小化以下損失函式等價:

我們可以用vu分別表示 中心詞背景詞 的向量。

換言之,對於詞典中索引為i的詞,它在作為中心詞和背景詞時的向量表示分別是vi和ui。而詞典中所有詞的這兩種向量正是跳字模型所要學習的模型引數。為了將模型引數植入損失函式,我們需要使用模型引數表達損失函式中的給定中心詞生成背景詞的條件概率。給定中心詞,假設生成各個背景詞是相互獨立的。設中心詞wc在詞典中索引為c,背景詞wo在詞典中索引為o,損失函式中的給定中心詞生成背景詞的條件概率可以通過softmax函式定義為:

上式:給定任何一箇中心詞Wc,產生背景詞Wo的概率

每一個詞,在模型中有兩個詞向量,一個是作為中心詞時的詞向量,一個是作為背景詞時的詞向量

利用隨機梯度下降求解:

當序列長度T較大時,我們通常在每次迭代時隨機取樣一個較短的子序列來計算有關該子序列的損失。然後,根據該損失計算詞向量的梯度並迭代詞向量。具體演算法可以參考“梯度下降和隨機梯度下降——從零開始”一節。 作為一個具體的例子,下面我們看看如何計算隨機取樣的子序列的損失有關中心詞向量的梯度。和上面提到的長度為T的文字序列的損失函式類似,隨機取樣的子序列的損失實際上是對子序列中給定中心詞生成背景詞的條件概率的對數求平均。通過微分,我們可以得到上式中條件概率的對數有關中心詞向量vc梯度:

該式也可改寫作:

上面的迭代更新計算開銷太大!!每次都需要遍歷整個字典,對應的解決方案在後面(這也是word2vec為啥這麼牛逼的原因...厲害的不是這個工具本身,而是一種思想的應用)

隨機取樣的子序列有關其他詞向量的梯度同理可得。訓練模型時,每一次迭代實際上是用這些梯度來迭代子序列中出現過的中心詞和背景詞的向量。訓練結束後,對於詞典中的任一索引為i的詞,我們均得到該詞作為中心詞和背景詞的兩組詞向量vi和ui。在自然語言處理應用中,我們會使用跳字模型的中心詞向量。


CBOW(連續詞袋模型)

CBOW

連續詞袋模型與跳字模型類似,與跳字模型最大的不同是:

連續詞袋模型用一箇中心詞在文字序列周圍的詞來預測該中心詞。

舉個例子,假設文字序列為:

“I love you very much”

連續詞袋模型所關心的是,鄰近詞“I”、“love”、“very”和“much”一起生成中心詞“you”的概率。

假設詞典索引集的大小為V,且V={0,1,…,|V|−1}</nobr>。給定一個長度為T的文字序列中,文字序列中第t個詞為wu(t)。當時間視窗大小為m時,連續詞袋模型需要最大化由背景詞生成任一中心詞的概率

上式的最大似然估計與最小化以下損失函式等價:

我們可以用vu分別表示背景詞和中心詞的向量(注意符號和跳字模型中的不同)。換言之,對於詞典中索引為i的詞,它在作為背景詞和中心詞時的向量表示分別是vi和ui。而詞典中所有詞的這兩種向量正是連續詞袋模型所要學習的模型引數。為了將模型引數植入損失函式,我們需要使用模型引數表達損失函式中的給定背景詞生成中心詞的概率。設中心詞wc在詞典中索引為c,背景詞wo1、wo2、...wo2m在詞典中索引為o1、o2、....o2m-1、o2m,損失函式中的給定背景詞生成中心詞的概率可以通過softmax函式定義為

和跳字模型一樣,當序列長度T較大時,我們通常在每次迭代時隨機取樣一個較短的子序列來計算有關該子序列的損失。然後,根據該損失計算詞向量的梯度並迭代詞向量。 通過微分,我們可以計算出上式中條件概率的對數有關任一背景詞向量voi(i=1,2,....2m)的梯度為:

該式也可寫作

隨機取樣的子序列有關其他詞向量的梯度同理可得。和跳字模型一樣,訓練結束後,對於詞典中的任一索引為i的詞,我們均得到該詞作為背景詞和中心詞的兩組詞向量vi和ui
在自然語言處理應用中,我們會使用連續詞袋模型的背景詞向量。


近似訓練法

我們可以看到,無論是skip-gram(跳字模型)還是CBOW(連續詞袋模型),每一步梯度計算的開銷與詞典V的大小相關。

因為計算softmax的時考慮了字典上的所有可能性

當詞典較大時,例如幾十萬到上百萬,這種訓練方法的計算開銷會較大。因此,我們將使用近似的方法來計算這些梯度,從而減小計算開銷。常用的近似訓練法包括負取樣和層序softmax。

(1)負取樣(Negative Sample)

我們以跳字模型為例討論負取樣。

實際上,詞典V的大小之所以會在損失中出現,是因為給定中心詞wc生成背景詞wo的條件概率P(w0∣wc)

使用了softmax運算,而softmax運算正是考慮了背景詞可能是詞典中的任一詞(使用了全部詞),並體現在分母上。

下面,我們可以使用σ(x)=1/(1+exp(−x))函式來表達中心詞wc和背景詞wo同時出現在該訓練資料視窗的概率。

σ(x)屬於[0,1]

那麼,給定中心詞wc生成背景詞wo的條件概率的對數可以近似為:

[上式的含義:中心詞wc與背景詞wo同時出(D=1)現概率,且中心詞wc與噪音詞wk不同時出現(D=0)的概率。]

假設噪聲詞wk在詞典中的索引為ik,上式可改寫為:

因此,有關給定中心詞wc生成背景詞wo的損失是:

假設詞典V很大,每次迭代的計算開銷由O(|V|)變為O(|K|)。當我們把K取較小值時,負取樣每次迭代的計算開銷將較小。

當然,我們也可以對連續詞袋模型進行負取樣。有關給定背景詞
wt-m、wt-m+1、...、wt+m生成中心詞wc的損失:

在負取樣中可以近似為:


同樣,當我們把K取較小值時,負取樣每次迭代的計算開銷將較小。

(2)層序softmax[]

層序softmax是另一種常用的近似訓練法。它利用了二叉樹這一資料結構。樹的每個葉子節點代表著詞典V中的每個詞。


假設L(w)為從二叉樹的根節點到詞w<的葉子節點的路徑(包括根和葉子節點)上的節點數。設n(w,j)為該路徑上第j個節點,並設該節點的向量為u n(w,j)。以上圖為例:L(w3)=4。設詞典中的詞w i的詞向量為v i。那麼,跳字模型和連續詞袋模型所需要計算的給定詞w i生成詞w的條件概率為:

其中σ(x)=1/(1+exp(−x)),leftChild(n)是節點n的左孩子節點,如果判斷x為真,[x]=1;反之[x]=−1。由於σ(x)+σ(−x)=1,給定詞wi生成詞典V中任一詞的條件概率之和為1這一條件也將滿足:

讓我們計算給定詞wi生成詞w3的條件概率。我們需要將wi的詞向量vi和根節點到w3路徑上的非葉子節點向量一一求內積。由於在二叉樹中由根節點到葉子節點w3的路徑上需要向左、向右、再向左地遍歷,我們得到:

整個遍歷的路徑已經通過Huffman編碼唯一的確定了

在使用softmax的跳字模型和連續詞袋模型中,詞向量和二叉樹中非葉子節點向量是需要學習的模型引數。

假設詞典V很大,每次迭代的計算開銷由O(|V|)下降至O(log2|V|)。

推薦資料:學習word2vec的經典資料

3.ELMo--動態詞向量

ELMo官網:https://allennlp.org/elmo

艾倫研究所開發,並於6月初在NAACL 2018年釋出ELMo(深度語境化的單詞表示)。

ELMO(Embeddings from Language Models) ,被稱為時下最好的通用詞和句子嵌入方法,來自於語言模型的詞向量表示,也是利用了深度上下文單詞表徵,該模型的優勢:
(1)能夠處理單詞用法中的複雜特性(比如句法和語義)
(2)這些用法在不同的語言上下文中如何變化(比如為詞的多義性建模)

ELMo與word2vec最大的不同:
Contextual: The representation for each word depends on the entire context in which it is used. 
(即詞向量不是一成不變的,而是根據上下文而隨時變化,這與word2vec或者glove具有很大的區別)

舉個例子:針對某一詞多義的詞彙w="蘋果"
文字序列1=“我 買了 六斤 蘋果。”
文字序列2=“我 買了一個 蘋果 7。”
上面兩個文字序列中都出現了“蘋果”這個詞彙,但是在不同的句子中,它們我的含義顯示是不同的,一個屬於水果領域,一個屬於電子產品呢領域,如果針對“蘋果”這個詞彙同時訓練兩個詞向量來分別刻畫不同領域的資訊呢?答案就是使用ELMo。

ELMo是雙向語言模型biLM的多層表示的組合,基於大量文字,ELMo模型是從深層的雙向語言模型(deep bidirectional language model)中的內部狀態(internal state)學習而來的,而這些詞向量很容易加入到QA、文字對齊、文字分類等模型中,後面會展示一下ELMo詞向量在各個任務上的表現。


它首先在大文字語料庫上預訓練了一個深度雙向語言模型(biLM),然後把根據它的內部狀態學到的函式作為詞向量。實驗表明,這些學到的詞表徵可以輕易地加入到現有的模型中,並在回答問題、文字蘊含、情感分析等 6 個不同的有難度的 NLP 問題中大幅提高最佳表現。實驗表明顯露出預訓練模型的深度內部狀態這一做法非常重要,這使得後續的模型可以混合不同種類的半監督訊號。

3.1 ELMo的安裝與使用

AllenNLP是一個相對成熟的基於深度學習的NLP工具包,它構建於 PyTorch之上,該工具包中集成了ELMo方法。
可以直接使用pip安裝:

pip install allennlp

適用於python3.6以上的版本

或者,也可以直接clone原始碼到本地[https://github.com/allenai/allennlp]

使用ELMo獲得詞向量替換Glove的詞向量作為多項特定NLP模型的輸入,在ELMo的論文實驗中表明具有一定的效果提升:

4.結束

詞向量技術為文字的額數值化表示提供瞭解決方案,不同的詞向量技術可以提取詞彙的不同角度或層級的語義資訊,作為NLP各項任務模型的輸入,對於提升模型的效果覺有顯著的作用。