转载自:| 01_word_embedding/04_Doc2Vec.ipynb | 基于gensim使用Doc2Vec模型 |Open In Colab |
Doc2Vec
上一节讲了Word2Vec可以用来训练词向量,那么句子向量怎么训练呢?
那这一节就看下如何训练句向量。
构建句子向量有比较多的方法,比较流行的是:
- bag-of-words词袋模型
- 基于word2vec计算句子中各个词语的词向量,然后加和平均得到句子向量
- 使用doc2vec训练句向量模型
说下这几个模型的优缺点:
-
词袋模型
词袋模型存在两个主要的缺点:一个是词袋模型忽略词序,如果两个不同的句子由相同的词但是顺序不同组成,词袋模型会将这两句话定义为同一个表达;另一个是词袋模型忽略了句法,这样训练出来的模型会造成类似'powerful','strong'和'Paris'的距离是相同的,而其实'powerful'应该相对于'Paris'距离'strong'更近才对。
-
word2vec
比较简单,没有考虑句子词语之间的相互语义关系,我写过一个开源实现:text2vec
-
doc2vec
本节的重点,下面介绍doc2vec模型。
Doc2vec又叫Paragraph Vector是Tomas Mikolov基于word2vec模型提出的,其具有一些优点,比如不用固定句子长度,接受不同长度的句子做训练样本,Doc2vec是一个无监督学习算法,该算法用于预测一个向量来表示不同的文档,该模型的结构潜在的克服了词袋模型的缺点。
Doc2vec也有两种训练方式,一种是PV-DM(Distributed Memory Model of paragraph vectors)类似于word2vec中的CBOW模型,另一种是PV-DBOW(Distributed Bag of Words of paragraph vector类似于Word2vec中的skip-gram模型。
python
import numpy as np
from gensim.models.doc2vec import Doc2Vec, TaggedDocument
def get_datasest():
with open("data/C000008_test.txt", 'r', encoding='utf8') as cf:
docs = cf.readlines()
print('docs size:', len(docs))
x_train = []
for i, text in enumerate(docs):
word_list = text.split()
l = len(word_list)
word_list[l - 1] = word_list[l - 1].strip()
document = TaggedDocument(word_list, tags=[i])
x_train.append(document)
return x_train
def get_vecs(model, corpus, size):
vecs = [np.array(model.docvecs[z.tags[0]].reshape(1, size))
for z in corpus]
return np.concatenate(vecs)
def train(x_train):
model_dm = Doc2Vec(x_train, min_count=1, window=3,
sample=1e-3, negative=5, workers=4)
model_dm.train(x_train, total_examples=model_dm.corpus_count, epochs=70)
model_dm.save('model_dm')
return model_dm
def infer(test_text):
model_dm = Doc2Vec.load("model_dm")
infer_vector_dm = model_dm.infer_vector(test_text)
sims = model_dm.dv.most_similar([infer_vector_dm], topn=10)
return sims
python
x_train = get_datasest()
x_train[:1]
python
model_dm = train(x_train)
model_dm
python
test_text = ['上海', '国外', '媒体', '昨日', '报道', '澳大利亚', '银行', 'acq',
'开发商', '行列', '竟是', '金融机构', '项目', '投融资', '资本运作', ]
sims = infer(test_text)
sims
python
for index, sim_score in sims:
sentence = x_train[index]
words = ''
for word in sentence[0]:
words = words + word + ' '
print(sim_score, words)
python
import os
os.remove('model_dm')