今天參考網上的博客,用gensim訓練了word2vec詞向量。訓練的語料是著名科幻小說《三體》,這部小說我一直沒有看,所以這次拿來折騰一下。
《三體》這本小說里有不少人名和一些特殊名詞,我從網上搜了一些,作為字典,加入到jieba里,以提高分詞的准確性。
一、gensim中關於word2vec的參數說明
這一部分其他博客整理的比較清楚了,我也就不抄過來了。看這個鏈接:
https://www.cnblogs.com/pinard/p/7278324.html
二、gensim訓練word2vec詞向量
(一)第一步:jieba加載自定義詞典
詞典是每個詞單獨一行,然后加入的時候,要注意把換行符去掉:word.strip(),不然你會驚奇地發現我的詞典加進去了怎么沒效果呢?
#encoding=utf8 import jieba from gensim.models import word2vec import gensim # 第一步:加入字典 def add_dict(): f = open('./text/special_nouns.txt','r', encoding='utf-8') for word in f: jieba.suggest_freq(word.strip(),tune=True) f.close() add_dict()
(二)第二步:讀取小說文本,進行分詞,並保存分詞結果
一般小說下載下來,文檔的原始編碼格式不是 UTF-8,而是 GBK,所以要進行編碼轉換。看其他博客轉來轉去比較麻煩,我是沒轉成功。。。然后我就直接把文檔另存為 UTF-8 格式了。
jieba分完詞后,要把結果用空格 ' ' 符號連接起來:' '.join(jieba.cut(document)), 詞語之間用空格隔開,這才是正確的輸入格式。
# 第二步:讀取三體小說的文本,並進行分詞 def document_segment(filename): f = open(filename, 'r',encoding='utf-8') document = f.read() document_cut = ' '.join(jieba.cut(document)) with open('./text/The_three_body_problem_segment.txt','w',encoding='utf-8') as f2: f2.write(document_cut) # f.close() f2.close() document_segment('./text/The_three_body_problem.txt')
(三)第三步:用CBOW模型訓練詞向量
LineSentence這個方法把傳入的文件轉化為一個迭代器,這個文件需要是每一行就是一個句子,每個句子中的詞之間用空格隔開。
word2vec 相關的參數都在包word2vec.Word2Vec中,sg=0表示用CBOW模型來訓練,hs=1表示加速方法為層次softmax,min_count=1表示詞的詞頻低於1就會被丟棄,實際上沒丟棄任何詞語。
windows=3 表示滑動窗口為3,上下文詞各取1個。size=100表示詞向量維度是100。
之所以這么設置是因為這個語料比較小。
def train_w2v(filename): text = word2vec.LineSentence(filename) model = word2vec.Word2Vec(text, sg=0,hs=1,min_count=1,window=3,size=100) model.save('./my_model') train_w2v('./text/The_three_body_problem_segment.txt')
(四)第四步:導入模型,簡單應用
導入保存好的模型后,一個是根據詞把相應的詞向量取出來,可以看到,取了三個詞的詞向量,所以詞向量矩陣為3*100維。
然后是計算兩個詞之間的相似度。再就是得到和某個詞比較相關的詞的列表。
# 導入保存好的模型 model = word2vec.Word2Vec.load('./my_model') # 取出詞語對應的詞向量。 vec = model[['紅岸','水滴','思想鋼印']] print('三個詞的詞向量矩陣的維度是:', vec.shape,'。') print('-------------------------------我是分隔符------------------------') # 計算兩個詞的相似程度。 print('葉文潔和紅岸的余弦相似度是:', model.similarity('葉文潔', '紅岸'),'。') print('-------------------------------我是分隔符------------------------') # 得到和某個詞比較相關的詞的列表 sim1 = model.most_similar('葉文潔',topn=10) for key in sim1: print('和葉文潔比較相關的詞有',key[0],',余弦距離是:',key[1])
三個詞的詞向量矩陣的維度是: (3, 100) 。 -------------------------------我是分隔符------------------------ 葉文潔和紅岸的余弦相似度是: 0.27795327 。 -------------------------------我是分隔符------------------------ 和葉文潔比較相關的詞有 章北海 ,余弦距離是: 0.9233694672584534 和葉文潔比較相關的詞有 他 ,余弦距離是: 0.9116515517234802 和葉文潔比較相關的詞有 羅輯 ,余弦距離是: 0.9056273698806763 和葉文潔比較相關的詞有 汪淼 ,余弦距離是: 0.8981802463531494 和葉文潔比較相關的詞有 吳岳 ,余弦距離是: 0.8976055979728699 和葉文潔比較相關的詞有 她 ,余弦距離是: 0.893031895160675 和葉文潔比較相關的詞有 程心 ,余弦距離是: 0.8800253868103027 和葉文潔比較相關的詞有 丁儀 ,余弦距離是: 0.8800160884857178 和葉文潔比較相關的詞有 雲天明 ,余弦距離是: 0.8763566613197327 和葉文潔比較相關的詞有 她們 ,余弦距離是: 0.875525712966919