Doc2vec段落向量的训练方法,与训练词向量类似,段落向量的训练分为训练数据预处理和段落向量训练两个步骤。这里采用的是网上爬取的问答对中的query作为训练集,在段落向量训练之前必须进行训练数据预处理:中文分词,这里采用的是jieba分词。此外doc2vec在训练的时候能够采用tag信息来更好的辅助训练(表明是同一类doc),因此相对于word2vec模型,输入文档多了一个tag属性。
具体代码如下所示。这里解释一下doc2vec函数里各个参数的意思:
用到的Doc2vec的功能主要有三个:
1.TaggedDocument语料预处理
2.train训练模型,save 和 load 加载训练好的模型
3.docvecs.most_similar 计算相似度
数据预处理,训练段落向量
import gensim
from gensim.models.doc2vec import Doc2Vec, LabeledSentence
TaggededDocument = gensim.models.doc2vec.TaggedDocument
def get_datasest():
with open("train_after_process.txt", 'r', encoding='utf-8') as cf:
docs = cf.readlines()
print(len(docs))
x_train = []
# y = np.concatenate(np.ones(len(docs)))
for i, text in enumerate(docs):
word_list = text.split(' ')
l = len(word_list)
word_list[l - 1] = word_list[l - 1].strip()
document = TaggededDocument(word_list, tags=[i])
x_train.append(document)
return x_train
# def getVecs(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, size=200, epoch_num=1):
model_dm = Doc2Vec(x_train, min_count=1, window=3, size=size, sample=1e-3, negative=5, workers=4)
model_dm.train(x_train, total_examples=model_dm.corpus_count, epochs=70)
model_dm.save('model/model_dm_jiedai')
if __name__ == '__main__':
x_train = get_datasest()
model_dm = train(x_train)
加载训练好的模型并进行文本相似度计算:
和word2vec计算相似度类似,doc2vec计算文本相似度也主要包括如下三个步骤:数据预处理、文档向量化、计算文本相似。
详细代码如下所示,在doc2vec函数中,首先就是数据预处理操作,采用jieba分词对输入的句子进行分词(这里直接输入的文本格式是已经分好的,而且没有加入自定义词典);然后对句子向量化操作,通过加载训练好的模型,迭代找出合适的向量来代表文本。采用余弦相似度来进行向量相似度计算。最后经过相似度计算得到前10个最相似的句子。
import gensim
from gensim.models.doc2vec import Doc2Vec, LabeledSentence
TaggededDocument = gensim.models.doc2vec.TaggedDocument
def get_datasest():
with open("train_after_process.txt", 'r',encoding='utf-8') as cf:
docs = cf.readlines()
print(len(docs))
x_train = []
# y = np.concatenate(np.ones(len(docs)))
for i, text in enumerate(docs):
word_list = text.split(' ')
l = len(word_list)
word_list[l - 1] = word_list[l - 1].strip()
document = TaggededDocument(word_list, tags=[i])
x_train.append(document)
return x_train
def test():
model_dm = Doc2Vec.load("model/model_dm_jiedai")
test_text = ['朋友', '借', '了','钱', '不','还','怎么办']
#句子向量化操作
inferred_vector_dm = model_dm.infer_vector(test_text)
print(inferred_vector_dm)
sims = model_dm.docvecs.most_similar([inferred_vector_dm], topn=10)
return sims
if __name__ == '__main__':
x_train = get_datasest()
sims = test()
for count, sim in sims:
sentence = x_train[count]
words = ''
for word in sentence[0]:
words = words + word + ' '
print(words, sim, len(sentence[0]))
测试结果:
小结:
通过实践,对于word2vec和doc2vec两种计算文本相似度的方法,一般对长文本语料进行训练时,采用doc2vec计算文本相似度的方法更胜一筹(由于语料限制,采用的是短文本语料训练的,结果不是很明显)。因为doc2vec不仅利用了词语的语义信息而且还综合了上下文语序的信息,而word2vec则通过向量相加求平均丢失了语序信息;word2vec计算长文本相似度时,关键词提取算法准确度不高,丢失了很多关键信息。
参考:http://linanqiu.github.io/2015/10/07/word2vec-sentiment/
上篇:向量化算法Doc2vec/str2vec/para2vec原理详解