從今天起,我們一起來學(xué)習(xí)詞向量word2vector(簡稱w2v)相關(guān)的知識。雖然,對于NLP來說,w2v技術(shù)和操作已經(jīng)爛大街了,隨便一個NLP任務(wù),底層基本都要搞一個w2v,但是到底為什么需要w2v,它背后的思想是什么,是怎么訓(xùn)練得到的,也許很多經(jīng)常使用w2v的人都不一定很清楚。不清楚,就會導(dǎo)致我們知道w2v很好用很神奇,但是出了問題卻不知道從哪里去改善。
所以,我會邊學(xué)習(xí)斯坦福cs224n的NLP課程的詞向量內(nèi)容,邊查閱其他的資料,并結(jié)合自己的實踐經(jīng)驗來寫下關(guān)于w2v的一系列筆記。
本文介紹兩個方面:
- 為什么我們需要w2v——WHY
- 得到w2v的大致思路是怎樣的——HOW
一、WHY
詞,是NLP要對付的一個基本語言單位,我們在用計算機處理海量文本的時候,希望盡可能地讓機器明白詞蘊含的信息,這樣可以大大地提高文本分類、文本聚類、文本生成、對話、翻譯等等任務(wù)的準(zhǔn)確性。所以,我們需要解決一個基本問題:
如何表示一個詞?
1.WordNet
在英文中,我們可以借助WordNet,來導(dǎo)出一個詞的同義詞、近義詞等等各種信息。
WordNet是由Princeton 大學(xué)的心理學(xué)家,語言學(xué)家和計算機工程師聯(lián)合設(shè)計的一種基于認知語言學(xué)的英語詞典。
網(wǎng)址:https://wordnet.princeton.edu/

我們可以下載wordnet,也可以通過NLTK等等包來獲取,便可以在計算機程序里查詢我們想要的詞。
對于中文的話,也有類似的對應(yīng)的wordnet。下面展示的這個Chinese wordnet由臺灣國立大學(xué)的學(xué)者們設(shè)計搭建。而且,他們還做了相應(yīng)的知識圖譜,更加直觀地表達詞之間的關(guān)系。不過都是繁體中文。
網(wǎng)址:http://lope.linguistics.ntu.edu.tw/cwn/

這些資源都十分地優(yōu)秀,而且都是花費研究機構(gòu)多年的心血才搭建手工而成,所以質(zhì)量也很高,在很多情況下可以滿足我們的需求。
但是通過wordnet來進行詞義表示有什么問題呢?
- 難以更新,畢竟這個靠人力搭建,無法應(yīng)對新詞或者詞的新含義
- 難以定量地計算不同詞之間的相似度
所以,wordnet更多地是作為一個“詞典”,提供一個詞意思的參考或者補充,而往往無法應(yīng)對現(xiàn)在NLP的許多任務(wù)。
所以我們需要其他的表示方法。
2.One-hot表示
假設(shè)我們要研究的一個問題,涉及到的語料共有10000個不同的詞。比如把它們按照首字母排序:
[阿,愛,······,明天,······,你,······,智能,職業(yè)]
那么每個詞可以表示成一個10000維的向量。比如:
“阿”可以表示為這樣的向量:
[1,0,0,0,......,0]
“愛”可以表示為:
[0,1,0,0,......,0]
最后一個詞“職業(yè)”可以表示為:
[0,0,0,0,......,1]
因為每個詞對應(yīng)的向量只有一個位置為1,故稱為“獨熱編碼(one-hot)”。
說白了,這種向量表示的就是這個詞在我們語料庫中的一個index。
這種方法是很流行的,在很多機器學(xué)習(xí)應(yīng)用中,都是對詞語進行這樣的處理的。
但是這樣做一個最大的問題就在于:任何兩個不同的詞的向量,都是“正交”的,內(nèi)積為0.
這樣的話,即使是意思十分相似的詞,也無法從one-hot詞向量中看出它們的聯(lián)系。因此,這種表示方法,我們無法衡量兩個詞的相似度。而相似度無法計算,很多NLP任務(wù)就無法進行。
3.Word2Vector詞向量模型
上面的one-hot表示,其實也是一種“詞向量”,只不過這個詞向量,就是由該詞的index決定的,而僅由index決定,就導(dǎo)致了無法表示詞義的問題。
因此,我們想,為何不讓詞向量表示的信息更加豐富一點呢?
比如,我們可以定義一些維度,然后對一個詞在每個維度上打分,這樣一個詞的意思不就豐富啦?
比如,我們定義“男”,“女”,“水果”,“產(chǎn)品”,“地址”,這幾個維度,對項目幾個詞來定義詞向量:
| Dimension | 國王 | 皇后 | 蘋果 | 酒店 |
|---|---|---|---|---|
| 男 | 0.98 | 0.02 | 0.15 | 0.3 |
| 女 | 0 | 0.99 | 0.27 | 0.2 |
| 水果 | 0.03 | 0.07 | 0.97 | 0 |
| 產(chǎn)品 | 0.11 | 0.12 | 0.89 | 0.23 |
| 地址 | 0.07 | 0.28 | 0.04 | 0.99 |
| ... | ... | ... | ... | ... |
上面只是我隨便編的幾個維度,只是舉個例子,我們可以讓一個詞在多個維度上表示,這個維度上的數(shù)越大,就代表越具有某種屬性。這樣的方法,就可以讓意思相近的詞,擁有相近的屬性值,它們之間的相似度就可以很容易的表示了,比如用余弦相似度來計算向量之間的距離。
這是個很好的思路,這樣就可以很好地表示一個詞在各個維度的含義,可以盡可能地表達一個詞的含義。
但是,如何定義維度呢?
實際上,我們幾乎不可能定義一個完善的維度。這么多的詞匯,維度根本無法定義。而且,這種定義是仁者見仁智者見智,每個人對詞的屬性的定義都是不一樣的。
這個時候,我們就會自然而然地想到“深度學(xué)習(xí)”了。
因為詞的屬性(即我說的維度),相當(dāng)于一個詞的一個“特征”,定義詞的屬性的過程,其實就是“特征工程”,當(dāng)特征工程難以實施的時候,就是深度學(xué)習(xí)大展拳腳的時候了。我們用大量的文本喂給深度學(xué)習(xí)模型,然后自動訓(xùn)練,學(xué)得詞向量。
下面我們來講解,怎么利用深度學(xué)習(xí)的方法,來學(xué)習(xí)詞向量。
二、HOW
我們怎么構(gòu)造一個模型,來“學(xué)習(xí)”詞向量呢?
如果你有機器學(xué)習(xí)或者深度學(xué)習(xí)經(jīng)驗的話,應(yīng)該,知道,最重要的是要明確目標(biāo)函數(shù),也就是我們要調(diào)整模型的參數(shù),讓什么目標(biāo)最大/最小。
針對詞的表示,有語言學(xué)家提出,“一個詞的意思,應(yīng)該由和它一起出現(xiàn)的周圍的詞來表現(xiàn)”。故,一個詞的含義,應(yīng)該由這個詞的各種各樣的上下文來構(gòu)建。
所以我們有兩個思路來構(gòu)造一個模型:
- 輸入上下文的詞,預(yù)測中心詞是什么
- 輸入中心詞,預(yù)測上下文長什么樣
實際上,后面我們會講到,這就是詞向量訓(xùn)練的兩種基本模型,前者為CBOW,后者為Skip-Gram(SG)。我們這里暫時用后者,也就是SG的方式來構(gòu)建。
于是我們構(gòu)建一個神經(jīng)網(wǎng)絡(luò)模型,可以輸入一個句子中的某個詞,輸出其他所有詞出現(xiàn)在這個詞周圍的概率。也就是說,既輸出這個詞附近的上下文的詞,也輸出跟這個詞完全不相干八竿子打不著的詞。
我們希望,這個原本來語料庫中這個中心詞周圍的詞的概率的乘積越大越好,因為這個乘積就是這幾個詞同時出現(xiàn)的概率,用極大似然的思想,我們希望這個概率盡可能大。
而這個網(wǎng)絡(luò)的參數(shù)矩陣,實際上就是輸入文本的特征,也就是我們想要得到的詞向量。
所以,我們通過梯度下降法不斷更新詞向量,就可以使得概率越來越大,最終就得到一組很好的詞向量。
下面,畫個圖來示意、講解:

假設(shè)我們從我們的語料庫里面隨便挑出一句話。我們想預(yù)測如果中心詞是natural的話,那么什么詞應(yīng)該出現(xiàn)在它的周圍呢?或者說,其他詞出現(xiàn)在natural周圍的概率為大多呢?概率越大,說明越可能出現(xiàn)在附近。
另外,什么叫“周圍、附近”呢?我們就用window來定義。
所以,我們的神經(jīng)網(wǎng)絡(luò)模型是這樣的:

注意:我們的輸出,是輸出所有的詞的概率,比如我們的語料庫中有10000個不同的詞,那么這里的輸出就有10000個。但是我們更關(guān)心我們附近的詞的概率,也就是圖中所示的“窗口內(nèi)的詞”。
窗口內(nèi)的詞,本來就是一個自然的語言組合,所以他們這些詞在一起出現(xiàn)的概率應(yīng)該高,所以他們的概率乘積就應(yīng)該高。
這就是詞向量怎么得來的基本思路??偨Y(jié)一下就是這張圖:

當(dāng)然,這個示意圖,只是示意了一個詞。實際上,我們要把我們的語料庫中的所有的詞,全部遍歷一次,分別計算“窗口內(nèi)概率的乘積”,然后求和,最后是要使得這個所有概率之和盡可能大。
用cs224n課堂上的例子:
語料庫中的句子:

我們設(shè)當(dāng)前中心詞的位置為t,而語料庫總長度為T。設(shè)窗口大小為m,那么對于中心詞
但是,我們需要遍歷整個語料庫,也就是計算位置t從0到T的所有的詞,所以最終的目標(biāo)函數(shù)應(yīng)該是:
其中,
但是上面是乘積,不打好求,一般我們?nèi)€負對數(shù),轉(zhuǎn)化成最小化某個和函數(shù),然后再取個平均,就方便求解了,所以我們轉(zhuǎn)化成如下的Cost function:
注意,上面的函數(shù)中,都要求
總之,一句話總結(jié)一下求詞向量的基本思路:
找一個巨大的文本形成語料庫,選擇一個窗口大小,遍歷每一個詞,依次把每個詞輸入進神經(jīng)網(wǎng)絡(luò),詞向量作為網(wǎng)絡(luò)的參數(shù),網(wǎng)絡(luò)輸出其他詞的概率。求得所有的詞的對應(yīng)窗口詞的條件概率的乘積,不斷地調(diào)整詞向量參數(shù),使得這個概率的乘積最大化,從而得到最終的詞向量。
此時,腦海里突然蹦出一句話:“夠了吧!”
所以本文就這么戛然而止了。
下一篇文章,會詳細講解有關(guān)詞向量的一些很重要的細節(jié),和一些訓(xùn)練的高級方法。
后記:
其實雖然本文不長,但是來來回回修改了N次,醞釀了好久才寫成。而且,實際上相關(guān)的內(nèi)容我在暑假的時候,就已經(jīng)學(xué)習(xí)過了,最近才下筆,主要是我在思考“為什么這個詞向量要這么設(shè)計,為什么模型要這樣設(shè)計,為什么目標(biāo)函數(shù)是這個”。因為,cs224n課程上面的說法,一直不能說服我,雖然他們講課的時候給人一種“這就是自然而然的啊”的感覺。而之前吳恩達在深度學(xué)習(xí)課程中講的word2vector的方式跟cs224n又很不一樣,這讓我就更矛盾了。所以,我花了大量時間,去協(xié)調(diào)二者的方法,總結(jié)成本文的思路,這才“自我說服”了。
伏筆:
這里想提前埋下一個伏筆,也是我想寫下有關(guān)詞向量系列文章的主要原因之一:
w2v的一個最基本用途就是尋找similar words(相似詞),但是w2v的一個最明顯的局限就是,這個相似,是“分布相似”,而不是語義相似。雖然,語義相似的詞,通常分布也是相似的,但是分布相似的詞,語義可能很不相似!
這個問題到底怎么解釋?為什么訓(xùn)練出來的詞向量就是反映的分布相似度?是什么原因?qū)е碌??這些問題,我們后面再詳細探討!
推薦閱讀:
?歡迎來微信公眾號SimpleAI閱讀本文:**
?想學(xué)深度學(xué)習(xí)?這些筆記你一定喜歡:
從此明白了卷積神經(jīng)網(wǎng)絡(luò)(CNN)
一只蚊子告訴你,什么是正則化(Regularization)
一文上手TensorFlow,并搭建神經(jīng)網(wǎng)絡(luò)實現(xiàn)手寫數(shù)字識別
神經(jīng)網(wǎng)絡(luò)中的優(yōu)化算法
?想了解更多Python有趣的知識?看看這些:
Python的矩陣傳播機制&矩陣運算——消滅for循環(huán)!
全套筆記請至公眾號菜單,戳【原創(chuàng)筆記】