word2vec詞向量加權(quán)的方法有哪些?
一、理論概述 (主要來(lái)源于http://licstar.net/archives/328這篇博客) 1.詞向量是什么 自然語(yǔ)言理解的問(wèn)題要轉(zhuǎn)化為機(jī)器學(xué)習(xí)的問(wèn)題,第一步肯定是要找一種方法把這些符號(hào)數(shù)學(xué)化。 NLP 中最直觀,也是到目前為止最常用的詞表示方法是 One-hot Representation,這種方法把每個(gè)詞表示為一個(gè)很長(zhǎng)的向量。這個(gè)向量的維度是詞表大小,其中絕大多數(shù)元素為 0,只有一個(gè)維度的值為 1,這個(gè)維度就代表了當(dāng)前的詞。 舉個(gè)栗子, “話筒”表示為 [0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 ...] “麥克”表示為 [0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 ...] 每個(gè)詞都是茫茫 0 海中的一個(gè) 1。 這種 One-hot Representation 如果采用稀疏方式存儲(chǔ),會(huì)是非常的簡(jiǎn)潔:也就是給每個(gè)詞分配一個(gè)數(shù)字 ID。比如剛才的例子中,話筒記為 3,麥克記為 8(假設(shè)從 0 開(kāi)始記)。如果要編程實(shí)現(xiàn)的話,用 Hash 表給每個(gè)詞分配一個(gè)編號(hào)就可以了。這么簡(jiǎn)潔的表示方法配合上最大熵、SVM、CRF 等等算法已經(jīng)很好地完成了 NLP 領(lǐng)域的各種主流任務(wù)。 當(dāng)然這種表示方法也存在一個(gè)重要的問(wèn)題就是“詞匯鴻溝”現(xiàn)象:任意兩個(gè)詞之間都是孤立的。光從這兩個(gè)向量中看不出兩個(gè)詞是否有關(guān)系,哪怕是話筒和麥克這樣的同義詞也不能幸免于難。 Deep Learning 中一般用到的詞向量并不是剛才提到的用 One-hot Representation 表示的那種很長(zhǎng)很長(zhǎng)的詞向量,而是用 Distributed Representation(不知道這個(gè)應(yīng)該怎么翻譯,因?yàn)檫€存在一種叫“Distributional Representation”(類(lèi)似,LDA中用topic表示詞語(yǔ)的詞向量的表示方法)表示的一種低維實(shí)數(shù)向量。這種向量一般是這個(gè)樣子:[0.792, ?0.177, ?0.107, 0.109, ?0.542, ...]。維度以 50 維和 100 維比較常見(jiàn)。 2.詞向量的來(lái)歷 Distributed representation 最早是 Hinton 在 1986 年的論文《Learning distributed representations of concepts》中提出的。雖然這篇文章沒(méi)有說(shuō)要將詞做 Distributed representation但至少這種先進(jìn)的思想在那個(gè)時(shí)候就在人們的心中埋下了火種,到 2000 年之后開(kāi)始逐漸被人重視。 3. 詞向量的訓(xùn)練 要介紹詞向量是怎么訓(xùn)練得到的,就不得不提到語(yǔ)言模型。到目前為止我了解到的所有訓(xùn)練方法都是在訓(xùn)練語(yǔ)言模型的同時(shí),順便得到詞向量的。 這也比較容易理解,要從一段無(wú)標(biāo)注的自然文本中學(xué)習(xí)出一些東西,無(wú)非就是統(tǒng)計(jì)出詞頻、詞的共現(xiàn)、詞的搭配之類(lèi)的信息。而要從自然文本中統(tǒng)計(jì)并建立一個(gè)語(yǔ)言模型,無(wú)疑是要求最為精確的一個(gè)任務(wù)(也不排除以后有人創(chuàng)造出更好更有用的方法)。既然構(gòu)建語(yǔ)言模型這一任務(wù)要求這么高,其中必然也需要對(duì)語(yǔ)言進(jìn)行更精細(xì)的統(tǒng)計(jì)和分析,同時(shí)也會(huì)需要更好的模型,更大的數(shù)據(jù)來(lái)支撐。目前最好的詞向量都來(lái)自于此,也就不難理解了。 詞向量的訓(xùn)練最經(jīng)典的有 3 個(gè)工作,C&W 2008、M&H 2008、Mikolov 2010。當(dāng)然在說(shuō)這些工作之前,不得不介紹一下這一系列中 Bengio 的經(jīng)典之作 4. 詞向量的評(píng)價(jià) 詞向量的評(píng)價(jià)大體上可以分成兩種方式,第一種是把詞向量融入現(xiàn)有系統(tǒng)中,看對(duì)系統(tǒng)性能的提升;第二種是直接從語(yǔ)言學(xué)的角度對(duì)詞向量進(jìn)行分析,如相似度、語(yǔ)義偏移等。 4.1 提升現(xiàn)有系統(tǒng) 詞向量的用法最常見(jiàn)的有兩種: 1. 直接用于神經(jīng)網(wǎng)絡(luò)模型的輸入層。如 C&W 的 SENNA 系統(tǒng)中,將訓(xùn)練好的詞向量作為輸入,用前饋網(wǎng)絡(luò)和卷積網(wǎng)絡(luò)完成了詞性標(biāo)注、語(yǔ)義角色標(biāo)注等一系列任務(wù)。再如 Socher 將詞向量作為輸入,用遞歸神經(jīng)網(wǎng)絡(luò)完成了句法分析、情感分析等多項(xiàng)任務(wù)。 2. 作為輔助特征擴(kuò)充現(xiàn)有模型。如 Turian 將詞向量作為額外的特征加入到接近 state of the art 的方法中,進(jìn)一步提高了命名實(shí)體識(shí)別和短語(yǔ)識(shí)別的效果。 4.2 語(yǔ)言學(xué)評(píng)價(jià) 還有一個(gè)有意思的分析是 Mikolov 在 2013 年剛剛發(fā)表的一項(xiàng)發(fā)現(xiàn)。他發(fā)現(xiàn)兩個(gè)詞向量之間的關(guān)系,可以直接從這兩個(gè)向量的差里體現(xiàn)出來(lái)。向量的差就是數(shù)學(xué)上的定義,直接逐位相減。比如 C(king)?C(queen)≈C(man)?C(woman)。更強(qiáng)大的是,與 C(king)?C(man)+C(woman) 最接近的向量就是 C(queen)。 為了分析詞向量的這個(gè)特點(diǎn), Mikolov 使用類(lèi)比(analogy)的方式來(lái)評(píng)測(cè)。如已知 a 之于 b 猶如 c 之于 d。現(xiàn)在給出 a、b、c,看 C(a)?C(b)+C(c) 最接近的詞是否是 d。 在文章 Mikolov 對(duì)比了詞法關(guān)系(名詞單復(fù)數(shù) good-better:rough-rougher、動(dòng)詞第三人稱單數(shù)、形容詞比較級(jí)最高級(jí)等)和語(yǔ)義關(guān)系(clothing-shirt:dish-bowl) 這些實(shí)驗(yàn)結(jié)果中最容易理解的是:語(yǔ)料越大,詞向量就越好。其它的實(shí)驗(yàn)由于缺乏嚴(yán)格控制條件進(jìn)行對(duì)比,談不上哪個(gè)更好哪個(gè)更差。不過(guò)這里的兩個(gè)語(yǔ)言學(xué)分析都非常有意思,尤其是向量之間存在這種線性平移的關(guān)系,可能會(huì)是詞向量發(fā)展的一個(gè)突破口。 關(guān)于Deep Lerning In Nlp的一些相關(guān)論文,《Deep Learning in NLP (一)詞向量和語(yǔ)言模型》(http://licstar.net/archives/328)這篇博客總結(jié)的非常的好。以上內(nèi)容大多數(shù)都是截取原博客內(nèi)容。 二、實(shí)際操作 這篇文章是最近幾天看word2vec源碼以及相關(guān)神經(jīng)網(wǎng)絡(luò)訓(xùn)練詞向量論文之后的個(gè)人小小的總結(jié),主要是針對(duì)word2vec的使用,做一下介紹。望大家使用的過(guò)程中,少走彎路。 word2vec工具中包含了對(duì)兩種模型的訓(xùn)練,如下圖。在訓(xùn)練每種模型的時(shí)候又分HS和NEG兩種方法。(看圖就可以發(fā)現(xiàn),其實(shí)word2vec并不deep……) 除了google自己的word2vec工具,各位對(duì)詞向量感興趣的牛人們也相繼編寫(xiě)了各自不同的版本。其中比較好用的是Python Gensim主題模型包中的word2vec,但通過(guò)閱讀其源碼python版本只實(shí)現(xiàn)了skip-gram模型,并且只實(shí)現(xiàn)了通過(guò)分層softmax方法對(duì)其訓(xùn)練,并沒(méi)有使用negative sampling。下面列舉一下目前出現(xiàn)的版本以及相對(duì)應(yīng)的地址,供大家選擇。如下表: 版本 地址 CBOW Skip-Gram C http://word2vec.googlecode.com/svn/trunk/ HS NEG HS NEG python http://radimrehurek.com/gensim/ HS Java https://github.com/ansjsun/Word2VEC_java HS HS C++ https://github.com/jdeng/word2vec 未知 未知 未知 未知 以上代碼,C++版本的我沒(méi)有看過(guò)。最權(quán)威的當(dāng)然是C語(yǔ)言版本,但是閱讀起來(lái)比較困難一點(diǎn)。Python版本有優(yōu)化處理,所以速度相對(duì)來(lái)說(shuō)也不慢,但只是實(shí)現(xiàn)了分層softmax方法對(duì)skip-gram模型進(jìn)行訓(xùn)練。Java版本分別實(shí)現(xiàn)了分層softmax方法對(duì)CBOW模型和skip-gram模型進(jìn)行訓(xùn)練。C++版本的沒(méi)有閱讀其代碼,所以未知…… 使用之前,先貼一些論文中對(duì)兩個(gè)模型和不同方法的評(píng)價(jià)圖片,方便大家根據(jù)不同任務(wù)進(jìn)行不同訓(xùn)練。 下面以c語(yǔ)言正式版本為例,來(lái)介紹word2vec的使用。 首先我們將google word2vec項(xiàng)目源碼checkout 到本機(jī),具體地址是http://word2vec.googlecode.com/svn/trunk/ 使用ssh登錄實(shí)驗(yàn)室Linux服務(wù)器,地址192.168.1.143。將剛才checkout的文件,上傳到服務(wù)器中。 進(jìn)入目錄,命令行輸入make指令,進(jìn)行編譯。 這樣我們就可以開(kāi)始使用,word2vec工具了。 1.將文本語(yǔ)料進(jìn)行分詞,以空格,tab隔開(kāi)都可以,中文分詞工具可以使用張華平博士的NLPIR2013 http://ictclas.nlpir.org/ 喜歡用Python 的童鞋也可以使用結(jié)巴分詞https://github.com/fxsjy/jieba。 2.將分好詞的訓(xùn)練語(yǔ)料進(jìn)行訓(xùn)練,假定我語(yǔ)料名稱為test.txt且在word2vec目錄中。輸入命令: ./word2vec -train test.txt -output vectors.bin -cbow 0 -size 200 -window 5 -negative 0 -hs 1 -sample 1e-3 -threads 12 -binary 1 以上命令表示的是輸入文件是test.txt,輸出文件是vectors.bin,不使用cbow模型,默認(rèn)為Skip-Gram模型。 每個(gè)單詞的向量維度是200,訓(xùn)練的窗口大小為5就是考慮一個(gè)詞前五個(gè)和后五個(gè)詞語(yǔ)(實(shí)際代碼中還有一個(gè)隨機(jī)選窗口的過(guò)程,窗口大小<=5)。不使用NEG方法,使用HS方法。-sampe指的是采樣的閾值,如果一個(gè)詞語(yǔ)在訓(xùn)練樣本中出現(xiàn)的頻率越大,那么就越會(huì)被采樣。-binary為1指的是結(jié)果二進(jìn)制存儲(chǔ),為0是普通存儲(chǔ)(普通存儲(chǔ)的時(shí)候是可以打開(kāi)看到詞語(yǔ)和對(duì)應(yīng)的向量的)除了以上命令中的參數(shù),word2vec還有幾個(gè)參數(shù)對(duì)我們比較有用比如-alpha設(shè)置學(xué)習(xí)速率,默認(rèn)的為0.025.–min-count設(shè)置最低頻率,默認(rèn)是5,如果一個(gè)詞語(yǔ)在文檔中出現(xiàn)的次數(shù)小于5,那么就會(huì)丟棄。-classes設(shè)置聚類(lèi)個(gè)數(shù),看了一下源碼用的是k-means聚類(lèi)的方法。 · 架構(gòu):skip-gram(慢、對(duì)罕見(jiàn)字有利)vs CBOW(快) · 訓(xùn)練算法:分層softmax(對(duì)罕見(jiàn)字有利)vs 負(fù)采樣(對(duì)常見(jiàn)詞和低緯向量有利) · 欠采樣頻繁詞:可以提高結(jié)果的準(zhǔn)確性和速度(適用范圍1e-3到1e-5) · 文本(window)大小:skip-gram通常在10附近,CBOW通常在5附近 3.訓(xùn)練好模型之后,得到vectors.bin這個(gè)模型文件。vectors.bin這個(gè)文件就是文檔中詞語(yǔ)和其對(duì)應(yīng)的向量,這個(gè)向量的維度是你訓(xùn)練時(shí)設(shè)置的參數(shù)大小。下面我們可以利用這個(gè)model做很多自然語(yǔ)言處理的任務(wù)了。Google代碼里面提供了distance的一個(gè)應(yīng)用,說(shuō)白了就是讀取模型文件中每一個(gè)詞和其對(duì)應(yīng)的向量,計(jì)算所輸入query的詞,與其他所有詞語(yǔ)的cosine相似度,排序,返回結(jié)果。同理訓(xùn)練命令中的-classes參數(shù),也是獲取每個(gè)詞對(duì)應(yīng)的向量之后,對(duì)詞語(yǔ)進(jìn)行k-means聚類(lèi)。對(duì)于訓(xùn)練出來(lái)的模型進(jìn)行操作,我推薦大家使用http://blog.csdn.net/zhaoxinfan/article/details/11640573這個(gè)java版本的模型讀取類(lèi),比較方便,讀取模型之后大家就可以來(lái)實(shí)現(xiàn)各種各樣有趣的東西了。下面舉幾個(gè)例子: a.計(jì)算兩個(gè)詞語(yǔ)相似度,如圖1計(jì)算asp與net的相似度為0.6215127 圖1 b.列出所有相似詞語(yǔ)列表,如圖2為“php”的結(jié)果。 圖二 c.尋找對(duì)應(yīng)關(guān)系:如圖3: 男人-男孩 女人-? 如圖4:內(nèi)蒙-呼和浩特 河北-? 圖3 圖4 d.刪選不合群的詞語(yǔ),可以用來(lái)做特征選擇:如圖5所示: