Word2Vec模型增量训练

一、 问题由来

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)
  1. text: 分词处理之后的语料
  2. size: 词向量的维度,默认值是100
  3. min_count: 需要计算词向量的最小词频。这个值可以去掉一些很生僻的低频词,默认是5。
  4. window: 滑动窗口大小,默认为5。
  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']

猜你喜欢

转载自blog.csdn.net/qq_43404784/article/details/83794296
今日推荐