word2vec原理、推導(dǎo)與總結(jié)

本篇博客主要記錄一下對(duì)語(yǔ)言模型、Word2Vec、ELMo和BERT學(xué)習(xí)和總結(jié),有些地方肯定理解不到位,希望小伙伴們賜教。

一、詞表征(Word Representation)

1、詞表征

首先明確句子是序列化,里面攜帶了大量大信息。在NLP發(fā)展的進(jìn)程里面, 采用了one-hot vector的形式來(lái)表示一個(gè)句子里面的詞是一種方式。表示這個(gè)句子的方式如下:
1、首先是創(chuàng)建一張?jiān)~匯表(Vocabulary),然后每個(gè)詞都有對(duì)應(yīng)的位置,假設(shè)現(xiàn)在我們有10000個(gè)單詞。本例子來(lái)自于吳恩達(dá)的Deeplearningai。圖中所示的詞匯表大小就是10000。一般規(guī)模的商業(yè)應(yīng)用來(lái)說(shuō),詞匯表大小為30000到50000詞。大型互聯(lián)網(wǎng)是百萬(wàn)級(jí)別的詞匯表。

image.png
2、將句子里面的每個(gè)單詞轉(zhuǎn)換為one-hot vector。one-hot vector從字面上來(lái)理解就是向量里面只有1個(gè)1,也就是找到這個(gè)詞在詞匯表里面的位置處填上1,然后其他的位置都是0??梢钥闯鰋ne-hot vector的模長(zhǎng)為1。
one-hot vector表示向量的缺陷:
(1)這種表示把每個(gè)詞都孤立出來(lái)了,使得算法對(duì)相關(guān)詞的泛化能力弱。兩個(gè)不同人名的one-hot vector的內(nèi)積為0,這樣來(lái)表示就不能體現(xiàn)出詞匯在某些方面的相關(guān)性

(2)這樣得到的向量是稀疏的,而且維度非常的大。

那么現(xiàn)在提個(gè)問(wèn)題:我們?cè)趺磥?lái)表示詞匯,能夠?qū)⒁恍┫嚓P(guān)詞匯之間的一些共通特征給表現(xiàn)出來(lái)呢?

2、詞嵌入(Word Embeddings)

前面我們看到了one-hot vector表示一個(gè)詞,只有一個(gè)維度有意義。那么我們可以想想,能不能把一些相似詞匯的一些特征抽取出來(lái),給詞不同的維度賦予一些意思呢?結(jié)果就出現(xiàn)了詞嵌入的方式來(lái)表示句子里面的詞。
(1)詞嵌入:顧名思義,就是將一些特征給嵌入到詞匯里面,讓它能表現(xiàn)出更多的信息。
現(xiàn)在舉個(gè)例子:
1)性別特征:我們可以看出一些詞如Man, Woman, King, Queen是有關(guān)系的,那么我們就在gender這一欄給填上相關(guān)性的權(quán)重,然后詞如Apple, Orange這些就與gender,沒(méi)有關(guān)系,那么就是賦予趨近于0的權(quán)重。
2)年齡特征:可以看出King, Queen和age還是很想關(guān)的,但是Man, Woman, Apple, Orange與此就沒(méi)有多大關(guān)系了。
采用相同的策略,我們可以從很多特征(Food、size、cost、alive等)來(lái)考察一個(gè)詞在這些特征上面是否有關(guān)系。在這里例子里面選取了300個(gè)特征,那么我們就可以將一個(gè)詞表示為300維的一個(gè)向量,那么這些向量里面很多維度上都不是0。而且我們也可以看出向量之間再做內(nèi)積就能體現(xiàn)出詞匯的相似度了。然后另外一個(gè)重要的特性就做類比推理,但是這種推理的準(zhǔn)確度在30%到75%區(qū)間范圍內(nèi)。

image.png

到這里了,你會(huì)想,我們?nèi)绾蝸?lái)得到一個(gè)詞嵌入的特征矩陣呢?
(2)學(xué)習(xí)詞嵌入
在介紹學(xué)習(xí)詞嵌入之前,把相關(guān)的符號(hào)在這里標(biāo)注下:
其中10000表示詞匯表次數(shù),300表示嵌入向量里面的特征數(shù)。所以我們有個(gè)詞匯表和嵌入矩陣之后,我們就能得到對(duì)應(yīng)單詞的詞向量了。
下面我們就開始對(duì)詞向量進(jìn)行一個(gè)學(xué)習(xí):
學(xué)習(xí)嵌入矩陣E的一個(gè)好方法就是2003年Bengio等人提出的神經(jīng)語(yǔ)言模型 ,關(guān)于語(yǔ)言模型的介紹可以參考我的前一篇博客。
這里我們以一句話為例,來(lái)說(shuō)明使用語(yǔ)言模型來(lái)學(xué)習(xí)詞嵌入。這句話:I want a glass of orange juice。
上下文(context):把預(yù)測(cè)詞前面的幾個(gè)詞作文上下文,這個(gè)例子中為a glass of orange
目標(biāo)詞(target):把要預(yù)測(cè)的單詞作為目標(biāo)詞,這個(gè)例子中的目標(biāo)詞就是juice
注意:這里是為了學(xué)習(xí)詞嵌入,不是為了構(gòu)建一個(gè)語(yǔ)言模型。
image.png

那么現(xiàn)在我們就有訓(xùn)練集樣本了:(context(w),w)content(w):維度((n-1)m,1),n-1指的是窗口里面的單詞數(shù),也就是例子中的4,m指的是詞向量的維度,例子中為300。那么例子中顯示的是(1200,1)。
w:要預(yù)測(cè)的下一個(gè)詞,例子中為juice,然后它的維度是(D, 1),D指的就是詞匯表的大小,也就是例子中所示的10000。
在softmax層,會(huì)計(jì)算10000個(gè)條件概率。然后可以通過(guò)反向傳播的方式,經(jīng)過(guò)梯度下降法,得到我們想獲得的嵌入矩陣E。
與n-gram模型相比,好處在于:
1、可以進(jìn)行詞語(yǔ)之間的相似度計(jì)算了,而且還能夠做類比。
2、不需要再考慮平滑操作了,因?yàn)閜(w|context)在0到1之間。

二、Word2Vec

看完了前面的神經(jīng)語(yǔ)言模型之后,我們看轉(zhuǎn)入了Word2Vec的兩個(gè)重要的模型CBOW(Continues bags of words)和Skip-gram模型。這兩個(gè)模型的示意圖如下:
CBOW和Skip gram

這里可以明顯看出下面的的預(yù)測(cè)的方法:

Model 如何預(yù)測(cè) 使用語(yǔ)料的規(guī)模
CBOW 使用上下文去預(yù)測(cè)目標(biāo)詞來(lái)訓(xùn)練得到詞向量 小型語(yǔ)料庫(kù)比較適合
Skip-gram 使用目標(biāo)詞去預(yù)測(cè)周圍詞來(lái)訓(xùn)練得到詞向量 在大型的語(yǔ)料上面表現(xiàn)得比較好

CBOW是非常常見的,但是不是非常常用的,最常用的還是Skip gram。所以本文就是針對(duì) Skip gram來(lái)進(jìn)行說(shuō)明了。

1、Skip-Gram模型

它只是一種學(xué)習(xí)方法而已。舉個(gè)例子:
I want a glass of orange juice。
思路就是我們有了glass之后,想去預(yù)測(cè)周圍的want a 和 of orange。現(xiàn)在我們?cè)趺慈?shù)學(xué)的方式去描述出來(lái)了。這里有一個(gè)window的size了。
Skip-Gram的目標(biāo)函數(shù)如下:
l(\theta) = arg \max_\theta \prod_{w\in Text} \prod_{C\in Context(w)} P(c|w;\theta)

取對(duì)數(shù)之后的形式就
L(\theta) = arg \max_\theta \sum_{w\in Text} \sum_{C\in Context(w)} logP(c|w;\theta) (w,c)在上下問(wèn)出現(xiàn),說(shuō)明它們的相似度很高,然后我們就需要ogP(c|w;\theta)是越大越好的,那么后面就用到的softmax的方式來(lái)得到一個(gè)概率。

這里注意我們的參數(shù)theta是兩次詞向量的矩陣
\theta = [u, v]
其中u代表了單詞作為上下文的詞向量,v代表了單詞作為中心詞的詞向量。這個(gè)在word2vec的源代碼中也是看得到的。
通過(guò)softwmax處理之后,我們就能得到
P(c|w;\theta) = \frac {e^{u_{c}*v_{w}}}{\sum_{c^{\prime} \in corpus} e^{u_{c^{\prime}}*v_{w}}} 注意這里的上下文就是語(yǔ)料庫(kù)中的了。將改公式帶入到我們的目標(biāo)函數(shù)中去,就可以得到:
\begin{eqnarray} L(\theta) &=& arg \max_\theta \sum_{w\in Text} \sum_{C\in Context(w)} logP(c|w;\theta)\\ & =& arg \max_\theta \sum_{w\in Text} \sum_{C\in Context(w)} log \frac {e^{u_{c}*v_{w}}}{\sum_{c^{\prime} \in corpus} e^{u_{c^{\prime}}*v_{w}}} \\ &=& arg \max_\theta \sum_{w\in Text} \sum_{C\in Context(w)}[u_{c}*v_{w}-log\sum_{c^{\prime} \in corpus}e^{u_{c^{\prime}}*v_{w}}] \end{eqnarray} 到這里來(lái)了之后,我們就得到了Skip-Gram模型的目標(biāo)函數(shù),但是這里有計(jì)算上的問(wèn)題,就是我們這里上下文取的是詞庫(kù),那么計(jì)算的時(shí)間復(fù)雜度很高。解決上面的問(wèn)題,目前使用了兩種手段:一個(gè)是負(fù)采樣,另外一個(gè)是層次化的softmax。

2、Skip-Gram與負(fù)采樣

先說(shuō)明一下負(fù)采樣之后的目標(biāo)函數(shù)有些變化,但是本質(zhì)上面還是一個(gè)道題。
這里就采用通俗易懂的方式來(lái)進(jìn)行說(shuō)明,假設(shè)我們的text如下
text = w_{1}w_{2}w_{3}w_{4}w_{5}

這里用到我們?cè)谶壿嫽貧w里面的思想
l(\theta) = arg \max_\theta \prod_{(c,w)\in D}P(D=1|c,w; \theta) \prod_{(c,w)\in \tilde{D}}P(D=0|c,w; \theta)

\begin{eqnarray} L(\theta) &=& arg \max_\theta[ \sum_{(c,w)\in D}P(D=1|c,w; \theta) +\sum_{(c,w)\in \tilde{D}}P(D=0|c,w; \theta)]\\ &=& arg \max_\theta[\sum_{(c,w)\in D} log\sigma(u_{c}\cdot v_{w}) +\sum_{(c,w)\in \tilde{D}}log\sigma(-u_{c}\cdot v_{w})] \end{eqnarray} 到目前為止的話,可能出現(xiàn)的問(wèn)題就是正樣本的數(shù)量非常少,然后負(fù)樣本的數(shù)量非常多,這個(gè)就是樣本數(shù)量極度不均衡的狀態(tài),所以我們需要從負(fù)樣本里面抽選一部分出來(lái),這樣的話,我們計(jì)算的時(shí)候就更快。
下面就是對(duì)負(fù)采樣的一個(gè)說(shuō)明:
I want a glass of orange juice
由上面的text,我們就知道了Vocab = {I, want, a, glass, of, orange, juice} 總共7個(gè)單詞,然后按照窗口是1的情況,進(jìn)行一個(gè)負(fù)采樣:

正樣本 負(fù)樣本
(glass, a) (glass, I), (glass, juice)
(glass, of) (glass, want), (glass, I)
(of, glass) (of, I), (of, juice)
(of, glass) (of, want), (of, glass)

這里就是一個(gè)負(fù)采樣的過(guò)程了,具體的負(fù)采樣的個(gè)數(shù)是一個(gè)超參數(shù)了,那么到了這里,我們就得到我們負(fù)采樣過(guò)程中的目標(biāo)函數(shù):
L(\theta) = arg \max_\theta[\sum_{(c,w)\in D} log\sigma(u_{c}\cdot v_{w}) +\sum_{c^{\prime }\in N(w)}. log\sigma(-u_{c^{\prime}}\cdot v_{w})
下面我們對(duì)各個(gè)未知數(shù)求一個(gè)偏導(dǎo):
\begin{eqnarray} \frac{\partial L(\theta)}{\partial u_{c}} &=& [1-\sigma(u_{c}\cdot v_{w})]\cdot v_{w}\\ \frac{\partial L(\theta)}{\partial u_{c^{\prime}}} &=& [\sigma(-u_{c^{\prime}}\cdot v_{w})-1]\cdot v_{w}\\ \frac{\partial L(\theta)}{\partial v_{w}} &=& [1-\sigma(u_{c}\cdot v_{w})]\cdot u_{c}+ \sum_{c^{\prime \in N(w)}}[\sigma(-u_{c^{\prime}}\cdot v_{w})-1]\cdot u_{c^{\prime}} \\ \end{eqnarray}
得到偏導(dǎo)之后,我們就能夠采用梯度下降法去更新我們的參數(shù):
u_{c} := u_{c} - \alpha \cdot \frac{\partial L(\theta)}{\partial u_{c}}

u_{c^{\prime}} := u_{c^{\prime}} - \alpha \cdot \frac{\partial L(\theta)}{\partial u_{c}^{\prime}}

v_{w} := v_{w} - \alpha \cdot \frac{\partial L(\theta)}{\partial v_{w}}

3、負(fù)采樣算法流程
for each (w, c) in 正樣本集合:
    負(fù)采樣得到集合N(w):中心詞是w,負(fù)采樣。超參數(shù)為負(fù)樣本個(gè)數(shù)
    進(jìn)行梯度計(jì)算
    更新參數(shù)

在for循環(huán)里面,我們需要去進(jìn)行負(fù)采樣的操作。這里負(fù)采樣的個(gè)數(shù)就是一個(gè)訓(xùn)練時(shí)候的超參數(shù)了。一般選擇是5或者是10。另外為了進(jìn)行加速的處理,我們?cè)创a里面是用到了哈夫曼樹的方式去進(jìn)行一個(gè)提速的采樣。

三、詞向量的評(píng)估方式

訓(xùn)練得到詞向量之后,我們可以采用三種方法去進(jìn)行詞向量的好壞的評(píng)估:
1、可視化的方式評(píng)估:我們將我們學(xué)習(xí)到的100/200/300維的詞向量通過(guò)降維算法TSNE降到2為空間里面。然后通過(guò)可視化的方式看出詞向量的好壞。


T-SNE

2、計(jì)算詞向量的相似度或者相關(guān)性去評(píng)估。這種評(píng)估的方式就需要用到人工去標(biāo)記相似度。
3、通過(guò)類比來(lái)評(píng)估。

analogy

四、Word2Vec操作和改進(jìn)

我們可以從https://code.google.com/archive/p/word2vec/source/default/source
下載下來(lái)word2vec的C++源碼。

make word2vec

通過(guò)make進(jìn)行編譯得到了word2vec的二進(jìn)制文件。

./word2vec

運(yùn)行一下,我們就能夠看到里面提醒的一些參數(shù)了。

?  trunk  ./word2vec
WORD VECTOR estimation toolkit v 0.1c

Options:
Parameters for training:
    -train <file>
        Use text data from <file> to train the model
    -output <file>
        Use <file> to save the resulting word vectors / word clusters
    -size <int>
        Set size of word vectors; default is 100
    -window <int>
        Set max skip length between words; default is 5
    -sample <float>
        Set threshold for occurrence of words. Those that appear with higher frequency in the training data
        will be randomly down-sampled; default is 1e-3, useful range is (0, 1e-5)
    -hs <int>
        Use Hierarchical Softmax; default is 0 (not used)
    -negative <int>
        Number of negative examples; default is 5, common values are 3 - 10 (0 = not used)
    -threads <int>
        Use <int> threads (default 12)
    -iter <int>
        Run more training iterations (default 5)
    -min-count <int>
        This will discard words that appear less than <int> times; default is 5
    -alpha <float>
        Set the starting learning rate; default is 0.025 for skip-gram and 0.05 for CBOW
    -classes <int>
        Output word classes rather than word vectors; default number of classes is 0 (vectors are written)
    -debug <int>
        Set the debug mode (default = 2 = more info during training)
    -binary <int>
        Save the resulting vectors in binary moded; default is 0 (off)
    -save-vocab <file>
        The vocabulary will be saved to <file>
    -read-vocab <file>
        The vocabulary will be read from <file>, not constructed from the training data
    -cbow <int>
        Use the continuous bag of words model; default is 1 (use 0 for skip-gram model)

Examples:
./word2vec -train data.txt -output vec.txt -size 200 -window 5 -sample 1e-4 -negative 5 -hs 0 -binary 0 -cbow 1 -iter 3

word2vec的源碼有很多種,這里可以去看看C++版本的word2vec。地址就是https://github.com/dav/word2vec
雖然word2vec思想非常的牛逼,但是也存在了很多的缺點(diǎn)和問(wèn)題:
1、學(xué)習(xí)出來(lái)的詞向量是固定的。這就導(dǎo)致了在任何的語(yǔ)境里面它表達(dá)的意思都是固定的了。實(shí)際上我們希望得到的是在不同語(yǔ)境下面得到不同的詞向量。所以后來(lái)就有了ELMo和BERT模型了。
2、窗口的長(zhǎng)度是有限的。解決的方式就通過(guò)language model了。
3、無(wú)法有效的學(xué)習(xí)低頻詞匯和未登陸詞。解決的方法就是subword embedding了。
4、預(yù)測(cè)不具備uncertainty。因?yàn)槲覀兊脑~向量都是固定住了的。但是不同語(yǔ)境下面的詞語(yǔ)的意義不同。解決的方式就是采用高斯embedding了。
5、可解釋性不夠。這個(gè)就是深度學(xué)習(xí)的一個(gè)通病了。

參考資料:
1、Deeplearningai主頁(yè)
2、網(wǎng)易云課堂-Deeplearningai
3、Yoshua Bengio, etc, A Neural Probabilistic Language Model(2003)
4、https://github.com/dav/word2vec
5、

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容