一文詳解 Word2vec 之 Skip-Gram 模型(訓練篇)

2020-12-14 雷鋒網

雷鋒網按:這是一個關於 Skip-Gram 模型的系列教程,依次分為結構、訓練和實現三個部分,本文為第二部分:訓練篇,最後一部分我們將隨後發布,敬請期待。原文作者天雨粟,原載於作者知乎專欄,雷鋒網已獲授權。

第一部分我們了解skip-gram的輸入層、隱層、輸出層。在第二部分,會繼續深入講如何在skip-gram模型上進行高效的訓練。

在第一部分講解完成後,我們會發現Word2Vec模型是一個超級大的神經網絡(權重矩陣規模非常大)。

舉個慄子,我們擁有10000個單詞的詞彙表,我們如果想嵌入300維的詞向量,那麼我們的輸入-隱層權重矩陣隱層-輸出層的權重矩陣都會有 10000 x 300 = 300萬個權重,在如此龐大的神經網絡中進行梯度下降是相當慢的。更糟糕的是,你需要大量的訓練數據來調整這些權重並且避免過擬合。百萬數量級的權重矩陣和億萬數量級的訓練樣本意味著訓練這個模型將會是個災難(太兇殘了)。

Word2Vec 的作者在它的第二篇論文中強調了這些問題,下面是作者在第二篇論文中的三個創新:

1. 將常見的單詞組合(word pairs)或者詞組作為單個「words」來處理。

2. 對高頻次單詞進行抽樣來減少訓練樣本的個數。

3. 對優化目標採用「negative sampling」方法,這樣每個訓練樣本的訓練只會更新一小部分的模型權重,從而降低計算負擔。

事實證明,對常用詞抽樣並且對優化目標採用「negative sampling」不僅降低了訓練過程中的計算負擔,還提高了訓練的詞向量的質量。

Word pairs and "phases"

論文的作者指出,一些單詞組合(或者詞組)的含義和拆開以後具有完全不同的意義。比如「Boston Globe」是一種報刊的名字,而單獨的「Boston」和「Globe」這樣單個的單詞卻表達不出這樣的含義。因此,在文章中只要出現「Boston Globe」,我們就應該把它作為一個單獨的詞來生成其詞向量,而不是將其拆開。同樣的例子還有「New York」,「United Stated」等。

在Google發布的模型中,它本身的訓練樣本中有來自Google News數據集中的1000億的單詞,但是除了單個單詞以外,單詞組合(或詞組)又有3百萬之多。

如果你對模型的詞彙表感興趣,可以點擊:

http://t.cn/RoVde3h

你還可以直接瀏覽這個詞彙表:

http://t.cn/RoVdsZr

如果想了解這個模型如何進行文檔中的詞組抽取,可以看論文中「Learning Phrases」這一章,對應的代碼在 word2phrase.c ,相關連結如下。

論文連結:

http://t.cn/RMct1c7

代碼連結:

http://t.cn/R5auFLz

對高頻詞抽樣

在第一部分的講解中,我們展示了訓練樣本是如何從原始文檔中生成出來的,這裡我再重複一次。我們的原始文本為「The quick brown fox jumps over the laze dog」,如果我使用大小為2的窗口,那麼我們可以得到圖中展示的那些訓練樣本。

但是對於「the」這種常用高頻單詞,這樣的處理方式會存在下面兩個問題:

  1. 當我們得到成對的單詞訓練樣本時,("fox", "the") 這樣的訓練樣本並不會給我們提供關於「fox」更多的語義信息,因為「the」在每個單詞的上下文中幾乎都會出現。

  2. 由於在文本中「the」這樣的常用詞出現概率很大,因此我們將會有大量的(」the「,...)這樣的訓練樣本,而這些樣本數量遠遠超過了我們學習「the」這個詞向量所需的訓練樣本數。

Word2Vec通過「抽樣」模式來解決這種高頻詞問題。它的基本思想如下:對於我們在訓練原始文本中遇到的每一個單詞,它們都有一定概率被我們從文本中刪掉,而這個被刪除的概率與單詞的頻率有關。
如果我們設置窗口大小(即),並且從我們的文本中刪除所有的「the」,那麼會有下面的結果:

1. 由於我們刪除了文本中所有的「the」,那麼在我們的訓練樣本中,「the」這個詞永遠也不會出現在我們的上下文窗口中。

2. 當「the」作為input word時,我們的訓練樣本數至少會減少10個。

這句話應該這麼理解,假如我們的文本中僅出現了一個「the」,那麼當這個「the」作為input word時,我們設置span=10,此時會得到10個訓練樣本 ("the", ...) ,如果刪掉這個「the」,我們就會減少10個訓練樣本。實際中我們的文本中不止一個「the」,因此當「the」作為input word的時候,至少會減少10個訓練樣本。

上面提到的這兩個影響結果實際上就幫助我們解決了高頻詞帶來的問題。

抽樣率

word2vec的C語言代碼實現了一個計算在詞彙表中保留某個詞概率的公式。

ω是一個單詞,Z(ωi) 是 ωi 這個單詞在所有語料中出現的頻次。舉個慄子,如果單詞「peanut」在10億規模大小的語料中出現了1000次,那麼 Z(peanut) = 1000/1000000000 = 1e - 6

在代碼中還有一個參數叫「sample」,這個參數代表一個閾值,默認值為0.001(在gensim包中的Word2Vec類說明中,這個參數默認為0.001,文檔中對這個參數的解釋為「 threshold for configuring which higher-frequency words are randomly downsampled」)。這個值越小意味著這個單詞被保留下來的概率越小(即有越大的概率被我們刪除)。

P(ωi) 代表著保留某個單詞的概率:

圖中x軸代表著 Z(ωi) ,即單詞 ωi 在語料中出現頻率,y軸代表某個單詞被保留的概率。對於一個龐大的語料來說,單個單詞的出現頻率不會很大,即使是常用詞,也不可能特別大。

從這個圖中,我們可以看到,隨著單詞出現頻率的增高,它被採樣保留的概率越來越小,我們還可以看到一些有趣的結論:

● 當 Z(ωi) <= 0.0026 時,P(ωi) = 1.0 。當單詞在語料中出現的頻率小於 0.0026 時,它是 100% 被保留的,這意味著只有那些在語料中出現頻率超過 0.26% 的單詞才會被採樣。

● 當時 Z(ωi) = 0.00746 時,P(ωi) = 0.5,意味著這一部分的單詞有 50% 的概率被保留。

● 當 Z(ωi) = 1.0 時,P(ωi) = 0.033,意味著這部分單詞以 3.3% 的概率被保留。

如果你去看那篇論文的話,你會發現作者在論文中對函數公式的定義和在C語言代碼的實現上有一些差別,但我認為C語言代碼的公式實現是更權威的一個版本。

負採樣(negative sampling)

訓練一個神經網絡意味著要輸入訓練樣本並且不斷調整神經元的權重,從而不斷提高對目標的準確預測。每當神經網絡經過一個訓練樣本的訓練,它的權重就會進行一次調整。

正如我們上面所討論的,vocabulary的大小決定了我們的Skip-Gram神經網絡將會擁有大規模的權重矩陣,所有的這些權重需要通過我們數以億計的訓練樣本來進行調整,這是非常消耗計算資源的,並且實際中訓練起來會非常慢。

負採樣(negative sampling)解決了這個問題,它是用來提高訓練速度並且改善所得到詞向量的質量的一種方法。不同於原本每個訓練樣本更新所有的權重,負採樣每次讓一個訓練樣本僅僅更新一小部分的權重,這樣就會降低梯度下降過程中的計算量。

當我們用訓練樣本 ( input word: "fox",output word: "quick") 來訓練我們的神經網絡時,「 fox」和「quick」都是經過one-hot編碼的。如果我們的vocabulary大小為10000時,在輸出層,我們期望對應「quick」單詞的那個神經元結點輸出1,其餘9999個都應該輸出0。在這裡,這9999個我們期望輸出為0的神經元結點所對應的單詞我們稱為「negative」 word。

當使用負採樣時,我們將隨機選擇一小部分的negative words(比如選5個negative words)來更新對應的權重。我們也會對我們的「positive」 word進行權重更新(在我們上面的例子中,這個單詞指的是」quick「)。

在論文中,作者指出指出對於小規模數據集,選擇5-20個negative words會比較好,對於大規模數據集可以僅選擇2-5個negative words。

回憶一下我們的隱層-輸出層擁有300 x 10000的權重矩陣。如果使用了負採樣的方法我們僅僅去更新我們的positive word-「quick」的和我們選擇的其他5個negative words的結點對應的權重,共計6個輸出神經元,相當於每次只更新 300 x 6 = 1800 個權重。對於3百萬的權重來說,相當於只計算了0.06%的權重,這樣計算效率就大幅度提高。

如何選擇negative words

我們使用「一元模型分布(unigram distribution)」來選擇「negative words」。

要注意的一點是,一個單詞被選作negative sample的概率跟它出現的頻次有關,出現頻次越高的單詞越容易被選作negative words。

在word2vec的C語言實現中,你可以看到對於這個概率的實現公式。每個單詞被選為「negative words」的概率計算公式與其出現的頻次有關。

代碼中的公式實現如下:

每個單詞被賦予一個權重,即 f(ωi), 它代表著單詞出現的頻次。

公式中開3/4的根號完全是基於經驗的,論文中提到這個公式的效果要比其它公式更加出色。你可以在google的搜索欄中輸入「plot y = x^(3/4) and y = x」,然後看到這兩幅圖(如下圖),仔細觀察x在[0,1]區間內時y的取值,x^(3/4) 有一小段弧形,取值在 y = x 函數之上。

負採樣的C語言實現非常的有趣。unigram table有一個包含了一億個元素的數組,這個數組是由詞彙表中每個單詞的索引號填充的,並且這個數組中有重複,也就是說有些單詞會出現多次。那麼每個單詞的索引在這個數組中出現的次數該如何決定呢,有公式,也就是說計算出的負採樣概率*1億=單詞在表中出現的次數

有了這張表以後,每次去我們進行負採樣時,只需要在0-1億範圍內生成一個隨機數,然後選擇表中索引號為這個隨機數的那個單詞作為我們的negative word即可。一個單詞的負採樣概率越大,那麼它在這個表中出現的次數就越多,它被選中的概率就越大。

到目前為止,Word2Vec中的Skip-Gram模型就講完了,對於裡面具體的數學公式推導細節這裡並沒有深入。這篇文章只是對於實現細節上的一些思想進行了闡述。

其他資料

如果想了解更多的實現細節,可以去查看C語言的實現源碼:

http://t.cn/R6w6Vi7

其他Word2Vec教程請參考:

http://t.cn/R6w6ViZ

下一部分將會介紹如何用 TensorFlow 實現一個 Word2Vec 中的 Skip-Gram 模型。

雷鋒網(公眾號:雷鋒網)相關閱讀:

一文詳解 Word2vec 之 Skip-Gram 模型(結構篇)

一文詳解 Word2vec 之 Skip-Gram 模型(實現篇)

25 行 Python 代碼實現人臉檢測——OpenCV 技術教程

雷鋒網版權文章,未經授權禁止轉載。詳情見轉載須知。

相關焦點

  • 一文詳解 Word2vec 之 Skip-Gram 模型(結構篇)
    這次的分享主要是對Word2Vec模型的兩篇英文文檔的翻譯、理解和整合,這兩篇英文文檔都是介紹Word2Vec中的Skip-Gram模型。下一篇專欄文章將會用TensorFlow實現基礎版Word2Vec的skip-gram模型,所以本篇文章先做一個理論鋪墊。
  • 理解 Word2Vec 之 Skip-Gram 模型【全】
    這次的分享主要是對Word2Vec模型的兩篇英文文檔的翻譯、理解和整合,這兩篇英文文檔都是介紹Word2Vec中的Skip-Gram模型。下一篇專欄文章將會用TensorFlow實現基礎版Word2Vec的skip-gram模型,所以本篇文章先做一個理論鋪墊。
  • Word Embedding Papers | 經典再讀之Word2Vec
    介紹分為三個部分,分別對應 Tomas Mikolov(託老師)2013 年經典的託三篇:1. word2vec(一):NLP 蛋糕的一大塊兒:圍繞 Efficient Estimation of Word Representations in Vector Space。會談到:word2vec 與自監督學習;CBOW 與 Skip-gram 的真正區別是什麼。
  • word2vec模型深度解析
    【前言】word2vec是一個被廣泛應用的word embedding方法,由於最近研究需要,將算法模型研究了一下由於word2vec內容很多,這裡儘量講解核心內容,有不足之處還請指出!word2vec是輕量級的神經網絡,其模型僅僅包括輸入層、隱藏層和輸出層,模型框架根據輸入輸出的不同,主要包括CBOW和skip-gram模型,CBOW模型是通過上下文的內容預測中間的目標詞,而skip-gram則相反,通過目標詞預測其上下文的詞,通過最大化詞出現的概率,我們訓練模型可得到各個層之間的權重矩陣,我們所說的得到的word embedding vector就是從這個權重矩陣裡面得來的。
  • 深入理解word2vec
    word2vec是一種基於神經網絡的語言模型,也是一種詞彙表徵方法。word2vec包括兩種結構:skip-gram(跳字模型)和CBOW(連續詞袋模型),但本質上都是一種詞彙降維的操作。  我們將NLP的語言模型看作是一個監督學習問題:即給定上下文詞,輸出中間詞,或者給定中間詞,輸出上下文詞。基於輸入和輸出之間的映射便是語言模型。
  • 【算法】word2vec與doc2vec模型
    2 word2vec與doc2vec有什麼差異?3 如何做word2vec和doc2vec?深度學習掀開了機器學習的新篇章,目前深度學習應用於圖像和語音已經產生了突破性的研究進展。目前訓練LDA模型的方法有原始論文中的基於EM和 差分貝葉斯方法以及後來出現的Gibbs Samplings 採樣算法。  d)  Word2Vector 模型  最近幾年剛剛火起來的算法,通過神經網絡機器學習算法來訓練N-gram 語言模型,並在訓練過程中求出word所對應的vector的方法。本文將詳細闡述此方法的原理。
  • 深度學習筆記 | 第13講:word2vec詞向量
    word2vec 是谷歌於 2013 年提出的一種 NLP 工具,其特點就是將詞彙進行向量化,這樣我們就可以定量的分析和挖掘詞彙之間的聯繫。因而 word2vec 也是我們上一講講到的詞嵌入表徵的一種,只不過這種向量化表徵需要經過神經網絡訓練得到。
  • 文本深度表示模型—word2vec&doc2vec詞向量模型
    Word2Vector 模型最近幾年剛剛火起來的算法,通過神經網絡機器學習算法來訓練N-gram 語言模型,並在訓練過程中求出word所對應的vector的方法。本文將詳細闡述此方法的原理。4.word2vec算法思想什麼是word2vec?
  • 文本深度表示模型——word2vec&doc2vec詞向量模型
    目前訓練LDA模型的方法有原始論文中的基於EM和 差分貝葉斯方法以及後來出現的Gibbs Samplings 採樣算法。  d)  Word2Vector 模型  最近幾年剛剛火起來的算法,通過神經網絡機器學習算法來訓練N-gram 語言模型,並在訓練過程中求出word所對應的vector的方法。本文將詳細闡述此方法的原理。
  • 詞嵌入的經典方法,六篇論文遍歷Word2vec的另類應用
    在開始正題之前,為了防止有人不清楚 word2vec 從而影響對後文的理解,這裡科普一下本文會用到的相關基本概念。圖源:https://towardsdatascience.com/introduction-to-word-embedding-and-word2vec-652d0c2060fa基本模型:訓練 word2vec 的常用方法有 CBOW 和 skip-gram。如圖三所示,w(t)表示當前單詞,w(t-?)
  • 手把手教你NumPy來實現Word2vec
    根據Mikolov(引用於這篇文章),以下是Skip-gram和CBOW之間的區別:Skip-gram:能夠很好地處理少量的訓練數據,而且能夠很好地表示不常見的單詞或短語CBOW:比skip-gram訓練快幾倍,對出現頻率高的單詞的準確度稍微更好一些
  • word2vec——高效word特徵求取
    繼上次分享了經典統計語言模型,最近公眾號中有很多做NLP朋友問到了關於word2vec的相關內容, 本文就在這裡整理一下做以分享。本文分為幾部分,暫時沒有加實驗章節,但其實感覺word2vec一文中實驗還是做了很多工作的,希望大家有空最好還是看一下~概括word2vec要解決的問題: 在神經網絡中學習將word映射成連續(高維)向量, 其實就是個詞語特徵求取。特點: 1. 不同於之前的計算cooccurrence次數方法,減少計算量 2.
  • 自然語言處理—詳解Skip-Gram
    ,數據降維,同時可以很方便計算同義詞(各個word之間的距離),底層實現是2-gram(詞頻)+神經網絡。首先選句子中間的一個詞作為輸入詞,比如「dog」作為input word有了input word,再定義一個叫做skip_window的參數,它代表著從當前input word的一側選取詞的量。如果設置skip_window=2,最終獲得窗口中的詞就是["The","dog","barked","at"]。skip_window意味著選取左右各2個詞加入窗口。
  • Word2vec在風控中的應用
    詞本身是一種符號,不可量化不可用數值描述,需要把詞映射成到數值向量空間(詞嵌入embedding),word2vec就是其中一種。NLP中,語言模型(CBOW上下文做輸入預測某個詞本身、Skip-gram用某個詞預測可能的上下文)的目的就是判斷上下文詞之間的相對位置是否接近真實情況,word2vec正式語言模型的產物,不要求語言模型最終效果逼近真實情況而是關心模型訓練完成後得到的神經網絡權重,這些權重就可以作為某個輸入詞的向量化表示。
  • 白話Word2Vec
    t=http://superjom.duapp.com/neural-language-model/word2vec-implement.htmlword2vec 代碼實現(2) – CBOWhttps://link.jianshu.com/?
  • 【Word2Vec】深入淺出Word2Vec原理解析
    常見的方法有n-gram模型、決策樹、最大熵模型、最大熵馬爾可夫模型、條件隨機場、神經網絡等方法。本文只討論n-gram模型和神經網絡兩種方法。事實上, 大部分情況下,詞向量和語言模型都是捆綁在一起的,訓練完成後兩者同時得到。在用神經網絡訓練語言模型方面,最經典的論文就是Bengio於2003年發表的《A Neural Probabilistic Language Model》 ,其後有一系列相關的研究工作,其中也包括谷歌Tomas Mikolov團隊的Word2Vec。3.
  • [NLP] 秒懂詞向量Word2vec的本質
    Word2vec參考資料總結(以下都是我踩過的坑,建議先跳過本節,閱讀正文部分,讀完全文回頭再來看)先大概說下我深挖 word2vec 的過程:先是按照慣例,看了 Mikolov 關於 Word2vec 的兩篇原始論文,然而發現看完依然是一頭霧水,似懂非懂,主要原因是這兩篇文章省略了太多理論背景和推導細節;然後翻出 Bengio 03年那篇JMLR
  • 圖解word2vec
    word2vec一直是一種有效的詞嵌入的方法,本文把word2vec用圖解的方式進行,全篇沒有數學公式,非常通俗易懂,推薦初學者閱讀。原文連結:https://jalammar.github.io/illustrated-word2vec/這篇文章的代碼傳到了本站的github:https://github.com/fengdu78/machine_learning_beginner/tree/master/word2vec正文開始
  • [教程]一篇最簡單的NLP入門:在Python上構建Word2Vec詞嵌入模型(Tensorflow篇)
    在本例中,大部分代碼都是以這裡的 TensorFlow Word2Vec 教程(https://github.com/tensorflow/tensorflow/blob/r1.2/tensorflow/examples/tutorials/word2vec/word2vec_basic.py)為參考講解以這篇文章
  • [開源推薦]Google開源基於Deep Learning的word2vec工具
    word2vec為計算向量詞提供了一種有效的連續詞袋(bag-of-words)和skip-gram架構實現,word2vec遵循Apache License 2.0開源協議。如何轉換?word2vec主要是將文本語料庫轉換成詞向量。