基於word2vec的文檔語義分析
偶然間看到了 https://zhuanlan.zhihu.com/p/21428792 的文章,一下子引起了我的興趣。但是文中對於很多概念都沒有很清楚的講解,那麼我就來做一個相對詳細的解釋吧。
作者:李凱東、徐麗
一簡介
1.1 引論
本文主要分析使用word2vec進行文檔(此處指由字元串表示的文檔)的與語義分析。使用gensim包的word2vec模型對文庫進行訓練,得到目標模型後,我們可進一步作如下研究:
1)判斷任意兩個辭彙的相似度。此處的相似度指餘弦相似度【1,similarity(w1, w2)】。
2)給定一個辭彙,找到與之最相似的n個辭彙。
3)對辭彙進行聚類,例如kMeans聚類,層次聚類等。因為word2vec的目標向量空間是對辭彙語義的相對準確描述,因此聚類時可以得到較好的結果。
1.2開發環境
本文所述演算法以Python實現。所用到的包如下:
1)scipy:科學計算
2)matplotlib:繪圖
3)gensim:語義分析
4)sklearn:機器學習
5)jieba:中文分詞
1.3 實驗環境
本文對金庸小說進行人物、功夫、幫派的語義上下文分析。事先準備的實驗資源為:
1)金庸小說的本文文件
2)人名列表
3)功夫名稱列表
4)幫派名稱列表
二樣本
本章可參考【2】。
2.1 文檔
文檔(Document)可描述為一個由單片語成的集合。而多個文檔則組成文檔集合。例如:
["Human machine interface for lababc computer applications",
"A survey of user opinion ofcomputer system response time",
"The EPS user interfacemanagement system",
"System and human systemengineering testing of EPS",
"Relation of user perceivedresponse time to error measurement",
"The generation of random binaryunordered trees",
"The intersection graph of pathsin trees",
"Graph minors IV Widths of treesand well quasi ordering",
"Graph minors A survey"]
每一行是一個文檔,而所有的文檔組成一個文檔集合。這些文檔可以作為訓練語義模型的樣本。
2.2 分詞
文檔必須分割為單詞序列。
對於英文文檔,可直接使用split()方法,依據空格進行分割。
對於中文,則必須用詞庫進行匹配。此處使用的是jieba分詞包。如果希望給jieba提供自定義此庫,可用以下方法實現:
for wordin words:
jieba.add_word(word)
使用cut方法進行分詞:
jieba.cut(line)
分詞之後將得到以下對象(此例子是從【2】中參考的,其中英文介詞已經被去掉):
[[human, interface, computer],
[survey, user, computer,system, response, time],
[eps, user, interface,system],
[system, human, system, eps],
[user, response, time],
[trees],
[graph, trees],
[graph, minors, trees],
[graph, minors, survey]]
三 word2vec訓練
3.1 實現
直接調用gensim的相應方法即可:
model =gensim.models.Word2Vec(sentences,
size=100,
window=5,
min_count=5,
workers=4)
該方法的參數如下:
sentences:訓練集,即前述2.2中的分詞結果列表。
Size:目標向量的長度。如果取100,則生成長度為100的向量。
Window:窗口大小,計算時所用的控制參數。控制當前辭彙和預測辭彙之間可能的最大距離。Window值越大,所需要枚舉的預測辭彙越多,計算時間越長。
Min_count:最小出現次數。此處意為出現次數少於5次的辭彙將被忽略。
Workers:訓練時使用的線程數。
3.2 Word2vec原理
Word2vec是用來重構語義上下文的演算法,它將辭彙空間映射到一個高維實向量空間中(維度的典型大小是幾百)。其發明者為Google的Tomas Mikolov,其原始論文在【3】。根據Mikolov,此系列演算法非常注重辭彙的上下文和語義,因此有別於傳統NLP領域中將辭彙看作是原子對象的做法,因而在NLP中取得了突破性的成功,而且被廣泛應用。
其現在常用的實現方式是兩層神經網路。它的基本思想是辭彙的語義相似度,可以由其對應向量的餘弦相似度表示。因此在目標空間中,相似的辭彙其向量將聚集為一處。因為維度較高,所以向量對空間的填充密集度很小,因此模型的敏感度較高。對Word2vec的數學原理分析可見【4】。
對於Word2vec的形象解釋可見【5】。請參見其中舉的如下示例。
China:Taiwan::Russia:[Ukraine,Moscow, Moldova, Armenia] //Two large countries and their small, estrangedneighbors
house:roof::castle:[dome,bell_tower, spire, crenellations, turrets]
前者China和Taiwan的關係,與Russia和例如Ukraine的關係相似。此處可以看到Word2vec的語義本質:它可以描述兩個概念之間的語義關係,而這種語義關係完全是通過文檔樣本的學習來實現的,它不要求有任何對現實世界的語義建模輸入(例如何為國家、國力、接壤等)。一方面在現階段進行常識建模的計算量非常大以至於不切合實際,另外也說明足夠量的樣本已經可以暴露出蘊含在其中的深層次語義概念。
四獲取相似度
4.1 獲取兩個辭彙的相似度
給定兩個辭彙w1和w2,S=similarity(w1, w2),0<=S<=1為w1和w2的相似度。S=1為最相似,S=0為最不相似。
在實驗中,我們設定:
name1=』小龍女』
names2=[『李莫愁』, 『周伯通』, 『裘千尺』, 『尼摩星』, 』楊過』,』黃蓉』,』郭靖』]
對[(w2,Si)]=S(w1, w2i)進行遍歷:
results ={};
fori inrange(0, len(names2)):
results[names2[i]]= model.similarity(name1, names2[i])
得到下面的結果。
李莫愁 0.894659744382
黃蓉 0.747729452107
尼摩星 0.562424555626
郭靖 0.714265416622
裘千尺 0.875459754365
周伯通 0.827707519769
楊過 0.969947306579
可以看到和「小龍女」最相關的人物為「楊過」。
4.2 給定辭彙獲取相似度列表
我們希望找到某一個辭彙的相似辭彙列表。例如尋找和「小龍女」最相關的30個人名,可以用以下方法實現:
for k, s inmodel.most_similar(positive=[u小龍女],topn=30):
if k innames:
print k, s
非人名辭彙已經被過濾掉,因此列表中的人名不足30條。輸出結果為:
楊過0.963029921055
李莫愁0.91172337532
郭芙0.906970024109
郭襄0.898455142975
裘千尺0.891280293465
周伯通0.855596780777
趙志敬0.850557327271
孫婆婆0.838372588158
陸無雙0.836666166782
公孫止0.79715013504
完顏萍0.780711233616
武修文0.775943934917
耶律齊0.770159721375
黃蓉0.766984045506
洪七公0.763851702213
柯鎮惡0.755305945873
朱子柳0.753480374813
4.3 匹配關係
此處敘述如何尋找匹配關係。所謂匹配關係,是指針對A和B之間的關係(A, B),如果給定C,求D,使得C和D之間的關係(C, D)是同性質的。例如【1】中most_similar中所舉的示例:
trained_model.most_similar(positive=[woman,king], negative=[man]) [(queen, 0.50882536), ...]
滿足
man:king::wonen:queen
即(man, king)與(women, queen)兩個關係的性質相同。另見【5】中Amusing Word2vec Results部分。
匹配關係的重構,可以看做是對潛在語義的發現。其原理仍然是根據向量的餘弦相似性。即尋找一個辭彙,其與women相關(性別),同時又與king相關(職位),但與man逆相關。
本實驗中我們尋找如下的匹配關係:
小龍女:楊過::黃蓉:?
楊過:小龍女::郭靖:?
使用如下的方法:
items =model.most_similar(positive=[u黃蓉, u楊過], negative=[u小龍女])
forr,s initems:
if r innames:
print r, s
得到的結果為:
1)
郭芙0.888121366501
郭靖0.8785790205
武修文0.872470200062
周伯通0.865872621536
丘處機0.861464202404
趙志敬0.861455023289
陸無雙0.851740598679
朱子柳0.849289953709
2)
黃蓉0.875000953674
黃藥師0.835819602013
丘處機0.828815102577
朱子柳0.803559422493
完顏萍0.802824795246
洪七公0.79979300499
可以看到匹配結果基本準確。
五人物姓名聚類分析
5.1 前提
在此我們以Word2vec產生的辭彙向量對《神鵰俠侶》中的人物姓名作kMeans聚類。一個辭彙的Word2vec向量緊湊地表示了它所處的上下文環境和基本語義,因此用它作為聚類的輸入,可預期相關人物將會被歸為一類。一般在小說情節上,我們可以列舉出如下的常見聚類方式:
1) 自然親屬關係:類別中的人物具有夫妻、父子、婦女、母子、母女等親屬關係。
2) 社區關係:類別中的人物同屬於一個社區(Community),例如公司、組織、派別、陣營等。
3) 意識形態關係:類別中的人物具有基本相同的意識形態或政治取向。
4) 性格關係:類別中的人物同屬於基本相同的性格特質或人格特徵。例如進取、冒險、獨斷、勇敢,或懦弱、虛偽、順從、自大、貪婪等。
5) 經歷關係:類別中的人物具有類似的人生經歷。例如深入敵方卧底、被國君冤殺、從草根到英雄等小說中的常見套路。
現階段從Word2vec的表象來看,Word2vec的訓練演算法對一個辭彙只能產生一個向量,即它對辭彙的語義歸屬只具有單一的解釋。它對語義的分析並非根據常識建模,也非根據自然語言的語法規則,而是根據辭彙的統計學規律對辭彙單元做出的統計性散列。根據聚類結果,我們無從直觀上判斷某一類別的歸類法則。因此對Word2vec向量聚類的實際語義取向以及其潛在分析價值,有待於對Word2vec方法作進一步深入研究後,方可得出準確結論。
5.2 實驗設計
1)對《神鵰俠侶》中的所有人物姓名集合S,首先以K=5運行kMeans聚類。
2)認為越小的類別其類別內聚性越大。因此去掉最大的兩個類別中的人物,將其餘人物收集為一個新的集合S1(kMeans聚類演算法本身無法判斷離群點的存在,因此需要集合其他統計性方法識別並過濾離群點)。
3)對S1以K=8運行kMeans聚類,得到類別C0-C7。
使用sklearn進行kMean聚類的代碼段如下:
names = [name for name in load_names()[u神鵰俠侶] if name in model]
name_vectors= [model[name] for name in names]
n = 5
label =KMeans(n).fit(name_vectors).labels_
首先獲取到小說中的所有人物姓名,即names。
然後創建names對應的Word2vec向量列表name_vectors。Model即實現訓練好的Word2vec模型。
最後調用KMeans的fit方法進行聚類。Fit仍然返回KMeans對象,其labels_屬性範圍對每一個向量的分類標號組成的列表。
5.3 實驗結果
第1遍
類別0:
子聰丁大全人廚子小棒頭尹志平王十三小王將軍王惟忠無常鬼申志凡
史伯威史仲猛聖因師太祁志誠弔死鬼百草仙陸二娘阿根張志光陸冠英
陳大方覺遠大師沙通天張一氓靈智上人耶律楚材喪門鬼青靈子柔兒郭破虜
宋五笑臉鬼崔志方鄂爾多薩多彭連虎韓無垢童大海瘦丐蒙哥
煞神鬼藍天和
類別1:
公孫止尹克西尼摩星達爾巴朱子柳完顏萍武三通武敦儒忽必烈耶律齊
洪凌波柯鎮惡洪七公黃藥師瀟湘子霍都樊一翁
類別2:
小龍女孫婆婆李莫愁陸無雙楊過武修文周伯通趙志敬郭芙郭襄
裘千尺
類別3:
馬鈺大頭鬼一燈大師王處一王志坦天竺僧少婦公孫綠萼孫不二馮默風
史叔剛史季強劉處玄李志常宋德方張君寶林朝英耶律燕點蒼漁隱鹿清篤
魯有腳彭長老裘千仞
類別4:
丘處機郭靖黃蓉 42
去掉類別0和3
第2遍
類別0:
丘處機朱子柳黃藥師
類別1:
孫婆婆武修文裘千尺
類別2:
小龍女楊過
類別3:
公孫止尹克西達爾巴完顏萍武三通武敦儒忽必烈洪凌波柯鎮惡洪七公
霍都樊一翁
類別4:
陸無雙郭芙郭襄
類別5:
尼摩星瀟湘子
類別6:
郭靖黃蓉
類別7:
李莫愁耶律齊周伯通趙志敬
六結語
6.1 結論
本文通過使用Word2vec模型作為實驗工具,對金庸小說《神鵰俠侶》進行了人物相似度和人物聚類分析。
6.2 進一步工作
1)本實驗在此方面留下很多問題,需對其做進一步深入研究。對Word2vec的語義取向方式尚不明晰,有很多可能的解釋方式:a)Word2vec忽略了語義相似定義的場合(語義上下文),b)Word2vec的散列方式是對所有可能語義取向方式的加權平均函數,因此並沒有忽略場合,c)Word2vec的語義相似定義方式與常識並無必然聯繫。另有研究者表明對Word2vec在語義重構方面成功的原因表示尚不清楚【6】。因此還有待研究本文中提出的問題與前述研究者所表述是否為同一概念。另外對【7】的研究可能會解釋前述的某些問題,因為該文章中說明了在NLP領域中研究者所關注的「語義」的真實含義。
2)有待於在小說文本中挖掘更多的可能性。例如把人物歸屬為幫派等,但此工作與本文中所述直接使用Word2vec的向量有明顯區別。現考慮此工作可能需要結合人工特徵工程方法實現。
參考文獻
1. gensim文檔:http://radimrehurek.com/gensim/models/word2vec.html
2. gensim文檔:http://radimrehurek.com/gensim/tut1.html
3. Mikolov的Word2vec原始論文:
http://120.52.73.78/arxiv.org/pdf/1301.3781.pdf
4. Word2vec的數學原理分析:
http://www-personal.umich.edu/~ronxin/pdf/w2vexp.pdf
5. deeplearning4j文檔:http://deeplearning4j.org/word2vec.html
6. Wikipedia:https://en.wikipedia.org/wiki/Word2vec,「The reasons for successful word embedding learning in the word2vec framework are poorlyunderstood. 」
7. Wikipedia:https://en.wikipedia.org/wiki/Distributional_semantics
推薦閱讀:
※有沒有雙重否定不是肯定的情況?
※目前哪些網站屬於語義網?
※請教高手:我理解的語義網路是否正確?我想參加這方面的研究。
※扯淡一詞的出處?
※編譯原理語義分析階段,現在已經做到了能生成語法樹,基於語法樹怎樣實現語義分析和中間代碼生成?
