轉:詞向量word2vector那些事兒 word2vec原理(一) CBOW與Skip-Gram模型基礎 word2vec原理(二) 基於Hierarchical Softmax的模型 word2v

基本知識

BOW,word2vector,glovehtml

cbow,skip-grampython

Hierarchical Softmax,Negative Samplinggit

 

https://www.cnblogs.com/wkang/p/9611257.htmlgithub

https://www.cnblogs.com/wkang/p/9978364.html算法

 

word2vec原理(一) CBOW與Skip-Gram模型基礎網絡

word2vec原理(二) 基於Hierarchical Softmax的模型數據結構

word2vec原理(三) 基於Negative Sampling的模型dom

 

0001,

word2vec原理(一) CBOW與Skip-Gram模型基礎

    word2vec原理(一) CBOW與Skip-Gram模型基礎機器學習

    word2vec原理(二) 基於Hierarchical Softmax的模型分佈式

    word2vec原理(三) 基於Negative Sampling的模型

    word2vec是google在2013年推出的一個NLP工具,它的特色是將全部的詞向量化,這樣詞與詞之間就能夠定量的去度量他們之間的關係,挖掘詞之間的聯繫。雖然源碼是開源的,可是谷歌的代碼庫國內沒法訪問,所以本文的講解word2vec原理以Github上的word2vec代碼爲準。本文關注於word2vec的基礎知識。

1. 詞向量基礎

    用詞向量來表示詞並非word2vec的獨創,在好久以前就出現了。最先的詞向量是很冗長的,它使用是詞向量維度大小爲整個詞彙表的大小,對於每一個具體的詞彙表中的詞,將對應的位置置爲1。好比咱們有下面的5個詞組成的詞彙表,詞"Queen"的序號爲2, 那麼它的詞向量就是(0,1,0,0,0)

。一樣的道理,詞"Woman"的詞向量就是(0,0,0,1,0)

。這種詞向量的編碼方式咱們通常叫作1-of-N representation或者one hot representation.

     One hot representation用來表示詞向量很是簡單,可是卻有不少問題。最大的問題是咱們的詞彙表通常都很是大,好比達到百萬級別,這樣每一個詞都用百萬維的向量來表示簡直是內存的災難。這樣的向量其實除了一個位置是1,其他的位置所有都是0,表達的效率不高,能不能把詞向量的維度變小呢?

    Distributed representation能夠解決One hot representation的問題,它的思路是經過訓練,將每一個詞都映射到一個較短的詞向量上來。全部的這些詞向量就構成了向量空間,進而能夠用普通的統計學的方法來研究詞與詞之間的關係。這個較短的詞向量維度是多大呢?這個通常須要咱們在訓練時本身來指定。

    好比下圖咱們將詞彙表裏的詞用"Royalty","Masculinity", "Femininity"和"Age"4個維度來表示,King這個詞對應的詞向量多是(0.99,0.99,0.05,0.7)

。固然在實際狀況中,咱們並不能對詞向量的每一個維度作一個很好的解釋。

 

    有了用Distributed Representation表示的較短的詞向量,咱們就能夠較容易的分析詞之間的關係了,好比咱們將詞的維度降維到2維,有一個有趣的研究代表,用下圖的詞向量表示咱們的詞時,咱們能夠發現:

KingMan+Woman=Queen

     可見咱們只要獲得了詞彙表裏全部詞對應的詞向量,那麼咱們就能夠作不少有趣的事情了。不過,怎麼訓練獲得合適的詞向量呢?一個很常見的方法是使用神經網絡語言模型。

2. CBOW與Skip-Gram用於神經網絡語言模型

    在word2vec出現以前,已經有用神經網絡DNN來用訓練詞向量進而處理詞與詞之間的關係了。採用的方法通常是一個三層的神經網絡結構(固然也能夠多層),分爲輸入層,隱藏層和輸出層(softmax層)。

    這個模型是如何定義數據的輸入和輸出呢?通常分爲CBOW(Continuous Bag-of-Words 與Skip-Gram兩種模型。

    CBOW模型的訓練輸入是某一個特徵詞的上下文相關的詞對應的詞向量,而輸出就是這特定的一個詞的詞向量。好比下面這段話,咱們的上下文大小取值爲4,特定的這個詞是"Learning",也就是咱們須要的輸出詞向量,上下文對應的詞有8個,先後各4個,這8個詞是咱們模型的輸入。因爲CBOW使用的是詞袋模型,所以這8個詞都是平等的,也就是不考慮他們和咱們關注的詞之間的距離大小,只要在咱們上下文以內便可。

    這樣咱們這個CBOW的例子裏,咱們的輸入是8個詞向量,輸出是全部詞的softmax機率(訓練的目標是指望訓練樣本特定詞對應的softmax機率最大),對應的CBOW神經網絡模型輸入層有8個神經元,輸出層有詞彙表大小個神經元。隱藏層的神經元個數咱們能夠本身指定。經過DNN的反向傳播算法,咱們能夠求出DNN模型的參數,同時獲得全部的詞對應的詞向量。這樣當咱們有新的需求,要求出某8個詞對應的最可能的輸出中心詞時,咱們能夠經過一次DNN前向傳播算法並經過softmax激活函數找到機率最大的詞對應的神經元便可。

    
    Skip-Gram模型和CBOW的思路是反着來的,即輸入是特定的一個詞的詞向量,而輸出是特定詞對應的上下文詞向量。仍是上面的例子,咱們的上下文大小取值爲4, 特定的這個詞"Learning"是咱們的輸入,而這8個上下文詞是咱們的輸出。

    這樣咱們這個Skip-Gram的例子裏,咱們的輸入是特定詞, 輸出是softmax機率排前8的8個詞,對應的Skip-Gram神經網絡模型輸入層有1個神經元,輸出層有詞彙表大小個神經元。隱藏層的神經元個數咱們能夠本身指定。經過DNN的反向傳播算法,咱們能夠求出DNN模型的參數,同時獲得全部的詞對應的詞向量。這樣當咱們有新的需求,要求出某1個詞對應的最可能的8個上下文詞時,咱們能夠經過一次DNN前向傳播算法獲得機率大小排前8的softmax機率對應的神經元所對應的詞便可。

    以上就是神經網絡語言模型中如何用CBOW與Skip-Gram來訓練模型與獲得詞向量的大概過程。可是這和word2vec中用CBOW與Skip-Gram來訓練模型與獲得詞向量的過程有不少的不一樣。

    word2vec爲何 不用現成的DNN模型,要繼續優化出新方法呢?最主要的問題是DNN模型的這個處理過程很是耗時。咱們的詞彙表通常在百萬級別以上,這意味着咱們DNN的輸出層須要進行softmax計算各個詞的輸出機率的的計算量很大。有沒有簡化一點點的方法呢?

3. word2vec基礎之霍夫曼樹

    word2vec也使用了CBOW與Skip-Gram來訓練模型與獲得詞向量,可是並無使用傳統的DNN模型。最早優化使用的數據結構是用霍夫曼樹來代替隱藏層和輸出層的神經元,霍夫曼樹的葉子節點起到輸出層神經元的做用,葉子節點的個數即爲詞彙表的小大。 而內部節點則起到隱藏層神經元的做用。

    具體如何用霍夫曼樹來進行CBOW和Skip-Gram的訓練咱們在下一節講,這裏咱們先複習下霍夫曼樹。

    霍夫曼樹的創建其實並不難,過程以下:

    輸入:權值爲(w1,w2,...wn)

n

個節點

    輸出:對應的霍夫曼樹

    1)將(w1,w2,...wn)

看作是有n

棵樹的森林,每一個樹僅有一個節點。

    2)在森林中選擇根節點權值最小的兩棵樹進行合併,獲得一個新的樹,這兩顆樹分佈做爲新樹的左右子樹。新樹的根節點權重爲左右子樹的根節點權重之和。

    3) 將以前的根節點權值最小的兩棵樹從森林刪除,並把新樹加入森林。

    4)重複步驟2)和3)直到森林裏只有一棵樹爲止。

    下面咱們用一個具體的例子來講明霍夫曼樹創建的過程,咱們有(a,b,c,d,e,f)共6個節點,節點的權值分佈是(20,4,8,6,16,3)。

    首先是最小的b和f合併,獲得的新樹根節點權重是7.此時森林裏5棵樹,根節點權重分別是20,8,6,16,7。此時根節點權重最小的6,7合併,獲得新子樹,依次類推,最終獲得下面的霍夫曼樹。

    那麼霍夫曼樹有什麼好處呢?通常獲得霍夫曼樹後咱們會對葉子節點進行霍夫曼編碼,因爲權重高的葉子節點越靠近根節點,而權重低的葉子節點會遠離根節點,這樣咱們的高權重節點編碼值較短,而低權重值編碼值較長。這保證的樹的帶權路徑最短,也符合咱們的信息論,即咱們但願越經常使用的詞擁有更短的編碼。如何編碼呢?通常對於一個霍夫曼樹的節點(根節點除外),能夠約定左子樹編碼爲0,右子樹編碼爲1.如上圖,則能夠獲得c的編碼是00。

    在word2vec中,約定編碼方式和上面的例子相反,即約定左子樹編碼爲1,右子樹編碼爲0,同時約定左子樹的權重不小於右子樹的權重。

    咱們在下一節的Hierarchical Softmax中再繼續講使用霍夫曼樹和DNN語言模型相比的好處以及如何訓練CBOW&Skip-Gram模型。

 

 

0002,

word2vec原理(二) 基於Hierarchical Softmax的模型

    word2vec原理(一) CBOW與Skip-Gram模型基礎

    word2vec原理(二) 基於Hierarchical Softmax的模型

    word2vec原理(三) 基於Negative Sampling的模型

    在word2vec原理(一) CBOW與Skip-Gram模型基礎中,咱們講到了使用神經網絡的方法來獲得詞向量語言模型的原理和一些問題,如今咱們開始關注word2vec的語言模型如何改進傳統的神經網絡的方法。因爲word2vec有兩種改進方法,一種是基於Hierarchical Softmax的,另外一種是基於Negative Sampling的。本文關注於基於Hierarchical Softmax的改進方法,在下一篇討論基於Negative Sampling的改進方法。

1. 基於Hierarchical Softmax的模型概述

    咱們先回顧下傳統的神經網絡詞向量語言模型,裏面通常有三層,輸入層(詞向量),隱藏層和輸出層(softmax層)。裏面最大的問題在於從隱藏層到輸出的softmax層的計算量很大,由於要計算全部詞的softmax機率,再去找機率最大的值。這個模型以下圖所示。其中V

是詞彙表的大小,

 

    word2vec對這個模型作了改進,首先,對於從輸入層到隱藏層的映射,沒有采起神經網絡的線性變換加激活函數的方法,而是採用簡單的對全部輸入詞向量求和並取平均的方法。好比輸入的是三個4維詞向量:(1,2,3,4),(9,6,11,8),(5,10,7,12)

,那麼咱們word2vec映射後的詞向量就是(5,6,7,8)

。因爲這裏是從多個詞向量變成了一個詞向量。

    第二個改進就是從隱藏層到輸出的softmax層這裏的計算量個改進。爲了不要計算全部詞的softmax機率,word2vec採樣了霍夫曼樹來代替從隱藏層到輸出softmax層的映射。咱們在上一節已經介紹了霍夫曼樹的原理。如何映射呢?這裏就是理解word2vec的關鍵所在了。

    因爲咱們把以前全部都要計算的從輸出softmax層的機率計算變成了一顆二叉霍夫曼樹,那麼咱們的softmax機率計算只須要沿着樹形結構進行就能夠了。以下圖所示,咱們能夠沿着霍夫曼樹從根節點一直走到咱們的葉子節點的詞w2

 

    和以前的神經網絡語言模型相比,咱們的霍夫曼樹的全部內部節點就相似以前神經網絡隱藏層的神經元,其中,根節點的詞向量對應咱們的投影后的詞向量,而全部葉子節點就相似於以前神經網絡softmax輸出層的神經元,葉子節點的個數就是詞彙表的大小。在霍夫曼樹中,隱藏層到輸出層的softmax映射不是一會兒完成的,而是沿着霍夫曼樹一步步完成的,所以這種softmax取名爲"Hierarchical Softmax"。

    如何「沿着霍夫曼樹一步步完成」呢?在word2vec中,咱們採用了二元邏輯迴歸的方法,即規定沿着左子樹走,那麼就是負類(霍夫曼樹編碼1),沿着右子樹走,那麼就是正類(霍夫曼樹編碼0)。判別正類和負類的方法是使用sigmoid函數,即:

P(+)=σ(xTwθ)=11+exTwθ

    其中xw

是當前內部節點的詞向量,而θ

則是咱們須要從訓練樣本求出的邏輯迴歸的模型參數。

    使用霍夫曼樹有什麼好處呢?首先,因爲是二叉樹,以前計算量爲V

,如今變成了log2V

。第二,因爲使用霍夫曼樹是高頻的詞靠近樹根,這樣高頻詞須要更少的時間會被找到,這符合咱們的貪心優化思想。

    容易理解,被劃分爲左子樹而成爲負類的機率爲P()=1P(+)

。在某一個內部節點,要判斷是沿左子樹仍是右子樹走的標準就是看P(),P(+)誰的機率值大。而控制P(),P(+)誰的機率值大的因素一個是當前節點的詞向量,另外一個是當前節點的模型參數θ

    對於上圖中的w2

,若是它是一個訓練樣本的輸出,那麼咱們指望對於裏面的隱藏節點n(w2,1)P()機率大,n(w2,2)P()機率大,n(w2,3)P(+)

機率大。

    回到基於Hierarchical Softmax的word2vec自己,咱們的目標就是找到合適的全部節點的詞向量和全部內部節點θ

, 使訓練樣本達到最大似然。那麼如何達到最大似然呢?

2. 基於Hierarchical Softmax的模型梯度計算

   咱們使用最大似然法來尋找全部節點的詞向量和全部內部節點θ

。先拿上面的w2例子來看,咱們指望最大化下面的似然函數:

i=13P(n(wi),i)=(111+exTwθ1)(111+exTwθ2)11+exTwθ3

    對於全部的訓練樣本,咱們指望最大化全部樣本的似然函數乘積。

    爲了便於咱們後面通常化的描述,咱們定義輸入的詞爲w

,其從輸入層詞向量求和平均後的霍夫曼樹根節點詞向量爲xw, 從根節點到w所在的葉子節點,包含的節點總數爲lw, w在霍夫曼樹中從根節點開始,通過的第i個節點表示爲pwi,對應的霍夫曼編碼爲dwi{0,1},其中i=2,3,...lw。而該節點對應的模型參數表示爲θwi, 其中i=1,2,...lw1,沒有i=lw

是由於模型參數僅僅針對於霍夫曼樹的內部節點。

    定義w

通過的霍夫曼樹某一個節點j的邏輯迴歸機率爲P(dwj|xw,θwj1)

,其表達式爲:

P(dwj|xw,θwj1)={σ(xTwθwj1)1σ(xTwθwj1)dwj=0dwj=1

    那麼對於某一個目標輸出詞w

,其最大似然爲:

j=2lwP(dwj|xw,θwj1)=j=2lw[σ(xTwθwj1)]1dwj[1σ(xTwθwj−1)]dwj

    在word2vec中,因爲使用的是隨機梯度上升法,因此並無把全部樣本的似然乘起來獲得真正的訓練集最大似然,僅僅每次只用一個樣本更新梯度,這樣作的目的是減小梯度計算量。這樣咱們能夠獲得w

的對數似然函數L

以下:

L=logj=2lwP(dwj|xw,θwj1)=j=2lw((1dwj)log[σ(xTwθwj1)]+dwjlog[1−σ(xTwθwj−1)])

    要獲得模型中w

詞向量和內部節點的模型參數θ, 咱們使用梯度上升法便可。首先咱們求模型參數θwj1

的梯度:

Lθwj1=(1dwj)(σ(xTwθwj1)(1σ(xTwθwj1)σ(xTwθwj−1)xw−dwj(σ(xTwθwj−1)(1−σ(xTwθwj−1)1−σ(xTwθwj−1)xw=(1−dwj)(1−σ(xTwθwj−1))xw−dwjσ(xTwθwj−1)xw=(1−dwj−σ(xTwθwj−1))xw(1)(2)(3)

    若是你們看過以前寫的邏輯迴歸原理小結,會發現這裏的梯度推導過程基本相似。

    一樣的方法,能夠求出xw

的梯度表達式以下:

Lxw=j=2lw(1dwjσ(xTwθwj1))θwj1

    有了梯度表達式,咱們就能夠用梯度上升法進行迭代來一步步的求解咱們須要的全部的θwj1

xw

3. 基於Hierarchical Softmax的CBOW模型

    因爲word2vec有兩種模型:CBOW和Skip-Gram,咱們先看看基於CBOW模型時, Hierarchical Softmax如何使用。

    首先咱們要定義詞向量的維度大小M

,以及CBOW的上下文大小2c,這樣咱們對於訓練樣本中的每個詞,其前面的c個詞和後面的c

個詞做爲了CBOW模型的輸入,該詞自己做爲樣本的輸出,指望softmax機率最大。

    在作CBOW模型前,咱們須要先將詞彙表創建成一顆霍夫曼樹。

    對於從輸入層到隱藏層(投影層),這一步比較簡單,就是對w

周圍的2c個詞向量求和取平均便可,即:

xw=12ci=12cxi

    第二步,經過梯度上升法來更新咱們的θwj1

xw,注意這裏的xw是由2c個詞向量相加而成,咱們作梯度更新完畢後會用梯度項直接更新原始的各個xi(i=1,2,,,,2c)

,即:

θwj1=θwj1+η(1dwjσ(xTwθwj1))xw
xw=xw+ηj=2lw(1dwjσ(xTwθwj1))θwj1(i=1,2..,2c)

    其中η

爲梯度上升法的步長。

    這裏總結下基於Hierarchical Softmax的CBOW模型算法流程,梯度迭代使用了隨機梯度上升法:

    輸入:基於CBOW的語料訓練樣本,詞向量的維度大小M

,CBOW的上下文大小2c,步長η

    輸出:霍夫曼樹的內部節點模型參數θ

,全部的詞向量w

    1. 基於語料訓練樣本創建霍夫曼樹。

    2. 隨機初始化全部的模型參數θ

,全部的詞向量w

    3. 進行梯度上升迭代過程,對於訓練集中的每個樣本(context(w),w)

作以下處理:

      a)  e=0, 計算xw=12ci=12cxi

      b)  for j = 2 to lw

, 計算:

f=σ(xTwθwj1)
g=(1dwjf)η
e=e+gθwj1
θwj1=θwj1+gxw

              c) 對於context(w)

中的每個詞向量xi(共2c個)進行更新:

xi=xi+e

 

      d) 若是梯度收斂,則結束梯度迭代,不然回到步驟3繼續迭代。

4. 基於Hierarchical Softmax的Skip-Gram模型

    如今咱們先看看基於Skip-Gram模型時, Hierarchical Softmax如何使用。此時輸入的只有一個詞w

,輸出的爲2c個詞向量context(w)

    咱們對於訓練樣本中的每個詞,該詞自己做爲樣本的輸入, 其前面的c

個詞和後面的c

個詞做爲了Skip-Gram模型的輸出,,指望這些詞的softmax機率比其餘的詞大。

    Skip-Gram模型和CBOW模型實際上是反過來的,在上一篇已經講過。

    在作CBOW模型前,咱們須要先將詞彙表創建成一顆霍夫曼樹。

    對於從輸入層到隱藏層(投影層),這一步比CBOW簡單,因爲只有一個詞,因此,即xw

就是詞w

對應的詞向量。

    第二步,經過梯度上升法來更新咱們的θwj1

xw,注意這裏的xw周圍有2c個詞向量,此時若是咱們指望P(xi|xw),i=1,2...2c最大。此時咱們注意到因爲上下文是相互的,在指望P(xi|xw),i=1,2...2c最大化的同時,反過來咱們也指望P(xw|xi),i=1,2...2c最大。那麼是使用P(xi|xw)好仍是P(xw|xi)好呢,word2vec使用了後者,這樣作的好處就是在一個迭代窗口內,咱們不是隻更新xw一個詞,而是xi,i=1,2...2c2c個詞。這樣總體的迭代會更加的均衡。由於這個緣由,Skip-Gram模型並無和CBOW模型同樣對輸入進行迭代更新,而是對2c

個輸出進行迭代更新。

    這裏總結下基於Hierarchical Softmax的Skip-Gram模型算法流程,梯度迭代使用了隨機梯度上升法:

    輸入:基於Skip-Gram的語料訓練樣本,詞向量的維度大小M

,Skip-Gram的上下文大小2c,步長η

    輸出:霍夫曼樹的內部節點模型參數θ

,全部的詞向量w

    1. 基於語料訓練樣本創建霍夫曼樹。

    2. 隨機初始化全部的模型參數θ

,全部的詞向量w

,

    3. 進行梯度上升迭代過程,對於訓練集中的每個樣本(w,context(w))

作以下處理:

      a)  for i =1 to 2c:

        i) e=0

        ii)for j = 2 to lw

, 計算:

f=σ(xTiθwj1)
g=(1dwjf)η
e=e+gθwj1
θwj1=θwj1+gxi

        iii) 

xi=xi+e

      b)若是梯度收斂,則結束梯度迭代,算法結束,不然回到步驟a繼續迭代。

5. Hierarchical Softmax的模型源碼和算法的對應    

    這裏給出上面算法和word2vec源碼中的變量對應關係。

    在源代碼中,基於Hierarchical Softmax的CBOW模型算法在435-463行,基於Hierarchical Softmax的Skip-Gram的模型算法在495-519行。你們能夠對着源代碼再深刻研究下算法。

    在源代碼中,neule對應咱們上面的e

, syn0對應咱們的xw, syn1對應咱們的θij1, layer1_size對應詞向量的維度,window對應咱們的c

    另外,vocab[word].code[d]指的是,當前單詞word的,第d個編碼,編碼不含Root結點。vocab[word].point[d]指的是,當前單詞word,第d個編碼下,前置的結點。

  

    以上就是基於Hierarchical Softmax的word2vec模型,下一篇咱們討論基於Negative Sampling的word2vec模型。

 

0003,

word2vec原理(三) 基於Negative Sampling的模型

    word2vec原理(一) CBOW與Skip-Gram模型基礎

    word2vec原理(二) 基於Hierarchical Softmax的模型

    word2vec原理(三) 基於Negative Sampling的模型

    在上一篇中咱們講到了基於Hierarchical Softmax的word2vec模型,本文咱們咱們再來看看另外一種求解word2vec模型的方法:Negative Sampling。

1. Hierarchical Softmax的缺點與改進

    在講基於Negative Sampling的word2vec模型前,咱們先看看Hierarchical Softmax的的缺點。的確,使用霍夫曼樹來代替傳統的神經網絡,能夠提升模型訓練的效率。可是若是咱們的訓練樣本里的中心詞w

是一個很生僻的詞,那麼就得在霍夫曼樹中辛苦的向下走好久了。能不能不用搞這麼複雜的一顆霍夫曼樹,將模型變的更加簡單呢?

    Negative Sampling就是這麼一種求解word2vec模型的方法,它摒棄了霍夫曼樹,採用了Negative Sampling(負採樣)的方法來求解,下面咱們就來看看Negative Sampling的求解思路。

2. 基於Negative Sampling的模型概述

    既然名字叫Negative Sampling(負採樣),那麼確定使用了採樣的方法。採樣的方法有不少種,好比以前講到的大名鼎鼎的MCMC。咱們這裏的Negative Sampling採樣方法並無MCMC那麼複雜。

    好比咱們有一個訓練樣本,中心詞是w

,它周圍上下文共有2c個詞,記爲context(w)。因爲這個中心詞w,的確和context(w)相關存在,所以它是一個真實的正例。經過Negative Sampling採樣,咱們獲得neg個和w不一樣的中心詞wi,i=1,2,..neg,這樣context(w)wi就組成了neg個並不真實存在的負例。利用這一個正例和neg個負例,咱們進行二元邏輯迴歸,獲得負採樣對應每一個詞wi對應的模型參數θi

,和每一個詞的詞向量。

    從上面的描述能夠看出,Negative Sampling因爲沒有采用霍夫曼樹,每次只是經過採樣neg個不一樣的中心詞作負例,就能夠訓練模型,所以整個過程要比Hierarchical Softmax簡單。

    不過有兩個問題還須要弄明白:1)若是經過一個正例和neg個負例進行二元邏輯迴歸呢? 2) 如何進行負採樣呢?

    咱們在第三節討論問題1,在第四節討論問題2.

3. 基於Negative Sampling的模型梯度計算

    Negative Sampling也是採用了二元邏輯迴歸來求解模型參數,經過負採樣,咱們獲得了neg個負例(context(w),wi)i=1,2,..neg

。爲了統一描述,咱們將正例定義爲w0

    在邏輯迴歸中,咱們的正例應該指望知足:

P(context(w0),wi)=σ(xTw0θwi),yi=1,i=0

    咱們的負例指望知足:

P(context(w0),wi)=1σ(xTw0θwi),yi=0,i=1,2,..neg

    咱們指望能夠最大化下式:

i=0negP(context(w0),wi)=σ(xTw0θw0)i=1neg(1σ(xTw0θwi))

    利用邏輯迴歸和上一節的知識,咱們容易寫出此時模型的似然函數爲:

i=0negσ(xTw0θwi)yi(1σ(xTw0θwi))1yi

    此時對應的對數似然函數爲:

L=i=0negyilog(σ(xTw0θwi))+(1yi)log(1σ(xTw0θwi))

    和Hierarchical Softmax相似,咱們採用隨機梯度上升法,僅僅每次只用一個樣本更新梯度,來進行迭代更新獲得咱們須要的xwi,θwi,i=0,1,..neg

, 這裏咱們須要求出xw0,θwi,i=0,1,..neg

的梯度。

    首先咱們計算θwi

的梯度:

Lθwi=yi(1σ(xTw0θwi))xw0(1yi)σ(xTw0θwi)xw0=(yi−σ(xTw0θwi))xw0(1)(2)

    一樣的方法,咱們能夠求出xw0

的梯度以下:

Lxw0=i=0neg(yiσ(xTw0θwi))θwi

    有了梯度表達式,咱們就能夠用梯度上升法進行迭代來一步步的求解咱們須要的xw0,θwi,i=0,1,..neg

4. Negative Sampling負採樣方法

    如今咱們來看看如何進行負採樣,獲得neg個負例。word2vec採樣的方法並不複雜,若是詞彙表的大小爲V

,那麼咱們就將一段長度爲1的線段分紅V份,每份對應詞彙表中的一個詞。固然每一個詞對應的線段長度是不同的,高頻詞對應的線段長,低頻詞對應的線段短。每一個詞w的線段長度由下式決定:

len(w)=count(w)uvocabcount(u)

    在word2vec中,分子和分母都取了3/4次冪以下:

len(w)=count(w)3/4uvocabcount(u)3/4

    在採樣前,咱們將這段長度爲1的線段劃分紅M

等份,這裏M>>V,這樣能夠保證每一個詞對應的線段都會劃分紅對應的小塊。而M份中的每一份都會落在某一個詞對應的線段上。在採樣的時候,咱們只須要從M個位置中採樣出neg

個位置就行,此時採樣到的每個位置對應到的線段所屬的詞就是咱們的負例詞。

    在word2vec中,M

取值默認爲108

5.  基於Negative Sampling的CBOW模型

    有了上面Negative Sampling負採樣的方法和邏輯迴歸求解模型參數的方法,咱們就能夠總結出基於Negative Sampling的CBOW模型算法流程了。梯度迭代過程使用了隨機梯度上升法:

    輸入:基於CBOW的語料訓練樣本,詞向量的維度大小Mcount

,CBOW的上下文大小2c,步長η

, 負採樣的個數neg

    輸出:詞彙表每一個詞對應的模型參數θ

,全部的詞向量xw

    1. 隨機初始化全部的模型參數θ

,全部的詞向量w

    2. 對於每一個訓練樣本(context(w0),w0)

,負採樣出neg個負例中心詞wi,i=1,2,...neg

    3. 進行梯度上升迭代過程,對於訓練集中的每個樣本(context(w0),w0,w1,...wneg)

作以下處理:

      a)  e=0, 計算xw0=12ci=12cxi

      b)  for i= 0 to neg, 計算:

f=σ(xTw0θwi)
g=(yif)η
e=e+gθwi
θwi=θwi+gxw0

              c) 對於context(w)

中的每個詞向量xk(共2c個)進行更新:

xk=xk+e

 

      d) 若是梯度收斂,則結束梯度迭代,不然回到步驟3繼續迭代。

6.  基於Negative Sampling的Skip-Gram模型

    有了上一節CBOW的基礎和上一篇基於Hierarchical Softmax的Skip-Gram模型基礎,咱們也能夠總結出基於Negative Sampling的Skip-Gram模型算法流程了。梯度迭代過程使用了隨機梯度上升法:

    輸入:基於Skip-Gram的語料訓練樣本,詞向量的維度大小Mcount

,Skip-Gram的上下文大小2c,步長η

, , 負採樣的個數neg。

    輸出:詞彙表每一個詞對應的模型參數θ

,全部的詞向量xw

    1. 隨機初始化全部的模型參數θ

,全部的詞向量w

    2. 對於每一個訓練樣本(context(w0),w0)

,負採樣出neg個負例中心詞wi,i=1,2,...neg

    3. 進行梯度上升迭代過程,對於訓練集中的每個樣本(context(w0),w0,w1,...wneg)

作以下處理:

      a)  for i =1 to 2c:

        i)  e=0

        ii)  for j= 0 to neg, 計算:

f=σ(xTw0iθwj)
g=(yjf)η
e=e+gθwj
θwj=θwj+gxw0i

        iii)  詞向量更新:

xw0i=xw0i+e

      b)若是梯度收斂,則結束梯度迭代,算法結束,不然回到步驟a繼續迭代。

7.  Negative Sampling的模型源碼和算法的對應  

    這裏給出上面算法和word2vec源碼中的變量對應關係。

    在源代碼中,基於Negative Sampling的CBOW模型算法在464-494行,基於Hierarchical Softmax的Skip-Gram的模型算法在520-542行。你們能夠對着源代碼再深刻研究下算法。

    在源代碼中,neule對應咱們上面的e

, syn0對應咱們的xw, syn1neg對應咱們的θwi, layer1_size對應詞向量的維度,window對應咱們的c。negative對應咱們的neg, table_size對應咱們負採樣中的劃分數M

    另外,vocab[word].code[d]指的是,當前單詞word的,第d個編碼,編碼不含Root結點。vocab[word].point[d]指的是,當前單詞word,第d個編碼下,前置的結點。這些和基於Hierarchical Softmax的是同樣的。

    以上就是基於Negative Sampling的word2vec模型,但願能夠幫到你們,後面會講解用gensim的python版word2vec來使用word2vec解決實際問題。

 

 (歡迎轉載,轉載請註明出處。歡迎溝通交流: liujianping-ok@163.com)

 

0004,

詞嵌入的那些事兒(一)

1. 詞向量介紹

在討論詞嵌入以前,先要理解詞向量的表達形式,注意,這裏的詞向量不是指Word2Vec。關於詞向量的表達,現階段採用的主要有One hot representation和Distributed representation兩種表現形式。

1.1 One hot representation

顧名思義,採用獨熱編碼的方式對每一個詞進行表示。

例如,一段描述「杭州和上海今天有雨」,經過分詞工具能夠把這段描述分爲[‘杭州’,‘和’,‘上海’,今天’,‘有’,‘雨’],所以詞表的長度爲6,那麼‘杭州’、‘上海’、'今天'的One hot representation分別爲[1 0 0 0 0 0],[0 0 1 0 0 0],[0 0 0 1 0 0]。

能夠看到,One hot representation編碼的每一個詞都是一個維度,元素非0即1,且詞與詞之間彼此相互獨立。

1.2 Distributed representation

Distributed representation在One hot representation的基礎上考慮到詞與詞之間的聯繫,例如詞義、詞性等信息。每個維度元素再也不是0或1,而是連續的實數,表示不一樣的程度。Distributed representation 又包含了如下三種處理方式:

  • 基於矩陣的分佈表示。,矩陣中的一行,就成爲了對應詞的表示,這種表示描述了該詞的上下文的分佈。因爲分佈假說認爲上下文類似的詞,其語義也類似,所以在這種表示下,兩個詞的語義類似度能夠直接轉化爲兩個向量的空間距離。
  • 基於聚類的分佈表示。
  • 基於神經網絡的分佈表示。

而咱們如今常說的Distributed representation主要是基於神經網絡的分佈式表示的。例如‘杭州’、‘上海’的Distributed representation分別爲[0.3 1.2 0.8 0.7] 和 [0.5 1.2 0.6 0.8 ] 。

因此對於詞嵌入,咱們能夠理解爲是對詞的一種分佈式表達方式,而且是從高維稀疏向量映射到了相對低維的實數向量上。

2. 爲何使用詞嵌入

詞嵌入,每每和Distributed representation聯繫在一塊兒。這裏主要從計算效率、詞關係和數量這三點說明。

  1. 計算效率。採用One hot representation的每一個詞的向量長度是由詞彙表的數量決定,若是詞彙表數量很大,那麼每一個詞的長度會很長,同時,因爲向量元素只有一個元素爲1,其他元素爲0,因此,每一個詞的向量表達也會很是稀疏。而對於海量的詞語來說,計算效率是須要考慮的。
  2. 詞關係。和One hot representation相比,Distributed representation可以表達詞與詞之間的關係。
  3. 數量。對於把詞語做爲模型輸入的任務,對於類似的詞語,能夠經過較少樣本完成目標任務的訓練,而這是One hot representation所沒法企及的優點。

3. Language Models

因爲詞嵌入目的是爲了能更好地對NLP的輸入作預處理。因此在對詞嵌入技術做進一步討論以前,有必要對語言模型的發展作一些介紹。

3.1 Bag of words model

Bag of words model又稱爲詞袋模型,顧名思義,一段文本能夠用一個裝着這些詞的袋子來表示。詞袋模型一般將單詞和句子表示爲數字向量的形式,其中向量元素爲句子中此單詞在詞袋錶出現的次數。而後將數字向量輸入分類器(例如Naive Bayes),進而對輸出進行預測。這種表示方式不考慮文法以及詞的順序。

例如如下兩個句子:

  1. John likes to watch movies. Mary likes movies too.
  2. John also likes to watch football games.

基於以上兩個句子,能夠建構詞袋錶:"John""likes""to""watch""movies""also""football""games""Mary""too" ]

因爲詞袋錶的長度爲10,因此每一個句子的數字向量表示長度也爲10。下面是每一個句子的向量表示形式:

  1. [1, 2, 1, 1, 2, 0, 0, 0, 1, 1]
  2. [1, 1, 1, 1, 0, 1, 1, 1, 0, 0]

Bag of words model的優缺點很明顯:優勢是基於頻率統計方法,易於理解。缺點是它的假設(單詞之間徹底獨立)過於強大,沒法創建準確的模型。

3.2 N-Gram model

N-gram model的提出旨在減小傳統Bag of words model的一些強假設。

語言模型試圖預測在給定前t個單詞的前提下觀察t第 + 1個單詞w t + 1的機率:

利用機率的鏈式法則,咱們能夠計算出觀察整個句子的機率:

能夠發現,估計這些機率多是困難的。所以能夠用最大似然估計對每一個機率進行計算:

然而,即便使用最大似然估計方法進行計算,仍然很是困難:咱們一般沒法從語料庫中觀察到足夠多的數據,而且計算長度仍然很長。所以採用了馬爾可夫鏈的思想。

馬爾可夫鏈規定:系統下一時刻的狀態僅由當前狀態決定,不依賴於以往的任何狀態。即第t + 1個單詞的發生機率表示爲:

所以,一個句子的機率能夠表示爲:

一樣地,馬爾可夫假設能夠推廣到:系統下一時刻的狀態僅由當前0個、1個、2個...n個狀態決定這就是N-gram model的N的意思:對下一時刻的狀態設置當前狀態的個數。下面分別給出了unigram(一元模型)和bigram(二元模型)的第t + 1個單詞的發生機率:

能夠發現,N-Gram model 在Bag of words model的基礎上,經過採用馬爾科夫鏈的思想,減小了機率計算的複雜度,同時考慮了單詞間的相關性。

3.3 Word2Vec Model

Word2Vec模型實際上分爲了兩個部分,第一部分爲訓練數據集的構造,第二部分是經過模型獲取詞嵌入向量,即word embedding。

Word2Vec的整個建模過程實際上與自編碼器(auto-encoder)的思想很類似,即先基於訓練數據構建一個神經網絡,當這個模型訓練好之後,並不會用這個訓練好的模型處理新任務,而真正須要的是這個模型經過訓練數據所更新到的參數。

關於word embedding的發展,因爲考慮上下文關係,因此模型的輸入和輸出分別是詞彙表中的詞組成,進而產生出了兩種詞模型方法:Skip-Gram和CBOW。同時,在隱藏層-輸出層,也從softmax()方法演化到了分層softmax和negative sample方法。

因此,要拿到每一個詞的詞嵌入向量,首先須要理解Skip-Gram和CBOW。下圖展現了CBOW和Skip-Gram的網絡結構:

本文以Skip-Gram爲例,來理解詞嵌入的相關知識。Skip-Gram是給定input word來預測上下文。咱們能夠用小學英語課上的造句來幫助理解,例如:「The __________」。

關於Skip-Gram的模型結構,主要分爲幾下幾步:

  1. 從句子中定義一箇中心詞,即Skip-Gram的模型input word
  2. 定義skip_window參數,用於表示從當前input word的一側(左邊及右邊)選取詞的數量。
  3. 根據中心詞和skip_window,構建窗口列表。
  4. 定義num_skips參數,用於表示從當前窗口列表中選擇多少個不一樣的詞做爲output word。

假設有一句子"The quick brown fox jumps over the lazy dog" ,設定的窗口大小爲2(window\_size=2),也就是說僅選中心詞(input word)先後各兩個詞和中心詞(input word)進行組合。以下圖所示,以步長爲1對中心詞進行滑動,其中藍色表明input word,方框表明位於窗口列表的詞。

因此,咱們可使用Skip-Gram構建出神經網絡的訓練數據。

咱們須要明白,不能把一個詞做爲文本字符串輸入到神經網絡中,因此咱們須要一種方法把詞進行編碼進而輸入到網絡。爲了作到這一點,首先從須要訓練的文檔中構建出一個詞彙表,假設有10,000個各不相同的詞組成的詞彙表。那麼須要作的就是把每個詞作One hot representation。此外神經網絡的輸出是一個單一的向量(也有10000個份量),它包含了詞彙表中每個詞隨機選擇附近的一個詞的機率。

3.4 Skip-Gram網絡結構

下圖是須要訓練的神經網絡結構。左側的神經元Input Vector是詞彙表中進行One hot representation後的一個詞,右側的每個神經元則表明着詞彙表的每個詞。實際上,在對該神經網絡feed訓練數據進行訓練時,不只輸入詞input word(中心詞)是用One hot representation表示,輸出詞output word也是用One hot representation進行表示。但當對此網絡進行評估預測時,輸出向量其實是經過softmax()函數計算獲得的一個詞彙表全部詞的機率分佈(即一堆浮點值,而不是一個One hot representation)。

3.5 Word2Vec Model隱藏層

假設咱們正在學習具備300個特徵的詞向量。所以,隱藏層將由一個包含10,000行(每一個單詞對應一行)和300列(每一個隱藏神經元對應一列)的權重矩陣來表示。(注:谷歌在其發佈的模型中的隱藏層使用了300個輸出(特徵),這些特徵是在谷歌新聞數據集中訓練出來的(您能夠從這裏下載)。特徵的數量300則是模型進行調優選擇後的「超參數」)。

下面左右兩張圖分別從不一樣角度表明了輸入層-隱層的權重矩陣。

從左圖看,每一列表明一個One hot representation的詞和隱層單個神經元鏈接的權重向量。從右圖看,每一行實際上表明瞭每一個詞的詞向量,或者詞嵌入。

因此咱們的目標就是學習輸入層-隱藏層的權矩陣,而隱藏層-輸出層的部分,則是在模型訓練完畢後不須要保存的參數。這一點,與自編碼器的設計思想是相似的。

你可能會問本身,難道真的分別要把每個One hot representation的詞(1 x 10000)與一個10000 x 300的權矩陣相乘嗎?實際上,並非這樣。因爲One hot representation的詞具備只有一個元素這爲1,其他元素值爲0的特性,因此能夠經過查找One hot representation中元素爲1的位置索引,進而得到對應要乘以的10000 x 300的權矩陣的向量值,從而解決計算速度緩慢的問題。下圖的例子,可幫助咱們進一步理解。

能夠看到,One hot representation中元素爲1的位置索引爲3,因此只須要乘以10000 x 300的權矩陣中位置索引一樣爲3的向量值便可獲得相應的輸出。

3.6 Word2Vec Model輸出層

下面是計算「car」這個單詞的輸出神經元的輸出的例子:

4. 基於Tensorflow的Skip-Gram極簡實現

網上找了一些Tensorflow版本的skip-gram實現,但都有一個問題,輸入單詞並無按照論文的要求作One hot representation,不知道是否是出於計算速度方面的考慮。所以,本小節的代碼仍是遵循原論文的描述,對輸入單詞及輸出單詞首先作了One hot representation。

首先,是訓練數據的構造,包括skip_window上下文參數、詞的One hot representation以及中心詞、輸出詞對的構造。

按 Ctrl+C 複製代碼
按 Ctrl+C 複製代碼

其次,是Tensorflow計算圖的構造,包括輸入輸出的定義、輸入層-隱藏層,隱藏層-輸出層的構造以及損失函數、優化器的構造。最後輸出每一個詞的word embedding。具體代碼以下所示:

按 Ctrl+C 複製代碼
按 Ctrl+C 複製代碼

上述代碼的計算圖能夠簡單表示爲如下形式:

最後,打印出每一個單詞的詞嵌入向量以下所示:

 當詞嵌入向量訓練完成後,咱們能夠進行一個簡單的測試,這裏經過計算詞嵌入向量間的歐氏距離尋找相近的詞:

複製代碼
# 測試 def euclidean_dist(vec1, vec2): """歐氏距離""" return np.sqrt(np.sum((vec1 - vec2) ** 2)) def find_closest(word_index, vectors): min_dist = 10000 # to act like positive infinity min_index = -1 query_vector = vectors[word_index] for index, vector in enumerate(vectors): if euclidean_dist(vector, query_vector) < min_dist and not np.array_equal(vector, query_vector): min_dist = euclidean_dist(vector, query_vector) min_index = index return min_index print('與 king 最接近的詞是:', int2word[find_closest(word2int['king'], vectors)]) print('與 queen 最接近的詞是:', int2word[find_closest(word2int['queen'], vectors)]) print('與 royal 最接近的詞是:', int2word[find_closest(word2int['royal'], vectors)])
複製代碼

下面是輸出的測試結果:

5. 總結

  1. 詞嵌入是一種把詞從高維稀疏向量映射到了相對低維的實數向量上的表達方式。
  2. Skip-Gram和CBOW的做用是構造神經網絡的訓練數據。
  3. 目前設計的網絡結構其實是由DNN+softmax()組成。
  4. 因爲每一個輸入向量有且僅有一個元素爲1,其他元素爲0,因此計算詞嵌入向量實際上就是在計算隱藏層的權矩陣。
  5. 對於單位矩陣的每一維(行)與實矩陣相乘,能夠簡化爲查找元素1的位置索引從而快速完成計算。

6. 結束了嗎?

仔細閱讀代碼,咱們發現prediction時,使用的是softmax()。即輸入詞在輸出層分別對詞彙表的每個詞進行機率計算,若是在海量詞彙表的前提下,計算效率是否須要考慮在內?有沒有更快的計算方式呢?

此外,本文第3節提到的分層softmax是什麼?negative samples又是什麼?Huffman code又是怎樣使用的?關於這些問題的思考,請關注:詞嵌入的那些事兒(二)

7. 參考資料

[1] Word2Vec Tutorial - The Skip-Gram Model

 

0005,

詞嵌入的那些事兒(二)

在文章詞嵌入的那些事兒(一)中,咱們獲得瞭如下結論:

  1. 詞嵌入是一種把詞從高維稀疏向量映射到了相對低維的實數向量上的表達方式。
  2. Skip-Gram和CBOW的做用是構造神經網絡的訓練數據。
  3. 目前設計的網絡結構其實是由DNN+softmax()組成。
  4. 計算詞嵌入向量實際上就是在計算隱藏層的權矩陣。
  5. 對於單位矩陣的每一維(行)與實矩陣相乘,能夠簡化爲查找元素1的位置索引從而快速完成計算。

本文主要是在上文的基礎上,對模型的隱藏層-輸出層的設計作進一步探索。

1. 霍夫曼編碼

霍夫曼編碼(Huffman Coding),又譯爲哈夫曼編碼、赫夫曼編碼,是一種用於無損數據壓縮的熵編碼(權編碼)算法。

霍夫曼樹常處理符號編寫工做。根據整組數據中符號出現的頻率高低,決定如何給符號編碼。若是符號出現的頻率越高,則給符號的碼越短,相反符號的號碼越長。假設咱們要給一個英文單字"F O R G E T"進行霍夫曼編碼,而每一個英文字母出現的頻率分別以下圖所示。

1.1 建立霍夫曼樹

進行霍夫曼編碼前,咱們先建立一個霍夫曼樹,具體步驟以下:

  1. 將每一個英文字母依照出現頻率由小排到大,最小在左,如上圖所示。
  2. 每一個字母都表明一個終端節點(葉節點),比較F.O.R.G.E.T六個字母中每一個字母的出現頻率,將最小的兩個字母頻率相加合成一個新的節點。如Fig.2所示,發現FO的頻率最小,故相加2+3=5。
  3. 比較5.R.G.E.T,發現RG的頻率最小,故相加4+4=8。
  4. 比較5.8.E.T,發現5E的頻率最小,故相加5+5=10。
  5. 比較8.10.T,發現8T的頻率最小,故相加8+7=15。
  6. 最後剩10.15,沒有能夠比較的對象,相加10+15=25。
  7. 最後產生的樹狀圖就是霍夫曼樹,參考下圖。 

 

1.2 進行編碼

給霍夫曼樹的全部左節點設置爲'0',全部右節點設置爲'1'。

從根節點到葉子節點依序記錄全部字母的編碼,以下圖所示:

以上步驟就是對詞進行霍夫曼編碼的操做步驟。能夠看到,詞的出現頻率越高,越靠近根節點,且編碼長度越短。

2. Hierarchical Softmax的理解

首先回顧一下softmax函數。softmax(規範化指數函數)是網絡輸出層的函數,用於計算包含至少兩種不一樣類型的詞嵌入向量。此外,它也常常被用做爲神經網絡的激活函數,相似的還包括sigmoid和tanh等函數。softmax的公式以下:

其中,激活輸出向量的每一個元素都是在給定輸入單詞I的狀況下,等於詞彙表中第j個單詞時的機率。同時,激活輸出向量的全部元素之和等於1且每一個元素映射到區間[0,1]。這個算法的計算複雜度便是詞彙表的大小O(V)。實踐代表,咱們能夠經過使用二叉樹結構來有效地地減小此計算複雜度。下面,將介紹Hierarchical Softmax。

使用Hierarchical Softmax的主要緣由是其計算複雜度是以2爲底V的對數。

每一個單詞均可以經過從根節點-內部節點的路徑到達,此外,對這個路徑的度量能夠由沿着這條路徑的各機率乘積表示。各個機率值由sigmoid函數產生:

其中x由輸入和輸出向量的點積求出,n(w,j)表示爲從根節點到葉子結點w(即上下文單詞)的路徑上的第j個節點。

實際上,咱們能夠用機率p來代替sigmoid函數。對於每一個內部節點,咱們都選擇了一個任意子節點(左或右),並將正的sigmoid函數值賦給其中的一個(一般是左子節點)。

經過保留這些約束,節點n的左子節點的sigmoid函數能夠描述爲:

同理,節點n的右子節點的sigmoid函數能夠描述爲:

因此,輸出詞的計算機率爲:

其中,L(w)表示霍夫曼樹的深度,ch(n)表示節點n的子節點;角大括號表示布爾檢驗是否爲真或假:若是布爾檢驗爲True,說明節點n與其子節點ch(n)都在樹的左邊,即其子節點爲左子節點。反之,若是布爾值爲False,即其子節點ch(n)爲右子節點。

回顧詞嵌入的那些事兒(一)基於Tensorfow的Skip-Gram極簡實現的內容,模型輸出的實際上是預測目標詞的機率,也就是說每一次預測都要基於所有的數據集進行softmax()機率計算。神經網絡結構以下圖所示:

而採用Hierarchical Softmax後,因爲替換了以前的softmax()函數,因此,隱藏層的詞嵌入向量不須要對詞彙表每一個單詞計算其爲輸出詞的機率。

例如假設輸出詞是w2,所以能夠沿着霍夫曼樹從根節點(即詞嵌入向量)一直走到咱們的葉子節點w2(輸出詞)。由下圖能夠觀察到,僅需執行3步的sigmoid函數計算,就能夠肯定葉子節點w2的位置。這無疑大大減小了操做數。

實際上,咱們在計算詞嵌入向量所採用的霍夫曼編碼與第一節的介紹基本一致,區別只是對左右節點的0 1計數有所不一樣,好比:

3. Negative Sampling的理解

那麼,霍夫曼樹是否是計算詞嵌入向量的最優解?假設咱們的訓練樣本里的中心詞w是一個很生僻的詞,那麼就得在霍夫曼樹中一直往下尋找路徑。能不能不用搞這麼複雜的一顆霍夫曼樹,將模型變的更加簡單呢?Negative Sampling就是這麼一種求解word2vec模型的方法,它摒棄了霍夫曼樹,採用了Negative Sampling(負採樣)的方法來求解,下面咱們就來看看Negative Sampling的求解思路。

首先,須要瞭解噪聲對比估計(NCE)。

3.1 噪聲對比估計(NCE)

噪聲對比估計(NCE)的核心思想是經過logistic迴歸將一個多分類問題轉化爲一個二分類問題,同時保留學習到的詞向量的質量。在NCE中,詞向量再也不是經過從中心詞中預測上下文單詞來學習,相反經過學習如何從(target, random word from vocabulary)對中區分出真實的(target, context)對從而完成詞向量的計算。換句話說,若是一個模型可以從隨機噪聲中分辨出實際的目標詞對和上下文詞對,那麼好的詞向量就會被學習。

3.2 Negative Sampling

而Negative Sampling是基於噪聲對比估計(相似於生成對抗性網絡)的一種方法。

即一個好的模型應該經過邏輯迴歸來區分假信號和真實信號。同時Negative Sampling背後的思想相似於隨機梯度降低:不是每次都改變全部的權重,考慮到咱們所擁有的成千上萬的觀測數據,咱們只使用了其中的K個,而且顯著地提升了計算效率:

正如上圖公式,與隨機梯度降低法的區別在於,咱們不只考慮了一個觀測結果還考慮了其中的K個。

對於訓練數據集,咱們使用的是具備噪聲分佈的數據集。之因此使用這種噪聲分佈數據集,是爲了區分真實數據和咱們試圖解決的假數據。具體來講,對於每一個正樣本(即 true target/context pair),咱們從噪聲分佈中隨機抽取k個負樣本,並feed進模型。對於小的訓練數據集,建議k值在5到20之間,而對於很是大的數據集,k值在2到5之間就足夠了。咱們的模型只有一個輸出節點,它能夠預測這對數據是隨機噪聲數據仍是真實有效的target/context對。

因爲採用了隨機採樣,因此須要假定一個機率分佈。在詞彙表中每一個單詞wi被採樣到的機率由下式決定,其中冪爲3/4。之所取3/4是由於能夠減弱因爲不一樣頻次差別過大形成的單詞采樣差別的影響,使得小頻次的單詞也有必定被採樣的機率。f(w)是詞彙表中單詞w出現的頻率:

舉例說明:

在採樣前,咱們將長度爲1的線段劃分紅M等份,這裏M>>V,這樣能夠保證每一個詞對應的線段都會劃分紅對應的區間塊。在採樣時,咱們只須要從M個區間中採樣出neg個區間,此時採樣到的每個區間塊對應到的線段所屬的詞就是咱們的負例詞。 

可能會有疑問:使用Negative Sampling後,負樣本數量較多,正樣本只有一個,會不會出現樣本不均衡的現象從而致使邏輯迴歸模型分錯左右子節點?實際上,樣本不均衡這種問題主要出如今分類算法中。而咱們這裏詞向量的訓練本質不是一個分類問題,因此問題不大。

最後,通常來說,NCE是一種漸近無偏的通常參數估計技術,而Negative Sampling更常常被用在二分類模型(例如邏輯迴歸)中,它們對詞向量學習有用,但不是做爲通用估計器去執行其餘機器學習任務。具體能夠參考這篇論文:Notes on Noise Contrastive Estimation and Negative Sampling 。

4. 總結

  1. 霍夫曼編碼會使得出現頻率最高的詞編碼長度最短,且路徑最短。
  2. Negative Sampling的核心思想是每次訓練只隨機取一小部分的負例使他們的機率最小,以及對應的正例機率最大。
  3. 相比於Hierarchical Softmax,Negative Sampling再也不採用霍夫曼樹,而是採用隨機負採樣。
  4. 從計算效率上講,Negative Sampling優於Hierarchical Softmax優於Softmax。

5. 參考資料

[1] 維基百科:霍夫曼編碼

[2] Language Models, Word2Vec, and Efficient Softmax Approximations

[3] word2vec(cbow skip-gram hierarchical softmax Negative sampling)模型深度解析

相關文章
相關標籤/搜索