目录
一:背景
之前总结了Word2vec训练词向量的细节,讲解了一个词是如何通过word2vec模型训练出唯一的向量来表示的。那接着可能就会想到,有没有什么办法能够将一个句子甚至一篇短文也用一个向量来表示呢?答案是肯定有的,Doc2vec就是常用的算法之一。许多机器学习算法需要的输入是一个固定长度的向量,当涉及到短文时,最常用的固定长度的向量方法是词袋模型(bag-of-words)。尽管它很流行,但是词袋模型存在两个主要的缺点:一个是词袋模型忽略词序,如果两个不同的句子由相同的词但是顺序不同组成,词袋模型会将这两句话定义为同一个表达;另一个是词袋模型忽略了句法,这样训练出来的模型会造成类似'powerful','strong'和'Paris'的距离是相同的,而其实'powerful'应该相对于'Paris'距离'strong'更近才对。
Doc2Vec 或者叫做 paragraph2vec, sentence embeddings,是一种非监督式算法,可以获得 sentences/paragraphs/documents 的向量表达,是 word2vec 的拓展。学出来的向量可以通过计算距离来找 sentences/paragraphs/documents 之间的相似性
二:基本原理
假设现在存在训练样本,每个句子是训练样本。和word2vec一样,Doc2vec也有两种训练方式,一种是PV-DM(Distributed Memory Model of paragraphvectors)类似于word2vec中的CBOW模型,训练句向量的方法和词向量的方法非常类似。训练词向量的核心思想就是说可以根据每个单词的上下文预测,也就是说上下文的单词对是有影响的。那么同理,可以用同样的方法训练doc2vec。例如对于一个句子i want to drink water,如果要去预测句子中的单词want,那么不仅可以根据其他单词生成feature, 也可以根据其他单词和句子来生成feature进行预测。如图一:
2.1:PV-DM
每个段落/句子都被映射到向量空间中,可以用矩阵DD的一列来表示。每个单词同样被映射到向量空间,可以用矩阵WW的一列来表示。然后将段落向量和词向量级联或者求平均得到特征,预测句子中的下一个单词。
这个段落向量/句向量也可以认为是一个单词,它的作用相当于是上下文的记忆单元或者是这个段落的主题,所以我们一般叫这种训练方法为Distributed Memory Model of Paragraph Vectors(PV-DM)
在训练的时候我们固定上下文的长度,用滑动窗口的方法产生训练集。段落向量/句向量 在该上下文中共享。
总结doc2vec的过程, 主要有两步:
- 训练模型,在已知的训练数据中得到词向量W, softmax的参数U和b,以及段落向量/句向量D
- 推断过程(inference stage),对于新的段落,得到其向量表达。具体地,在矩阵D中添加更多的列,在固定WW,UU,bb的情况下,利用上述方法进行训练,使用梯度下降的方法得到新的D,从而得到新段落的向量表达。
2.2:PV-DBOW
还有一种训练方法是忽略输入的上下文,让模型去预测段落中的随机一个单词。就是在每次迭代的时候,从文本中采样得到一个窗口,再从这个窗口中随机采样一个单词作为预测任务,让模型去预测,输入就是段落向量。如下所示:
2.3:和word2vec区别
Doc2vec相对于word2vec不同之处在于,在输入层,增添了一个新句子向量Paragraph vector,Paragraph vector可以被看作是另一个词向量,它扮演了一个记忆,它每次训练也是滑动截取句子中一小部分词来训练,Paragraph Vector在同一个句子的若干次训练中是共享的,所以同一句话会有多次训练,每次训练中输入都包含Paragraph vector。它可以被看作是句子的主旨,有了它,该句子的主旨每次都会被放入作为输入的一部分来训练。这样每次训练过程中,不光是训练了词,得到了词向量。同时随着一句话每次滑动取若干词训练的过程中,作为每次训练的输入层一部分的共享Paragraph vector,该向量表达的主旨会越来越准确。
2.4:预测新文本的向量
训练完了以后,就会得到训练样本中所有的词向量和每句话对应的句子向量,那么Doc2vec是怎么预测新的句子Paragraph vector呢?其实在预测新的句子的时候,还是会将该Paragraph vector随机初始化,放入模型中再重新根据随机梯度下降不断迭代求得最终稳定下来的句子向量。不过在预测过程中,模型里的词向量还有投影层到输出层的softmax weights参数是不会变的,这样在不断迭代中只会更新Paragraph vector,其他参数均已固定,只需很少的时间就能计算出带预测的Paragraph vector。
三:代码实战
3.1:接口介绍
1.dm=1 PV-DM dm=0 PV-DBOW。
2.size 所得向量的维度。
3.window 上下文词语离当前词语的最大距离。
4.alpha 初始学习率,在训练中会下降到min_alpha。
5.min_count 词频小于min_count的词会被忽略。
6.max_vocab_size 最大词汇表size,每一百万词会需要1GB的内存,默认没有限制。
7.sample 下采样比例。
8.iter 在整个语料上的迭代次数(epochs),推荐10到20。
9.hs=1 hierarchical softmax ,hs=0(default) negative sampling。
10.dm_mean=0(default) 上下文向量取综合,dm_mean=1 上下文向量取均值。
11.dbow_words:1训练词向量,0只训练doc向量。
3.2:主要代码
#定义模型:
model = Doc2Vec(dm=1, min_count=1, window=3, size=size, sample=1e-3, negative=5)
#训练模型:
model.train(x_train, total_examples=model_dm.corpus_count, epochs=epoch_num)
#保存模型:
model.save('model/model_my.model')
#使用infer_vector来推理文档的向量 (输入text仍然是文档的分词列表):
vector = model.infer_vector(text)
#使用model.docvecs[tag]得到已训练文档的向量。得到与输入文档相似度最高的十个文档:
sims = model.docvecs.most_similar([vector], topn=10)
来源:CSDN
作者:I am stupid
链接:https://blog.csdn.net/zhongqiqianga/article/details/103764150