word2vec 構建中文詞向量

詞向量做爲文本的基本結構——詞的模型,以其優越的性能,受到天然語言處理領域研究人員的青睞。良好的詞向量能夠達到語義相近的詞在詞向量空間裏彙集在一塊兒,這對後續的文本分類,文本聚類等等操做提供了便利,本文將詳細介紹如何使用word2vec構建中文詞向量。php

1、中文語料庫python

本文采用的是搜狗實驗室的搜狗新聞語料庫,數據連接 http://www.sogou.com/labs/resource/cs.phpgit

下載下來的文件名爲: news_sohusite_xml.full.tar.gzgithub

2、數據預處理
vim

2.1 解壓並查看原始數據app

cd 到原始文件目錄下,執行解壓命令:性能

tar -zvxf news_sohusite_xml.full.tar.gz

獲得文件 news_sohusite_xml.dat, 用vim打開該文件,this

vim news_sohusite_xml.dat

 獲得以下結果:spa

2.2 取出內容.net

取出<content>  </content> 中的內容,執行以下命令:

cat news_tensite_xml.dat | iconv -f gbk -t utf-8 -c | grep "<content>"  > corpus.txt 

 獲得文件名爲corpus.txt的文件,能夠經過vim 打開

vim corpus.txt

獲得以下效果:

 

2.3 分詞

注意,送給word2vec的文件是須要分詞的,分詞能夠採用jieba分詞實現,安裝jieba 分詞 

pip install jieba

 對原始文本內容進行分詞,python 程序以下: 

 1 ##!/usr/bin/env python
 2 ## coding=utf-8
 3 import jieba
 4 
 5 filePath='corpus.txt'
 6 fileSegWordDonePath ='corpusSegDone.txt'
 7 # read the file by line
 8 fileTrainRead = []
 9 #fileTestRead = []
10 with open(filePath) as fileTrainRaw:
11     for line in fileTrainRaw:
12         fileTrainRead.append(line)
13 
14 
15 # define this function to print a list with Chinese
16 def PrintListChinese(list):
17     for i in range(len(list)):
18         print list[i],
19 # segment word with jieba
20 fileTrainSeg=[]
21 for i in range(len(fileTrainRead)):
22     fileTrainSeg.append([' '.join(list(jieba.cut(fileTrainRead[i][9:-11],cut_all=False)))])
23     if i % 100 == 0 :
24         print i
25 
26 # to test the segment result
27 #PrintListChinese(fileTrainSeg[10])
28 
29 # save the result
30 with open(fileSegWordDonePath,'wb') as fW:
31     for i in range(len(fileTrainSeg)):
32         fW.write(fileTrainSeg[i][0].encode('utf-8'))
33         fW.write('\n')

 

能夠獲得文件名爲 corpusSegDone.txt 的文件,須要注意的是,對於讀入文件的每一行,使用結巴分詞的時候並非從0到結尾的所有都進行分詞,而是對[9:-11]分詞 (如行22中所示: fileTrainRead[i][9:-11] ),這樣能夠去掉每行(一篇新聞稿)起始的<content> 和結尾的</content>。

一樣的,能夠經過vim 打開分詞以後的文件,執行命令:

vim corpusSegDone.txt

獲得以下圖所示的結果:

 3、構建詞向量

3.1 安裝word2vec

pip install word2vec

3.2 構建詞向量

執行如下程序:

import word2vec
word2vec.word2vec('corpusSegDone.txt', 'corpusWord2Vec.bin', size=300,verbose=True)

便可構建詞向量,獲得結果放在文件名爲 corpusWord2Vec.bin的文件中。能夠經過設定size 的大小來指定詞向量的維數。用vim打開生成的二進制文件會出現亂碼,目前不知道解決方法。

3.3 顯示並使用詞向量

3.3.1 查看詞向量

import word2vec
model = word2vec.load('corpusWord2Vec.bin')
print (model.vectors)

能夠獲得以下結果:

 3.3.2 查看詞表中的詞

import word2vec
model = word2vec.load('corpusWord2Vec.bin')
index = 1000
print (model.vocab[index]

獲得結果以下:

能夠獲得詞表中第1000個詞爲 確保。

3.3.3 顯示空間距離相近的詞

一個好的詞向量能夠實現詞義相近的一組詞在詞向量空間中也是接近的,能夠經過顯示詞向量空間中相近的一組詞並判斷它們語義是否相近來評價詞向量構建的好壞。代碼以下:

import word2vec
model = word2vec.load('corpusWord2Vec.bin')
indexes = model.cosine(u'加拿大')
for index in indexes[0]:
    print (model.vocab[index])

獲得的結果以下:

能夠修改但願查找的中文詞,例子以下:

 

4、二維空間中顯示詞向量

將詞向量採用PCA進行降維,獲得二維的詞向量,並打印出來,代碼以下:

 1 #!/usr/bin/env python
 2 # coding=utf-8
 3 import numpy as np
 4 import matplotlib
 5 import matplotlib.pyplot as plt
 6 
 7 from sklearn.decomposition import PCA
 8 import word2vec
 9 # load the word2vec model
10 model = word2vec.load('corpusWord2Vec.bin')
11 rawWordVec=model.vectors
12 
13 # reduce the dimension of word vector
14 X_reduced = PCA(n_components=2).fit_transform(rawWordVec)
15 
16 # show some word(center word) and it's similar words
17 index1,metrics1 = model.cosine(u'中國')
18 index2,metrics2 = model.cosine(u'清華')
19 index3,metrics3 = model.cosine(u'牛頓')
20 index4,metrics4 = model.cosine(u'自動化')
21 index5,metrics5 = model.cosine(u'劉亦菲')
22 
23 # add the index of center word 
24 index01=np.where(model.vocab==u'中國')
25 index02=np.where(model.vocab==u'清華')
26 index03=np.where(model.vocab==u'牛頓')
27 index04=np.where(model.vocab==u'自動化')
28 index05=np.where(model.vocab==u'劉亦菲')
29 
30 index1=np.append(index1,index01)
31 index2=np.append(index2,index03)
32 index3=np.append(index3,index03)
33 index4=np.append(index4,index04)
34 index5=np.append(index5,index05)
35 
36 # plot the result
37 zhfont = matplotlib.font_manager.FontProperties(fname='/usr/share/fonts/truetype/wqy/wqy-microhei.ttc')
38 fig = plt.figure()
39 ax = fig.add_subplot(111)
40 
41 for i in index1:
42     ax.text(X_reduced[i][0],X_reduced[i][1], model.vocab[i], fontproperties=zhfont,color='r')
43 
44 for i in index2:
45     ax.text(X_reduced[i][0],X_reduced[i][1], model.vocab[i], fontproperties=zhfont,color='b')
46 
47 for i in index3:
48     ax.text(X_reduced[i][0],X_reduced[i][1], model.vocab[i], fontproperties=zhfont,color='g')
49 
50 for i in index4:
51     ax.text(X_reduced[i][0],X_reduced[i][1], model.vocab[i], fontproperties=zhfont,color='k')
52 
53 for i in index5:
54     ax.text(X_reduced[i][0],X_reduced[i][1], model.vocab[i], fontproperties=zhfont,color='c')
55 
56 ax.axis([0,0.8,-0.5,0.5])
57 plt.show()

中文的顯示須要作特殊處理,詳見代碼 line: 37

下圖是執行結果:

 

主要參考 

http://blog.csdn.net/zhaoxinfan/article/details/11069485

http://nbviewer.jupyter.org/github/danielfrg/word2vec/blob/master/examples/word2vec.ipynb

相關文章
相關標籤/搜索