文本分布式表示(三):用gensim訓練word2vec詞向量


今天參考網上的博客,用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

 


免責聲明!

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



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