這是全棧數(shù)據(jù)工程師養(yǎng)成攻略系列教程的第十八期:18 NLP 詞嵌入的概念和實(shí)現(xiàn)芳肌。
詞嵌入(Word Embedding)是一項(xiàng)非常重要且應(yīng)用廣泛的技術(shù)夯到,可以將文本和詞語轉(zhuǎn)換為機(jī)器能夠接受的數(shù)值向量宾巍,這里我們?cè)敿?xì)討論其概念和實(shí)現(xiàn)倒堕。
語言的表示
如何向計(jì)算機(jī)解釋一個(gè)詞語的意思闽巩?或者說如何表示一個(gè)詞語才能恰當(dāng)?shù)伢w現(xiàn)出其包含的語義框冀?看到“蘋果”這個(gè)詞時(shí)流椒,我們會(huì)聯(lián)想起可以吃的蘋果這一水果,還會(huì)聯(lián)想起喬布斯創(chuàng)建的蘋果公司明也,因此一個(gè)詞可以包含多重語義宣虾。如果讓計(jì)算機(jī)分析“蘋果”和“梨子”兩個(gè)詞之間的相關(guān)性,通過字符串匹配只能得到完全不相等的結(jié)論温数,但是我們知道它們都屬于水果安岂,因此詞語所蘊(yùn)含的語義往往非常復(fù)雜,無法通過簡(jiǎn)單的字符串表示帆吻。
語言的表示主要有兩種:符號(hào)主義和分布式表示域那。
符號(hào)主義中典型的代表是Bag of words,即詞袋模型猜煮。如果將語料詞典中的每個(gè)詞都看作一個(gè)袋子次员,那么一句話無非是選擇一些袋子,然后將出現(xiàn)的詞丟入相應(yīng)的袋子王带。用數(shù)學(xué)的語言來說淑蔚,假設(shè)詞典中一共有N個(gè)詞,就可以用N個(gè)N維向量來表示每個(gè)詞愕撰。以下是用Python描述的一個(gè)簡(jiǎn)單例子刹衫,這里的詞典中只有5個(gè)詞:蘋果、梨子搞挣、香蕉带迟、和、好吃囱桨,分別用一個(gè)5維向量表示仓犬,僅對(duì)應(yīng)的維度上為1,其他維度都為0舍肠〔蠹蹋基于詞袋模型可以方便地用一個(gè)N維向量表示任何一句話窘面,每個(gè)維度的值即對(duì)應(yīng)的詞出現(xiàn)的次數(shù)。
# 詞典:蘋果叽躯、梨子财边、香蕉、和点骑、好吃
dictionary = {
"蘋果": [1, 0, 0, 0, 0],
"梨子": [0, 1, 0, 0, 0],
"香蕉": [0, 0, 1, 0, 0],
"和": [0, 0, 0, 1, 0],
"好吃": [0, 0, 0, 0, 1]
}
# 蘋果好吃:[1, 0, 0, 0, 1]
# 梨子和香蕉好吃:[0, 1, 1, 1, 1]
# 蘋果好吃蘋果好吃:[2, 0, 0, 0, 2]
詞袋模型雖然簡(jiǎn)單制圈,但其缺點(diǎn)也十分顯著。
- 當(dāng)詞典中詞的數(shù)量增大時(shí)畔况,向量的維度將隨之增大。雖然常用的漢字只有幾千個(gè)慧库,但是依然會(huì)給計(jì)算帶來很大的不便跷跪;
- 無論是詞還是句子的表示,向量都過于稀疏齐板,除了少數(shù)維度之外的大多數(shù)維度都為0吵瞻;
- 每個(gè)詞所對(duì)應(yīng)的向量在空間上都兩兩正交,任意一對(duì)向量之間的內(nèi)積等數(shù)值特征都為零甘磨,無法表達(dá)詞語之間的語義關(guān)聯(lián)和差異橡羞;
- 句子的向量表示丟失了詞序特征,即“我很不高興”和“不我很高興”對(duì)應(yīng)的向量相同济舆,而這顯然是不符合語義的卿泽。
分布式表示中典型的代表是Word Embedding,即詞嵌入滋觉,使用低維签夭、稠密、實(shí)值的詞向量來表示每一個(gè)詞椎侠,從而賦予詞語豐富的語義含義第租,并使得計(jì)算詞語相關(guān)度成為可能。以最簡(jiǎn)單的情況為例我纪,如果使用二維向量來表示詞語慎宾,那么可以將每個(gè)詞看作平面上的一個(gè)點(diǎn),點(diǎn)的位置即橫縱坐標(biāo)由對(duì)應(yīng)的二維向量確定浅悉,可以是任意且連續(xù)的趟据。如果希望點(diǎn)的位置中蘊(yùn)含詞的語義,那么平面上位置相鄰的點(diǎn)應(yīng)當(dāng)具有相關(guān)或相似的語義术健。用數(shù)學(xué)的語言來說之宿,兩個(gè)詞具有語義相關(guān)或相似,則它們所對(duì)應(yīng)的詞向量之間距離相近苛坚,度量向量之間的距離可以使用經(jīng)典的歐拉距離和余弦相似度等比被。
詞嵌入可以將詞典中的每個(gè)詞映射成對(duì)應(yīng)的詞向量色难,一個(gè)好的詞嵌入模型應(yīng)當(dāng)滿足以下兩方面要求:
- 相關(guān):語義相關(guān)或相似的詞語,它們所對(duì)應(yīng)的詞向量之間距離相近等缀,例如“蘋果”和“梨子”的詞向量距離相近枷莉;
- 類比:具有類比關(guān)系的四個(gè)詞語,例如男人對(duì)于女人尺迂,類比國(guó)王對(duì)于王后笤妙,滿足
男人-女人=國(guó)王-王后
,即保持詞向量之間的關(guān)聯(lián)類比噪裕,其中的減號(hào)表示兩個(gè)詞向量之間求差蹲盘。
這樣一來,通過詞嵌入模型得到的詞向量中既包含了詞本身的語義膳音,又蘊(yùn)含了詞之間的關(guān)聯(lián)召衔,同時(shí)具備低維、稠密祭陷、實(shí)值等優(yōu)點(diǎn)苍凛,可以直接輸入到計(jì)算機(jī)并進(jìn)行后續(xù)分析。但詞典中的詞如此之多兵志,詞本身的語義便十分豐富醇蝴,詞之間的關(guān)聯(lián)則更為復(fù)雜,所以相對(duì)于詞袋模型想罕,訓(xùn)練一個(gè)足夠好的詞向量模型更加困難悠栓。
訓(xùn)練詞嵌入模型
詞嵌入模型的訓(xùn)練主要是基于無監(jiān)督學(xué)習(xí),從大量文本語料中學(xué)習(xí)出每個(gè)詞的最佳詞向量按价,例如維基百科闸迷、大量新聞報(bào)道等。訓(xùn)練的核心思想是俘枫,語義相關(guān)或相似的詞語腥沽,往往具有相似的上下文,即它們經(jīng)常在相似的語境中出現(xiàn)鸠蚪,例如“蘋果”和“梨子”的上下文中可能都會(huì)出現(xiàn)類似“吃”今阳、“水果”等詞語,可以使用“開心”的語境往往也能使用“高興”茅信。
詞嵌入模型中的典型代表是Word2Vec盾舌,模型實(shí)現(xiàn)原理可以參考Mikolov的兩篇文章,Distributed Representations of Words and Phrases and their Compositionality蘸鲸,Efficient Estimation of Word Representations in Vector Space妖谴,主要包括CBOW和Skip-Gram兩個(gè)模型,前者根據(jù)上下文預(yù)測(cè)對(duì)應(yīng)的當(dāng)前詞語,后者根據(jù)當(dāng)前詞語預(yù)測(cè)相應(yīng)的上下文膝舅。如果希望進(jìn)一步深入理解詞嵌入模型訓(xùn)練的原理和細(xì)節(jié)嗡载,可以仔細(xì)研讀以上兩篇文章。如果僅需要應(yīng)用詞嵌入模型仍稀,則直接了解如何用代碼實(shí)現(xiàn)即可洼滚。
代碼實(shí)現(xiàn)
gensim是一款開源的Python工具包,用于從非結(jié)構(gòu)化文本中無監(jiān)督地學(xué)習(xí)文本隱層的主題向量表示技潘,支持包括TF-IDF遥巴、LSA、LDA和Word2Vec在內(nèi)的多種主題模型算法享幽,并提供了諸如相似度計(jì)算铲掐、信息檢索等一系列常用任務(wù)的API接口。以下是gensim官網(wǎng)對(duì)于其中Word2Vec模型的介紹值桩,http://radimrehurek.com/gensim/models/word2vec.html摆霉,里面提供了和Word2Vec相關(guān)的完整使用文檔。
同樣颠毙,如果沒有g(shù)ensim的話,使用pip安裝即可砂碉。
pip install gensim
另外蛀蜜,gensim僅提供了Word2Vec的模型實(shí)現(xiàn),訓(xùn)練詞向量的另一個(gè)必須條件是足夠大的文本語料增蹭。這里我們將要使用的是中文維基百科語料滴某,我已經(jīng)整理成文本文件并放在網(wǎng)盤上,直接下載即可滋迈,https://pan.baidu.com/s/1qXKIPp6霎奢,提取密碼為kade
。
下載之后可以在Sublime中打開并查看其內(nèi)容饼灿,文件名和后綴名可以不用在意幕侠,因?yàn)镾ublime支持打開任意類型的文本文件。其中每一行是一條維基百科碍彭,即一項(xiàng)詞條對(duì)應(yīng)的百科內(nèi)容晤硕,并且已經(jīng)完成了分詞處理。
以下代碼使用gensim提供的Word2Vec模型訓(xùn)練并使用詞向量庇忌,主要包括加載包舞箍、訓(xùn)練模型、保存模型皆疹、加載模型疏橄、使用模型等步驟。
# 加載包
from gensim.models import Word2Vec
from gensim.models.word2vec import LineSentence
# 訓(xùn)練模型
sentences = LineSentence('wiki.zh.word.text')
# size:詞向量的維度
# window:上下文環(huán)境的窗口大小
# min_count:忽略出現(xiàn)次數(shù)低于min_count的詞
model = Word2Vec(sentences, size=128, window=5, min_count=5, workers=4)
# 保存模型
model.save('word_embedding_128')
# 如果已經(jīng)保存過模型略就,則直接加載即可
# 前面訓(xùn)練并保存的代碼都可以省略
# model = Word2Vec.load("word_embedding_128")
# 使用模型
# 返回和一個(gè)詞語最相關(guān)的多個(gè)詞語以及對(duì)應(yīng)的相關(guān)度
items = model.most_similar(u'中國(guó)')
for item in items:
# 詞的內(nèi)容捎迫,詞的相關(guān)度
print item[0], item[1]
# 返回兩個(gè)詞語之間的相關(guān)度
model.similarity(u'男人', u'女人')
除此之外宣脉,gensim中的Word2Vec還實(shí)現(xiàn)了多項(xiàng)NLP功能,例如從多個(gè)詞中找出和其他詞相關(guān)性相對(duì)更弱的一個(gè)雹锣,以及根據(jù)給定的三個(gè)詞類比推理出第四個(gè)詞等耳高,詳細(xì)使用方法可以參考官方完整文檔。
視頻鏈接:詞嵌入的概念和實(shí)現(xiàn)