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

劉建平Pinard發表於2017-07-13

    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維,有一個有趣的研究表明,用下圖的詞向量表示我們的詞時,我們可以發現:$$\vec {King} - \vec {Man} + \vec {Woman} = \vec {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的訓練我們在下一節講,這裡我們先複習下霍夫曼樹。

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

    輸入:權值為$(w_1,w_2,...w_n)$的$n$個節點

    輸出:對應的霍夫曼樹

    1)將$(w_1,w_2,...w_n)$看做是有$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模型。

 

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

相關文章