1. 程式人生 > >word embedding的模型與測試

word embedding的模型與測試

模型

text:

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

one-hot

這裡寫圖片描述
缺點:高維度,稀疏性,相似度無法衡量

co-occurrence

這裡寫圖片描述
優點:相似度一定程度上可以衡量
缺點:高維度,稀疏性

SVD(降維)

觀察發現,前10%甚至前10%的奇異值的和佔了全部奇異值之和的99%以上
這裡寫圖片描述
優點:改善了高緯度,稀疏性,相似度無法衡量問題
缺點:複雜度高O(mn2)

word2vec

對原始的NNLM模型做如下改造:

  1. 移除前向反饋神經網路中非線性的hidden layer,直接將中間層的embedding layer與輸出層的softmax layer連線;
  2. 忽略上下文環境的序列資訊:輸入的所有詞向量均彙總到同一個embedding layer;
  3. 將future words納入上下文環境

從數學上看,CBoW模型等價於一個詞袋模型的向量乘以一個embedding矩陣,從而得到一個連續的embedding向量。這也是CBoW模型名稱的由來。

CBoW模型依然是從context對target word的預測中學習到詞向量的表達。反過來,我們能否從target word對context的預測中學習到word vector呢?答案顯然是可以的:這個模型被稱為Skip-gram模型(名稱源於該模型在訓練時會對上下文環境裡的word進行取樣)。

這裡寫圖片描述

如果將Skip-gram模型的前向計算過程寫成數學形式,我們得到:

這裡寫圖片描述
Skip-gram模型的本質是計算輸入word的input vector與目標word的output vector之間的餘弦相似度,並進行softmax歸一化。

疑問:為什麼不用NNLM去訓練詞向量
答:NNLM存在的幾個問題。NNLM的訓練太慢了,NNLM模型只能處理定長的序列。
原始的NNLM模型的訓練其實可以拆分成兩個步驟:
1.用一個簡單模型訓練出連續的詞向量;
2.基於詞向量的表達,訓練一個連續的Ngram神經網路模型。
word2vec實現的就是第一步。

疑問:模型輸入的詞向量都是隨機的,如何訓練模型的同時,訓練這些詞向量的?
答:
會先跟據語料建立一個詞彙表,所有的訓練樣本應該是(前n-1個詞的索引,第n個詞的索引),對應一個C表,|V|*m, m是詞向量的維度,|V|是詞彙表的詞量。訓練的時候,更新語言模型的同時,也更新C表,這樣,每個詞對應的詞向量就更新了。

手繪word2vec實現原理圖,手殘見諒。
這裡寫圖片描述
首先,它的結構就是一個三層網路——輸入層、隱層(也可稱為對映層),輸出層。

輸入層讀入視窗內的詞,將它們的向量(K維,初始隨機)加和在一起,形成隱藏層K個節點。輸出層是一個巨大的二叉樹,葉節點代表語料裡所有的詞(語料含有V個獨立的詞,則二叉樹有|V|個葉節點)。而這整顆二叉樹構建的演算法就是Huffman樹。這樣,對於葉節點的每一個詞,就會有一個全域性唯一的編碼,形如”010011”。我們可以記左子樹為1,右子樹為0。接下來,隱層的每一個節點都會跟二叉樹的內節點有連邊,於是對於二叉樹的每一個內節點都會有K條連邊,每條邊上也會有權值。

在訓練階段,當給定一個上下文,要預測中心詞(Wn)的時候,實際上我們知道要的是哪個詞(Wn),而Wn是肯定存在於二叉樹的葉子節點的,因此它必然有一個二進位制編號,如”010011”,那麼接下來我們就從二叉樹的根節點一個個地去便利,而這裡的目標就是預測這個詞的二進位制編號的每一位!即對於給定的上下文,我們的目標是使得預測詞的二進位制編碼概率最大。形象地說,我們希望(詞向量和)與(節點相連邊的權重)經過logistic計算得到的概率儘量接近0;在第二層,概率儘量接近1……這麼一直下去,我們把一路上計算得到的概率相乘,即得到目標詞Wn在當前網路下的概率(P(Wn)),那麼對於當前這個sample的殘差就是1-P(Wn)。於是就可以SGD優化各種權值了。

按照目標詞的二進位制編碼計算到最後的概率值就是歸一化的,這也是為啥它被稱作hierarchical softmax的原因。傳統的softmax,就需要對|V|中的每一個詞都算一遍,這個過程時間複雜度是O(|V|)的。而使用了二叉樹(如word2vec中的Huffman樹),其時間複雜度就降到了O(log2(|V|)),速度大大地加快了。

Glove

全域性的共現矩陣求法舉例:
這裡寫圖片描述
公式:
這裡寫圖片描述

測試

分為內部測試和外部測試:
內部測試:測試語法,語義,詞義。
論文實驗結果:
這裡寫圖片描述
本實驗結果:
這裡寫圖片描述
內部測試:NER(命名實體識別)
實驗結果:
這裡寫圖片描述

結果

經過實驗對比,三個模型的效果同等條件下差別不大,最終選擇CBOW模型訓練,原因如下:
1:CBOW有成熟的開源工具包gensim.word2vec,可以提供分散式訓練
2:word2vec可以線上訓練,glove不可以
3:CBOW比SG訓練速度快

word2vec訓練方法

import multiprocessing
from gensim.models import Word2Vec
def train_model1(corpusfilename, modelfilenamebin, modelfilenametxt, size):
  """訓練一個詞向量模型"""
  model = Word2Vec(MySentences(corpusfilename),
  hs=1, size=size, window=5, min_count=10, iter=10, workers=multiprocessing.cpu_count())

  model.save(modelfilenamebin)
  model.wv.save_word2vec_format(modelfilenametxt, binary=False)

引數解釋:
1.sg=1是skip-gram演算法,對低頻詞敏感;預設sg=0為CBOW演算法。
2.size是輸出詞向量的維數,值太小會導致詞對映因為衝突而影響結果,值太大則會耗記憶體並使演算法計算變慢,一般值取為100到300之間。
3.window是句子中當前詞與目標詞之間的最大距離,3表示在目標詞前看3-b個詞,後面看b個詞(b在0-3之間隨機)。
4.min_count是對詞進行過濾,頻率小於min-count的單詞則會被忽視,預設值為5。
5.negative和sample可根據訓練結果進行微調,sample表示更高頻率的詞被隨機下采樣到所設定的閾值,預設值為1e-3。
6.workers控制訓練的並行,此引數只有在安裝了Cpython後才有效,否則只能使用單核。

word2vec模型背後的基本思想是對出現在上下文環境裡的詞進行預測。對於每一條輸入文字,我們選取一個上下文視窗和一箇中心詞,並基於這個中心詞去預測窗口裡其他詞出現的概率。因此,word2vec模型可以方便地從新增語料中學習到新增詞的向量表達,是一種高效的線上學習演算法(online learning)。

def retrain(corpusfilename,modelfilenamebin,remodelfilenamebin,remodelfilenametxt):
  model = Word2Vec.load(modelfilenamebin)
  model.build_vocab(MySentences(corpusfilename), update=True)
  model.train(MySentences(corpusfilename), total_examples=model.corpus_count, epochs=10)
  model.save(remodelfilenamebin)
  model.wv.save_word2vec_format(remodelfilenametxt, binary=False)

參考文獻

  1. Distributed Representations of Words and Phrases and their Compositionality
  2. Efficient Estimation of Word Representations in Vector Space
  3. GloVe Global Vectors forWord Representation
  4. 參考了一些部落格網站,不一一列表,但非常感謝