任務3 word2vec詞向量原理與實踐

Word2Vec的定義

在講述 Word2vec 之前,先說NLP (自然語言處理)。NLP 裏面,最細粒度的是 詞語,詞語組成句子,句子再組成段落、篇章、文檔。所以處理 NLP 的問題,首先就要拿詞語開刀。
先舉個例子,判斷一個詞的詞性,是動詞還是名詞。用機器學習的思路,我們有一系列樣本(x,y),這裏 x 是詞語,y 是它們的詞性,我們要構建 f(x)->y 的映射,但這裏的數學模型 f(比如神經網絡、SVM)只接受數值型輸入,而 NLP 裏的詞語,是人類的抽象總結,是符號形式的(比如中文、英文、拉丁文等等),所以需要把他們轉換成數值形式,或者說——嵌入到一個數學空間裏,這種嵌入方式,就叫詞嵌入(word embedding),而 Word2vec,就是詞嵌入( word embedding) 的一種。
在大部分的有監督機器學習模型,額可以歸結爲:
f(x)>yf(x) -> y
在 NLP 中,把 x 看做一個句子裏的一個詞語,y 是這個詞語的上下文詞語,那麼這裏的 f,便是 NLP 中經常出現的『語言模型』(language model),這個模型的目的,就是判斷 (x,y) 這個樣本,是否符合自然語言的法則,更通俗點說就是:詞語x和詞語y放在一起,是不是人話。

Word2vec 正是來源於這個思想,但它的最終目的,不是要把 f 訓練得多麼完美,而是隻關心模型訓練完後的副產物——模型參數(這裏特指神經網絡的權重),並將這些參數,作爲輸入 x 的某種向量化的表示,這個向量便叫做——詞向量.

Skip-gram 和 CBOW 模型

上面我們提到了語言模型

如果是用一個詞語作爲輸入,來預測它周圍的上下文,那這個模型叫做『Skip-gram 模型』
而如果是拿一個詞語的上下文作爲輸入,來預測這個詞語本身,則是 『CBOW 模型』

Skip-gram 和 CBOW 的簡單情形

我們先來看個最簡單的例子。上面說到, y 是 x 的上下文,所以 y 只取上下文裏一個詞語的時候,語言模型就變成:用當前詞 x 預測它的下一個詞 y。

但如上面所說,一般的數學模型只接受數值型輸入,這裏的 x 該怎麼表示呢? 顯然不能用 Word2vec,因爲這是我們訓練完模型的產物,現在我們想要的是 x 的一個原始輸入形式。
這樣我們首先採用的是one-hot encoder。

one-hot encoder是用一個只含一個 1、其他都是 0 的向量來唯一表示詞語。

我舉個例子,假設全世界所有的詞語總共有 V 個,這 V 個詞語有自己的先後順序,假設『吳彥祖』這個詞是第1個詞,『我』這個單詞是第2個詞,那麼『吳彥祖』就可以表示爲一個 V 維全零向量、把第1個位置的0變成1,而『我』同樣表示爲 V 維全零向量、把第2個位置的0變成1。這樣,每個詞語都可以找到屬於自己的唯一表示。

OK,那我們接下來就可以看看 Skip-gram 的網絡結構了,x 就是上面提到的 one-hot encoder 形式的輸入,y 是在這 V 個詞上輸出的概率,我們希望跟真實的 y 的 one-hot encoder 一樣。
在這裏插入圖片描述
首先說明一點:隱層的激活函數其實是線性的,相當於沒做任何處理(這也是 Word2vec 簡化之前語言模型的獨到之處),我們要訓練這個神經網絡,用反向傳播算法,本質上是鏈式求導,在此不展開說明了。

當模型訓練完後,最後得到的其實是神經網絡的權重,比如現在輸入一個 x 的 one-hot encoder: [1,0,0,…,0],對應剛說的那個詞語『吳彥祖』,則在輸入層到隱含層的權重裏,只有對應 1 這個位置的權重被激活,這些權重的個數,跟隱含層節點數是一致的,從而這些權重組成一個向量 vx 來表示x,而因爲每個詞語的 one-hot encoder 裏面 1 的位置是不同的,所以,這個向量 vx 就可以用來唯一表示 x。

注意:上面這段話說的就是 Word2vec 的精髓!!

此外,我們剛說了,輸出 y 也是用 V 個節點表示的,對應V個詞語,所以其實,我們把輸出節點置成 [1,0,0,…,0],它也能表示『吳彥祖』這個單詞,但是激活的是隱含層到輸出層的權重,這些權重的個數,跟隱含層一樣,也可以組成一個向量 vy,跟上面提到的 vx 維度一樣,並且可以看做是詞語『吳彥祖』的另一種詞向量。而這兩種詞向量 vx 和 vy,正是 Mikolov 在論文裏所提到的,『輸入向量』和『輸出向量』,一般我們用『輸入向量』。

需要提到一點的是,這個詞向量的維度(與隱含層節點數一致)一般情況下要遠遠小於詞語總數 V 的大小,所以 Word2vec 本質上是一種降維操作——把詞語從 one-hot encoder 形式的表示降維到 Word2vec 形式的表示。

Skip-gram 更一般的情形

上面討論的是最簡單情形,即 y 只有一個詞,當 y 有多個詞時,網絡結構如下:
在這裏插入圖片描述
可以看成是 單個x->單個y 模型的並聯,cost function 是單個 cost function 的累加(取log之後)

如果你想深入探究這些模型是如何並聯、 cost function 的形式怎樣,不妨仔細閱讀參考資料4. 在此我們不展開。

CBOW 更一般的情形

跟 Skip-gram 相似,只不過:
Skip-gram 是預測一個詞的上下文,而 CBOW 是用上下文預測這個詞
網絡結構如下
在這裏插入圖片描述
更 Skip-gram 的模型並聯不同,這裏是輸入變成了多個單詞,所以要對輸入處理下(一般是求和然後平均),輸出的 cost function 不變,在此依然不展開。

Word2vec 的訓練trick

Hierarchical softmax 只是 softmax 的一種近似形式,而 negative sampling 也是從其他方法借鑑而來。

爲什麼要用訓練技巧呢? 如我們剛提到的,Word2vec 本質上是一個語言模型,它的輸出節點數是 V 個,對應了 V 個詞語,本質上是一個多分類問題,但實際當中,詞語的個數非常非常多,會給計算造成很大困難,所以需要用技巧來加速訓練。

Word2vec 實踐

import gensim
vector_size = 100

def sentence2list(sentence):
    return sentence.strip().split()

sentences_train = list(train_set.loc[:, 'word_seg'].apply(sentence2list))
sentences_test = list(val_set.loc[:, 'word_seg'].apply(sentence2list))
sentences = sentences_train + sentences_test

wv = model.wv
vocab_list = wv.index2word
word_idx_dict = {}
for idx, word in enumerate(vocab_list):
    word_idx_dict[word] = idx
    
vectors_arr = wv.vectors
vectors_arr = np.concatenate((np.zeros(vector_size)[np.newaxis, :], vectors_arr), axis=0)

參考文獻:
https://zhuanlan.zhihu.com/p/26306795

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章