Python之利用 gensim的word2vec进行酒店评论+wiki百科语料联合词向量训练

1.word2vec词向量原理解析

word2vec,即词向量,就是一个词用一个向量来表示。是2013年Google提出的。word2vec工具主要包含两个模型:跳字模型(skip-gram)和连续词袋模型(continuous bag of words,简称CBOW),以及两种高效训练的方法:负采样(negative sampling)和层序softmax(hierarchical softmax)。word2vec词向量可以较好地表达不同词之间的相似和类比关系。word2vec是一个NLP工具,它可以将所有的词向量化,这样词与词之间就可以定量的去度量他们之间的关系,挖掘词之间的联系。

NLP(自然语言处理)里面,最细粒度的是词语,词语组成句子,句子再组成段落、篇章、文档。所以处理 NLP 的问题,首先要先处理词语。词语,是人类的抽象总结,是符号形式的(比如中文、英文、拉丁文等等),所以需要把他们转换成数值形式,或者说——嵌入到一个数学空间里,这种嵌入方式,就叫词嵌入(word embedding),而 Word2vec,就是词嵌入( word embedding) 的一种。简单点来说就是把一个词语转换成对应向量的表达形式,来让机器读取数据。

2.gensim训练中文词向量

如果在以词为基本单元输入的自然语言处理任务中,都避免不了使用词的表示,词的表示有很多种,这里主要介绍的就是词向量,word2vec是目前比较通用的训练词向量的工具,使用Gensim模块,可以使词向量的训练变的简单,那么我们知道对于word2vec来说,不论的Skip-Gram models还是CBOW models,他们的输入以及输出都是以单词为基本单位的,只是他们对应的输入以及输出不一样:

  1. Skip-Gram models:输入为单个词,输出目标为多个上下文单词;
  2. CBOW models:输入为多个上下文单词,输出目标为一个单词;

我们从上面可以看出,无论是Skip-Gram models还是CBOW models基本的单元都是词,那么我们获取到的语料,必须要经过分词处理以后才能用于词向量的训练语料。

对于词向量的训练,语料越大训练出来的结果越好(非常重要)

3.word2vec类

参数表这一列,等号右边的值表示默认值

sentences (iterable of iterables, optional) – 供训练的句子,可以使用简单的列表,但是对于大语料库,建议直接从磁盘/网络流迭代传输句子。参阅word2vec模块中的BrownCorpus,Text8Corpus或LineSentence
corpus_file (str, optional) – LineSentence格式的语料库文件路径。
size (int, optional) – word向量的维度。
window (int, optional) – 一个句子中当前单词和被预测单词的最大距离。
min_count (int, optional) – 忽略词频小于此值的单词。
workers (int, optional) – 训练模型时使用的线程数。
sg ({0, 1}, optional) – 模型的训练算法: 1: skip-gram; 0: CBOW.
hs ({0, 1}, optional) – 1: 采用hierarchical softmax训练模型; 0: 使用负采样。
negative (int, optional) – > 0: 使用负采样,设置多个负采样(通常在5-20之间)。
ns_exponent (float, optional) – 负采样分布指数。1.0样本值与频率成正比,0.0样本所有单词均等,负值更多地采样低频词。
cbow_mean ({0, 1}, optional) – 0: 使用上下文单词向量的总和; 1: 使用均值,适用于使用CBOW。
alpha (float, optional) – 初始学习率。
min_alpha (float, optional) – 随着训练的进行,学习率线性下降到min_alpha。
seed (int, optional) – 随机数发生器种子。
max_vocab_size (int, optional) – 词汇构建期间RAM的限制; 如果有更多的独特单词,则修剪不常见的单词。 每1000万个类型的字需要大约1GB的RAM。
max_final_vocab (int, optional) – 自动选择匹配的min_count将词汇限制为目标词汇大小。
sample (float, optional) – 高频词随机下采样的配置阈值,范围是(0,1e-5)。
hashfxn (function, optional) – 哈希函数用于随机初始化权重,以提高训练的可重复性。
iter (int, optional) – 迭代次数。
trim_rule (function, optional) – 词汇修剪规则,指定某些词语是否应保留在词汇表中,修剪掉或使用默认值处理。
sorted_vocab ({0, 1}, optional) – 如果为1,则在分配单词索引前按降序对词汇表进行排序。
batch_words (int, optional) – 每一个batch传递给线程单词的数量。
compute_loss (bool, optional) – 如果为True,则计算并存储可使用get_latest_training_loss()检索的损失值。
callbacks (iterable of CallbackAny2Vec, optional) – 在训练中特定阶段执行回调序列。

4.开始训练

只需要给Word2Vec类赋上参数,就可以直接训练了。其中common_texts是一段内置的语料

[[‘human’, ‘interface’, ‘computer’], [‘survey’, ‘user’, ‘computer’, ‘system’, ‘response’, ‘time’], [‘eps’, ‘user’, ‘interface’, ‘system’], [‘system’, ‘human’, ‘system’, ‘eps’], [‘user’, ‘response’, ‘time’], [‘trees’], [‘graph’, ‘trees’], [‘graph’, ‘minors’, ‘trees’], [‘graph’, ‘minors’, ‘survey’]]

可以看到整体格式是[['A','B'],['C','D','E']],其中这个list表示所有的文本(此处表示2个文本,里面的A,B等表示单词,如果是中文则表示分词的结果

在示例1中,第8行和第10行都是用来保存训练模型的(简称save和format_save),而两者之间的相同点就是:都可以复用,即载入之后可以得到对应单词的词向量;不同点是:save保存的模型,载入之后可以继续在此基础上接着训练(后文会介绍),而format_save保存的模型不能,但有个好处就是如果s设置binary=False则保存后的结果可以直接打开查看(一共有12个词向量,每个词向量100维)

(1)查看词表相关信息

model = Word2Vec.load('./MyModel')
# 对于训练好的模型,我们可以通过下面这前三行代码来查看词表中的词,频度,以及索引位置,
# 最关键的是可以通过第四行代码判断模型中是否存在这个词
for key in model.wv.vocab:
    print(key)
    print(model.wv.vocab[key])
print('human' in model.wv.vocab)
print(len(model.wv.vocab)) #获取词表中的总词数

控制台输出:

human
Vocab(count:2, index:4, sample_int:579459575)
interface
Vocab(count:2, index:5, sample_int:579459575)
computer
Vocab(count:2, index:6, sample_int:579459575)
survey
Vocab(count:2, index:7, sample_int:579459575)
user
Vocab(count:3, index:1, sample_int:463795800)
system
Vocab(count:4, index:0, sample_int:396841800)
response
Vocab(count:2, index:8, sample_int:579459575)
time
Vocab(count:2, index:9, sample_int:579459575)
eps
Vocab(count:2, index:10, sample_int:579459575)
trees
Vocab(count:3, index:2, sample_int:463795800)
graph
Vocab(count:3, index:3, sample_int:463795800)
minors
Vocab(count:2, index:11, sample_int:579459575)
True
12

(2)获取对应的词向量及维度

# 示例3  获取对应的词向量及维度
model = Word2Vec.load('./MyModel')
print(model.wv.vector_size) #输出词向量的维度
print(model['human'])  #输出human这个词的词向量
print(model['good'])

(3)wiki+hotel语料训练词向量

from gensim.models import word2vec
import gensim
#分词结果split_result_txt包下多个txt合并,将分割符由/替换成空格
def review_corpus_merge():
    for i in range(1, 10):
        review_split_txt_path = 'split_result_txt/split_txt_' + str(i) + '.txt'
        fenci_result_corpus_path = 'fenci_result_corpus/hotel_review_corpus.txt'
        #读取文件
        f = open(review_split_txt_path, 'r', encoding='utf-8')
        for line in f.readlines():
            review = line.split("/")
            review_kongge = " ".join(review)
            if (len(review_kongge.strip()) != 0):  # strip()函数删除空格与换行符,删除空行
                #向文件中追加写入
                f = open(fenci_result_corpus_path, 'a', encoding='utf-8')
                f.write('\n' + review_kongge.strip())
                f.close()

#review_corpus_merge() 这个函数运行一次即可

def train_word2vec(filename):
    text = gensim.models.word2vec.LineSentence(filename)
    #参数说明:text训练语料,size设置训练的词向量为300维,min_count表示词频小于10的词汇不训练,sg=1表示使用skip-gram
    #hs=1表示使用hierarchical softmax训练模型,workers训练模型使用的线程数
    word2vec = gensim.models.word2vec.Word2Vec(text, size=300, window=10, min_count=10, sg=1, hs=1, iter=8,
                                               workers=25)
    word2vec.save('../word2vec_model/word2vec_hotel')
    word2vec.wv.save_word2vec_format('../word2vec_model/word2vec_hotel.txt', binary=False)
    print('语料数:', word2vec.corpus_count)
    print('词表长度:', len(word2vec.wv.vocab))

#首先先单独训练酒店语料库
train_word2vec('../fenci_result_corpus/hotel_review_corpus.txt')

# 在原有的酒店语料库中添加wiki百科语料库,进行进一步训练
loaded_model = gensim.models.word2vec.Word2Vec.load('../word2vec_model/word2vec_hotel')  # 加载模型
text_add = gensim.models.word2vec.LineSentence('../fenci_result_corpus/wiki_corpus')
loaded_model.build_vocab(sentences=text_add, update=True)
loaded_model.train(sentences=text_add, total_examples=loaded_model.corpus_count, epochs=loaded_model.iter)
loaded_model.save('../word2vec_model/word2vec_hotel_wiki')
loaded_model.wv.save_word2vec_format('../word2vec_model/word2vec_hotel_wiki.txt', binary=False)
print('语料数:', loaded_model.corpus_count)
print('词表长度:', len(loaded_model.wv.vocab))

训练结果:

5.追加训练

FileNotFoundError: [Errno 2] No such file or directory: 'word2vec_model/word2vec_hotel_3.wv.vectors.npy'

这是文件保存的路径有问题,应该检查文件的路径地址,考虑目录的层级结构,是否少了../等

最终训练模型保存为4个文件:

word2vec_hotel_wiki,
word2vec_hotel_wiki.trainables.syn1.npy,
word2vec_hotel_wiki.trainables.syn1neg.npy,
word2vec_hotel_wiki.wv.vectors.npy
import gensim
#加载已训练好的模型
loaded_model = gensim.models.word2vec.Word2Vec.load('../word2vec_model/word2vec_hotel_wiki')  # 加载模型
#获取要追加训练的语料
text_add = gensim.models.word2vec.LineSentence('../fenci_result_corpus/hotel_review_corpus_add02.txt')
loaded_model.build_vocab(sentences=text_add, update=True)
loaded_model.train(sentences=text_add, total_examples=loaded_model.corpus_count, epochs=loaded_model.iter)
#训练好的模型重新保存
loaded_model.save('../word2vec_model/word2vec_hotel_3')
loaded_model.wv.save_word2vec_format('../word2vec_model/word2vec_hotel_3.txt', binary=False)
print('语料数:', loaded_model.corpus_count)
print('词表长度:', len(loaded_model.wv.vocab))

参考文献:

https://blog.csdn.net/liuchenbaidu/article/details/106289334

https://www.jianshu.com/p/3c6c53ec1512 推荐

https://blog.csdn.net/The_lastest/article/details/81734980 必看

posted @ 2020-06-28 14:30  雨后观山色  阅读(1874)  评论(0编辑  收藏  举报