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']
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章