一,原理
其训练原理与word2vec很相似。主要的不同如下:
每次从一句话中滑动采样固定长度的词,取其中一个词作为预测词,其他词作为输入。在输入层,增添了一个新句子向量Paragraph vector,Paragraph vector可以被看作是另一个词向量,它扮演了一个记忆,每次训练滑动截取句子中一小部分词来训练,Paragraph Vector在同一个句子的若干次训练中是共享的,所以同一句话会有多次训练,每次训练中输入都包含Paragraph vector。它可以被看作是句子的主旨,有了它,该句子的主旨每次都会被放入作为输入的一部分来训练。这样每次训练过程中,不光是训练了词,得到了词向量。同时随着一句话每次滑动取若干词训练的过程中,作为每次训练的输入层一部分的共享Paragraph vector,该向量表达的主旨会越来越准确。
在预测新的句子的时候,会先将该Paragraph vector随机初始化,放入模型中再重新根据随机梯度下降不断迭代求得最终稳定下来的句子向量。不过在预测过程中,模型里的词向量还有投影层到输出层的softmax weights参数是不会变的,这样在不断迭代中只会更新Paragraph vector,其他参数均已固定,只需很少的时间就能计算出带预测的Paragraph vector。
二,测试demo
代码如下:
from gensim.test.utils import common_texts
from gensim.models.doc2vec import Doc2Vec, TaggedDocument
def doc2vec_demo():
# 得到文本训练数据
documents = [TaggedDocument(doc, [i]) for i, doc in enumerate(common_texts)]
# 训练模型
model = Doc2Vec(documents, vector_size=5, window=2, min_count=1, workers=4)
print(len(documents))
print(documents[0:4])
# 获取与tag为0的向量最相似的数据
sims = model.docvecs.most_similar(0)
print(sims)
# 计算tag 0,2两者之间的距离
print(model.docvecs.similarity(0,2))
# 获取tag 4的向量
print(model.docvecs[4])
输出结果为:
9
[TaggedDocument(words=['human', 'interface', 'computer'], tags=[0]), TaggedDocument(words=['survey', 'user', 'computer', 'system', 'response', 'time'],
tags=[1]), TaggedDocument(words=['eps', 'user', 'interface', 'system'], tags=[2]), TaggedDocument(words=['system', 'human', 'system', 'eps'], tags=[3])]
[(2, 0.38414308428764343), (8, 0.3346472680568695), (4, 0.1297619640827179), (3, 0.05100887268781662), (7, -0.03428802639245987),
(5, -0.20345287024974823), (6, -0.45190441608428955), (1, -0.5631040930747986)]
0.38414308
[-0.0676489 -0.025297 -0.0700455 0.01598585 0.02966787]
三,利用wiki数据训练英文doc2vec
先将wiki文件下载下来,将wiki文件编码转化等。
然后训练数据;
最后测试。
https://radimrehurek.com/gensim/models/doc2vec.html
参考链接:https://blog.youkuaiyun.com/kan2281123066/article/details/83451151
https://cloud.tencent.com/developer/news/211889
代码:https://github.com/2281123066/doc2vec
补充在执行代码之前要保证在toy_data/文件夹下有wiki_en.txt文件和model文件夹。