一、 問題由來
word2vec的本質是一個神經網絡語言模型,基於語言模型進行分佈式詞向量的訓練。它需要大量的語料進行訓練,從而找到詞與詞之間的關係,但是當我們已經訓練好了一個word2vec模型之後,數據庫中又新流動進來了很多語料,我們應該在怎麼辦呢?我們不可能又基於所有語料重新訓練一遍(當語料過大時,太耗費時間了),這時候,增量訓練就派上了用場。
二、word2vec模型的增量訓練
import jieba
import re
import pandas as pd
from gensim.models.word2vec import Word2Vec
class TrainWord2Vec:
"""
訓練得到一個Word2Vec模型
@author:xiaozhu
@time:2018年10月12日
"""
def __init__(self, data, stopword, num_features=100, min_word_count=1, context=4, incremental=False,
old_path):
"""
定義變量
:param data: 用於訓練胡語料
:param stopword: 停用詞表
:param num_features: 返回的向量長度
:param min_word_count: 最低詞頻
:param context: 滑動窗口大小
:param incremental: 是否進行增量訓練
:param old_path: 若進行增量訓練,原始模型路徑
"""
self.data = data
self.stopword = stopword
self.num_features = num_features
self.min_word_count = min_word_count
self.context = context
self.incremental = incremental
self.old_path = old_path
def clean_text(self):
"""
採用結巴分詞函數分詞
:param corpus: 待分詞的Series序列
:return: 分詞結果,list
"""
# 去除無用字符
pattern = re.compile(r'[\sA-Za-z~()()【】%*#+-\.\\\/:=:__,,。、;;“”""''’‘??!!<《》>^&{}|=……]')
corpus_ = self.data.apply(lambda s: re.sub(pattern, '', s))
# 分詞
text = corpus_.apply(jieba.lcut)
# 過濾通用詞
text = text.apply(lambda cut_words: [word for word in cut_words if word not in self.stopword])
return text
def get_model(self, text):
"""
從頭訓練word2vec模型
:param text: 經過清洗之後的語料數據
:return: word2vec模型
"""
model = Word2Vec(text, size=self.num_features, min_count=self.min_word_count, window=self.context)
return model
def update_model(self, text):
"""
增量訓練word2vec模型
:param text: 經過清洗之後的新的語料數據
:return: word2vec模型
"""
model = Word2Vec.load(self.old_path) # 加載舊模型
model.build_vocab(text, update=True) # 更新詞彙表
model.train(text, total_examples=model.corpus_count, epochs=model.iter) # epoch=iter語料庫的迭代次數;(默認爲5) total_examples:句子數。
return model
def main(self):
"""
主函數,保存模型
"""
# 加入自定義分析詞庫
jieba.load_userdict("add_word.txt")
text = self.clean_text()
if self.incremental:
model = self.update_model(text)
else:
model = self.get_model(text)
# 保存模型
model.save("word2vec.model")
if __name__ == '__main__':
corpus = pd.read_csv("corpus.csv", encoding='gbk')
stop_word = pd.read_csv("stopword.csv", encoding='gbk')
trainmodel = TrainWord2Vec(data=corpus, stopword=stop_word)
trainmodel.main()
三、 gensim word2vec API概述
- 訓練模型
在gensim中,word2vec 相關的API都在包gensim.models.word2vec中。進行word2vec模型訓練的函數以及常用參數解釋如下:
from gensim.models.word2vec import Word2Vec
model = Word2Vec(text, size, min_count, window, sg)
- text: 分詞處理之後的語料
- size: 詞向量的維度,默認值是100
- min_count: 需要計算詞向量的最小詞頻。這個值可以去掉一些很生僻的低頻詞,默認是5。
- window: 滑動窗口大小,默認爲5。
- sg: 即我們的word2vec兩個模型的選擇了。如果是0, 則是CBOW模型,是1則是Skip-Gram模型,默認是0即CBOW模型。
- 保存模型
youmodelname.save('yourpath/word2vec.model')
- 加載模型
model = gensim.models.Word2Vec.load(r'youpath/word2vec.model')
- 計算兩個詞的相似度
yourmodel.similarity('word1', 'word2')
- 找到相似度最高的詞
yourmodel.most_similar('word', topn=10)
# topn: 返回最相似的詞的個數,默認爲10
- 在一些詞中找到最不相關的詞
yourmodel.doesbt_match(['word1', 'word2', 'word3', 'word4'])
- 輸出某個詞的詞向量
yourmodel['word']