利用python中的gensim模塊訓練和測試word2vec


word2vec的基礎知識介紹參考上一篇博客和列舉的參考資料。

首先利用安裝gensim模塊,相關依賴如下,注意版本要一致:

    Python >= 2.7 (tested with versions 2.7, 3.5 and 3.6)
    NumPy >= 1.11.3
    SciPy >= 0.18.1
    Six >= 1.5.0
    smart_open >= 1.2.1

我們利用jieba分詞對《射雕英雄傳》進行分詞,然后訓練詞向量,最后進行測試

# -*- coding: utf-8-*-
import jieba
from gensim.models import word2vec

#  去掉中英文狀態下的逗號、句號
def clearSen(comment):
    comment = ' '.join(comment).replace('', '').replace('', '').replace('', '').replace('', '') \ .replace('', '').replace('', '').replace('', '').replace('', '').replace('', '').replace('', '') \ .replace('', '').replace('', '').replace('', '').replace('', '').replace('', '') \ .replace('', '') # 去掉標點符號
    return comment

# 用jieba進行分詞
comment = open(u'./corpus/金庸-射雕英雄傳txt精校版.txt').read()
comment = clearSen(comment)
#jieba.load_userdict('./user_dict/userdict_food.txt')
comment = ' '.join(jieba.cut(comment))
#print comment


# 分完詞后保存到新的txt中
fo = open("./corpus/afterSeg.txt","w")
fo.write(comment.encode('utf-8'))
print("finished!")
fo.close()

# 用 word2vec 進行訓練
sentences=word2vec.Text8Corpus(u'./corpus/afterSeg.txt')
# 第一個參數是訓練語料,第二個參數是小於該數的單詞會被剔除,默認值為5, 第三個參數是神經網絡的隱藏層單元數,默認為100
model=word2vec.Word2Vec(sentences,min_count=3, size=50, window=5, workers=4)
#------------------------------------------------------------------------
# Word2vec有很多可以影響訓練速度和質量的參數:
# (1) sg=1是skip-gram算法,對低頻詞敏感,默認sg=0為CBOW算法,所以此處設置為1。
# (2) min_count是對詞進行過濾,頻率小於min-count的單詞則會被忽視,默認值為5。
# (3) size是輸出詞向量的維數,即神經網絡的隱藏層的單元數。值太小會導致詞映射因為沖突而影響結果,值太大則會耗內存並使算法計算變慢,大的size需要更多的訓練數據, 但是效果會更好,在本文中設置的size值為300維度。
# (4) window是句子中當前詞與目標詞之間的最大距離,即為窗口。本文設置窗口移動的大小為5。
# (5) negative和sample可根據訓練結果進行微調,sample表示更高頻率的詞被隨機下采樣到所設置的閾值,默認值為1e-3。
# (6) hs=1表示層級softmax將會被使用,默認hs=0且negative不為0,則負采樣將會被選擇使用。
# (7) 最后一個主要的參數控制訓練的並行:worker參數只有在安裝了Cython后才有效,由於本文沒有安裝Cython的, 使用的單核。
#------------------------------------------------------------------------

# 保存模型
model.save("word2vec.model")
model.wv.save_word2vec_format("word2vec.model.bin", binary=True)

#測試
y2=model.similarity(u"郭靖", u"黃蓉") #計算兩個詞之間的余弦距離
print u"郭靖", u"黃蓉", 'similarity:',y2

for i in model.most_similar(u"黃蓉"): #計算余弦距離最接近“黃蓉”的10個詞
    print i[0],i[1]
    
for i in model.most_similar(u"郭靖"): #計算余弦距離最接近“郭靖”的10個詞
    print i[0],i[1]
# 訓練詞向量時傳入的兩個參數也對訓練效果有很大影響,需要根據語料來決定參數的選擇,好的詞向量對NLP的分類、聚類、相似度判別等任務有重要意義

加載保存的模型,進行測試:

>>> from gensim.models import word2vec
>>> model = word2vec.Word2Vec.load('word2vec.model')
>>> for e in model.most_similar(u"郭靖"): print e[0], e[1]
...
黃蓉 0.978638648987
歐陽克 0.95745909214
歐陽鋒 0.954400420189
梅超風 0.925759136677
鄭重 0.914724588394
裘千仞 0.907471776009
眾人 0.906147062778
彭連虎 0.903428137302
柯鎮惡 0.902874648571
梁子翁 0.893080115318
>>> for e in model.most_similar(u"黃蓉"): print e[0], e[1]
...
郭靖 0.978638589382
歐陽鋒 0.941402435303
歐陽克 0.937647461891
柯鎮惡 0.913198530674
鄭重 0.898928642273
梅超風 0.895552039146
楊康 0.890073120594
穆念慈 0.888899266720.887811601162
裘千仞 0.884677648544
>>>

利用這里訓練好的模型,查看其訓練效果:

>>> from gensim.models.deprecated.word2vec import Word2Vec
C:\Python27\lib\site-packages\gensim\utils.py:1212: UserWarning: detected Windows; aliasing chunkize to chunkize_serial
  warnings.warn("detected Windows; aliasing chunkize to chunkize_serial")
>>> model = Word2Vec.load('./model/Word60.model')
>>> for e in model.most_similar(u"朝陽區"): print e[0], e[1]
...
C:\Python27\lib\site-packages\gensim\matutils.py:737: FutureWarning: Conversion of the second argument of issubdtype from `int` to `np.signedinteger` is deprecated. In future, it will be treated as `np.int32 == np.dtype(int).type`.
  if np.issubdtype(vec.dtype, np.int):
海淀區 0.953941822052
豐台區 0.940896630287
石景山區 0.928724527359
東城區 0.90411567688
大興區 0.887912631035
西城區 0.885163784027
崇文區 0.872635483742
濟南市 0.868344843388
海淀 0.866064548492
通州區 0.860960006714
>>>
>>> for e in model.most_similar(u"郭靖"): print e[0], e[1]
...
黃蓉 0.947447776794
楊過 0.939437627792
段譽 0.930292785168
令狐沖 0.928993582726
張無忌 0.921128869057
周伯通 0.918897628784
黃葯師 0.918717026711
楊康 0.913613200188
小龍女 0.911328673363
喬峰 0.908709168434
>>>
>>> for e in model.most_similar(u"黃蓉"): print e[0], e[1]
...
郭靖 0.947447776794
楊過 0.942064762115
張無忌 0.929110050201
令狐沖 0.925551056862
楊康 0.922640800476
小龍女 0.92034471035
段譽 0.915760040283
趙敏 0.914794445038
黃葯師 0.910506725311
韋小寶 0.909034609795
>>> model.similarity(u"郭靖", u"黃蓉") #計算兩個詞之間的余弦距離
0.9474477

補充,word2vec是自然語言處理基礎知識,實現了詞向量表達。在此基礎上可以完成分類、推薦等。

本片文章是通過gensim來完成word2vec,上篇博客中參考資料也有通過TensorFlow實現word2vec。

還有一些詞向量的模型,看到https://www.cnblogs.com/royhoo/p/Advanced-Word-Vector-Representations.html介紹了GloVe,有時間再繼續學習。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM