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,他们的输入以及输出都是以单词为基本单位的,只是他们对应的输入以及输出不一样:
- Skip-Gram models:输入为单个词,输出目标为多个上下文单词;
- 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(' ' + 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 必看