[深度學習NPL]word2vector總結與理解

1. 目前成熟的Word2Vector

1.1. English Pre-trained word embeddings

  1. Google’s word2vec embedding:
    外網地址: [ Word2Vec] [ DownloadLink]
    300維英語詞向量: [ 百度雲]

  2. Glove word vectors:
    外網地址: [Glove]
    國內地址: [百度雲]

  3. Facebook’s fastText embeddings:
    外網地址:[FastText]
    國內地址:[百度雲]

  4. FastText Crawl:
    https://pan.baidu.com/s/1NPlqAOnX1k88VictTshVMQ
    [DeepMoji]: To understand how language is used to express emotions

1.2 Chinese Pre-trained word embeddings

目前最全的
https://github.com/Embedding/Chinese-Word-Vectors
https://github.com/to-shimo/chinese-word2vec

2. one_hot編碼

首先,瞭解下什麼是one_hot編碼,直接舉例子如下:
詞庫

我   從   哪   裏   來   要   到   何   處  去
0    1    2    3   4    5   6    7    8   9

__one_hot編碼__如下:

# 我從哪裏來,要到何處去
[
[1 0 0 0 0 0 0 0 0 0]
[0 1 0 0 0 0 0 0 0 0]
[0 0 1 0 0 0 0 0 0 0]
[0 0 0 1 0 0 0 0 0 0]
[0 0 0 0 1 0 0 0 0 0]
[0 0 0 0 0 1 0 0 0 0]
[0 0 0 0 0 0 1 0 0 0]
[0 0 0 0 0 0 0 1 0 0]
[0 0 0 0 0 0 0 0 1 0]
[0 0 0 0 0 0 0 0 0 1]
]
 
# 我從何處來,要到哪裏去
[
[1 0 0 0 0 0 0 0 0 0]
[0 1 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 1 0 0]
[0 0 0 0 0 0 0 0 1 0]
[0 0 0 0 1 0 0 0 0 0]
[0 0 0 0 0 1 0 0 0 0]
[0 0 0 0 0 0 1 0 0 0]
[0 0 1 0 0 0 0 0 0 0]
[0 0 0 1 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 1]
]

one_hot編碼後,一個句子可以用一個矩陣表示,出現在詞庫中的詞對應在矩陣中位置爲1

2.1. 簡單對比

one_hot編碼之前使用列表(一維)表達一個句子
one_hot編碼之後使用矩陣(二維)表達一個句子

2.2.優勢分析:

  1. 稀疏矩陣做矩陣計算的時候,只需要把1對應位置的數相乘求和就行,
  2. one-hot編碼的優勢就體現出來了,計算方便快捷、表達能力強

2.3. 缺點分析:

  1. 過於稀疏時,過度佔用資源
    比如:中文大大小小簡體繁體常用不常用有十幾萬,然後一篇文章100W字,要表達所有句子,需要100W X 10W的矩陣
  2. 每個向量之間相互正交的(內積爲0)。向量正交意味着無相關性,這也正交意味着詞與詞之間是沒有任何關係的。
  3. 每個詞的向量維度和不同詞的個數有關。比方說,在上面的這個句子裏,有5個不同的詞,所以向量的維度是5。然而往往實際應用中,一篇文章的中不同的詞的個數是很多的。這樣,向量的維度會非常的高

3. 什麼是word2vector?

我們先來看一個問題,假如有一個句子 " the dog bark at the mailman"。
假如用向量來表示每個單詞,我們最先想到的是用one hot 編碼的方式來表達每個單詞,具體來說。
the 可以表示爲 [1,0,0,0,0]
dog 可以表示爲 [0,1,0,0,0]
bark 可以表示爲 [0,0,1,0,0]
at 可以表示爲[0,0,0,1,0]
mailman可以表示爲[0,0,0,0,1]

我們可以看到每個單詞其實就用一個向量來表示。我們發現幾個問題:
第一,每個向量之間相互正交的(內積爲0)。也就是說詞與詞之間是沒有任何關係的。
第二,每個詞的向量維度和不同詞的個數有關。比方說,在上面的這個句子裏,有5個不同的詞,所以向量的維度是5。然而往往現實中,一篇文章的中不同的詞的個數是很多的。這樣,向量的維度會非常的高。
這種對詞的向量表示方法存在着以上的問題,忽略了詞與詞之間的關係(比如說,dog和cat都是動物,並非完全無關係)。維度太高的向量作爲模型輸入會導致模型變的複雜(模型複雜需要更多的訓練樣本才能夠收斂)

那麼是否存在一種更加合理的對詞的用向量的表達方式呢?有的,其實就是word embedding。
word embedding說的簡單一點其實就是將高維稀疏的向量降維成稠密的低維向量。(一種高維到低維的映射)

那麼如和實現word embedding?
w2v其實就是一種高效實現word embedding的工具。
所以,如果用一句話來描述word2vector的話你會怎麼描述?簡單的說,我覺得可以這麼說w2v其實是一種將單詞轉化向量的工具。這一種向量的其實是對單詞更有效的表達

4. word2vector怎麼做

下面總結一下word2vector主要的思想

4.1. Skip-Gram& CBOW

在介紹w2v模型之前,先介紹兩個模型。一個是Skip-Gram和CBOW(Continuous Bag-of-Words)。首先看CBOW,它的做法是,將一個詞所在的上下文中的詞作爲輸入,而那個詞本身作爲輸出。
在這裏插入圖片描述
來看Skip-Gram,它的做法和CBOW相反,將一個詞所在的上下文中的詞作爲輸出,而詞本身作爲輸入。

在這裏插入圖片描述
(下面有例子說明)另外,我們介紹這兩個模型都會涉及到的一個重要參數。

window_size:窗口大小。舉一個例子,還是上面那句話:" the dog bark at the mailman"。假設window_size取1時,利用CBOW模型可以得到:

([the,bark],dog)

([dog,at],bark)

([bark,the],at)

([at,mailman],the)

一共4組數據。同樣的,假設window_size還是1,利用Skip-Gram模型可以得到:

(dog,[the,bark])

(bark,[dog,at])

(at,[bark,the])

(the,[at,mailman])

對於每組數據會稍微做一下處理。比如對於第一組 (dog,[the,bark])一般處理成

(dog,the),(dog,bark)。

類似有:

(bark,dog),(bark,at),(at,bark),(at,the),(the,at),(the,mailman)共8組數據。

下面的圖中給出了一些我們的訓練樣本的例子。我們選定句子“The quick brown fox jumps over lazy dog”,設定我們的窗口大小爲2(window_size=2),也就是說我們僅選輸入詞前後各兩個詞和輸入詞進行組合。下圖中,藍色代表input word,方框內代表位於窗口內的單詞。
在這裏插入圖片描述
我們的模型將會從每對單詞出現的次數中習得統計結果。例如,我們的神經網絡可能會得到更多類似(“Soviet“,”Union“)這樣的訓練樣本對,而對於(”Soviet“,”Sasquatch“)這樣的組合卻看到的很少。因此,當我們的模型完成訓練後,給定一個單詞”Soviet“作爲輸入,輸出的結果中”Union“或者”Russia“要比”Sasquatch“被賦予更高的概率。

4.2. word2vector

下面就可以直接介紹如何進行w2v,上面提到w2v可以看作是一個將高維空間映射到低維空間的過程,用一個單層神經網絡就可以實現這種功能(和自編碼器有點類似其實)。對於CBOW,假如還是上面的句子" the dog bark at the mailman",訓練數據是([the,brak],dog)那麼網絡的輸入輸出如下圖所示:
在這裏插入圖片描述
這裏有幾個細節:

(1).上面介紹CBOW模型的時有一個模型的結構圖,其中的SUM意思其實就是把各個上下文的詞one-hot後的向量相加。比如對於the的向量是[1,0,0,0,0]。bark向量是[0,0,1,0,0],SUM之後就是[1,0,1,0,0]這就是網絡的輸入。輸出就是[0,1,0,0,0],對應-dog

(2).我們所謂的embedding vetcor其實就第二個紅框裏的線,每一根線其實就是一個權值。

(3).第二個框裏的紅線其實就是dog這個單詞的embedding結果(由5維變成3維)

(4).這個單層NN訓練完畢之後有用的部分就是embedding martrix這部分,其大小爲 輸入個數(詞彙表長度)×embedding後的維度。

類似對於Skip-Gram模型有:

在這裏插入圖片描述
當取訓練數據(dog,bark)時,網絡結構如上圖,對比上面的CBOW最大的不同其實就是在於輸入數據。

4.3. 模型細節

我們如何來表示這些單詞呢?首先,我們都知道神經網絡只能接受數值輸入,我們不可能把一個單詞字符串作爲輸入,因此我們得想個辦法來表示這些單詞。最常用的辦法就是基於訓練文檔來構建我們自己的詞彙表(vocabulary)再對單詞進行one-hot編碼。

假設從我們的訓練文檔中抽取出10000個唯一不重複的單詞組成詞彙表。我們對這10000個單詞進行one-hot編碼,得到的每個單詞都是一個10000維的向量,向量每個維度的值只有0或者1,假如單詞ants在詞彙表中的出現位置爲第3個,那麼ants的向量就是一個第三維度取值爲1,其他維都爲0的10000維的向量(ants=[0, 0, 1, 0, …, 0])。

還是上面的例子,“The dog barked at the mailman”,那麼我們基於這個句子,可以構建一個大小爲5的詞彙表(忽略大小寫和標點符號):(“the”, “dog”, “barked”, “at”, “mailman”),我們對這個詞彙表的單詞進行編號0-4。那麼”dog“就可以被表示爲一個5維向量[0, 1, 0, 0, 0]。

模型的輸入如果爲一個10000維的向量,那麼輸出也是一個10000維度(詞彙表的大小)的向量,它包含了10000個概率,每一個概率代表着當前詞是輸入樣本中output word的概率大小。

下圖是我們神經網絡的結構:
在這裏插入圖片描述
隱層沒有使用任何激活函數,但是輸出層使用了sotfmax。

我們基於成對的單詞來對神經網絡進行訓練,訓練樣本是 ( input word, output word ) 這樣的單詞對,input word和output word都是one-hot編碼的向量。最終模型的輸出是一個概率分佈。

4.4. 隱層

說完單詞的編碼和訓練樣本的選取,我們來看下我們的隱層。如果我們現在想用300個特徵來表示一個單詞(即每個詞可以被表示爲300維的向量)。那麼隱層的權重矩陣應該爲10000行,300列(隱層有300個結點)。

Google在最新發布的基於Google news數據集訓練的模型中使用的就是300個特徵的詞向量。詞向量的維度是一個可以調節的超參數(在Python的gensim包中封裝的Word2Vec接口默認的詞向量大小爲100, window_size爲5)。

看下面的圖片,左右兩張圖分別從不同角度代表了輸入層-隱層的權重矩陣。左圖中每一列代表一個10000維的詞向量和隱層單個神經元連接的權重向量。從右邊的圖來看,每一行實際上代表了每個單詞的詞向量。
在這裏插入圖片描述
所以我們最終的目標就是學習這個隱層的權重矩陣。

我們現在回來接着通過模型的定義來訓練我們的這個模型。

上面我們提到,input word和output word都會被我們進行one-hot編碼。仔細想一下,我們的輸入被one-hot編碼以後大多數維度上都是0(實際上僅有一個位置爲1),所以這個向量相當稀疏,那麼會造成什麼結果呢。如果我們將一個1 x 10000的向量和10000 x 300的矩陣相乘,它會消耗相當大的計算資源,爲了高效計算,它僅僅會選擇矩陣中對應的向量中維度值爲1的索引行(這句話很繞),看圖就明白。
在這裏插入圖片描述
我們來看一下上圖中的矩陣運算,左邊分別是1 x 5和5 x 3的矩陣,結果應該是1 x 3的矩陣,按照矩陣乘法的規則,結果的第一行第一列元素爲0 x 17 + 0 x 23 + 0 x 4 + 1 x 10 + 0 x 11 = 10,同理可得其餘兩個元素爲12,19。如果10000個維度的矩陣採用這樣的計算方式是十分低效的。

爲了有效地進行計算,這種稀疏狀態下不會進行矩陣乘法計算,可以看到矩陣的計算的結果實際上是矩陣對應的向量中值爲1的索引,上面的例子中,左邊向量中取值爲1的對應維度爲3(下標從0開始),那麼計算結果就是矩陣的第3行(下標從0開始)—— [10, 12, 19],這樣模型中的隱層權重矩陣便成了一個”查找表“(lookup table),進行矩陣計算時,直接去查輸入向量中取值爲1的維度下對應的那些權重值。隱層的輸出就是每個輸入單詞的“嵌入詞向量”

4.5. 輸出層

經過神經網絡隱層的計算,ants這個詞會從一個1 x 10000的向量變成1 x 300的向量,再被輸入到輸出層。輸出層是一個softmax迴歸分類器,它的每個結點將會輸出一個0-1之間的值(概率),這些所有輸出層神經元結點的概率之和爲1。

下面是一個例子,訓練樣本爲 (input word: “ants”, output word: “car”) 的計算示意圖。
在這裏插入圖片描述

5. 直覺上的理解

下面我們將通過直覺來進行一些思考。

如果兩個不同的單詞有着非常相似的“上下文”(也就是窗口單詞很相似,比如“Kitty climbed the tree”和“Cat climbed the tree”),那麼通過我們的模型訓練,這兩個單詞的嵌入向量將非常相似。

那麼兩個單詞擁有相似的“上下文”到底是什麼含義呢?比如對於同義詞“intelligent”和“smart”,我們覺得這兩個單詞應該擁有相同的“上下文”。而例如”engine“和”transmission“這樣相關的詞語,可能也擁有着相似的上下文

實際上,這種方法實際上也可以幫助你進行詞幹化(stemming),例如,神經網絡對”ant“和”ants”兩個單詞會習得相似的詞向量。

詞幹化(stemming)就是去除詞綴得到詞根的過程。

6. 參考資料

https://www.leiphone.com/news/201706/PamWKpfRFEI42McI.html

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