word2vec原理(一) CBOW與Skip-Gram模型基礎html
word2vec原理(二) 基於Hierarchical Softmax的模型git
word2vec原理(三) 基於Negative Sampling的模型github
word2vec是google在2013年推出的一個NLP工具,它的特色是將全部的詞向量化,這樣詞與詞之間就能夠定量的去度量他們之間的關係,挖掘詞之間的聯繫。雖然源碼是開源的,可是谷歌的代碼庫國內沒法訪問,所以本文的講解word2vec原理以Github上的word2vec代碼爲準。本文關注於word2vec的基礎知識。算法
用詞向量來表示詞並非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} $$post
可見咱們只要獲得了詞彙表裏全部詞對應的詞向量,那麼咱們就能夠作不少有趣的事情了。不過,怎麼訓練獲得合適的詞向量呢?一個很常見的方法是使用神經網絡語言模型。優化
在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計算各個詞的輸出機率的的計算量很大。有沒有簡化一點點的方法呢?
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)