doc2vec
Doc2vec 办法是一种无监督算法,能从变长的文本(例如:句子、段落或文档)中学习失去固定长度的特色示意。Doc2vec 也能够叫做 Paragraph Vector、Sentence Embeddings,它能够取得句子、段落和文档的向量表白,是 Word2Vec 的拓展,其具备一些长处,比方不必固定句子长度,承受不同长度的句子做训练样本。
简略来说就是先用大量文本进行训练失去模型,之后用模型就能够将任意一段文本转为向量。有了向量,能力进行类似度的计算。
gensim 里有现成的 doc2vec,间接拿来应用就行
gensim 的应用
import os
import gensim
import smart_open
import logging
import sqlite3
logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)
def read_db3(fname):
conn = sqlite3.connect(fname)
cur = conn.cursor()
cur.execute('select lngid,description from modify_title_info_zt where description !=""')
outtext = cur.fetchone()
while outtext:
tokens = gensim.utils.simple_preprocess(outtext[1])
yield gensim.models.doc2vec.TaggedDocument(tokens, outtext[0])
outtext = cur.fetchone()
train_corpus = list(read_db3('zt_aipjournal_20210615_1.db3'))
下面的代码非常简单,将 db3 中的 description 字段进行小写化、去掉符号、分词失去用来训练的语料
model = gensim.models.doc2vec.Doc2Vec(vector_size=100, min_count=2, epochs=10,workers=4)
model.build_vocab(train_corpus)
model.train(train_corpus, total_examples=model.corpus_count, epochs=model.epochs)
model.save('aip.model')
vector_size 向量的维数,默认 100
min_count 去掉词频小于设定值的词
epochs 迭代次数 默认 10 次
workers 训练的过程数
训练实现后保留模型,供之后应用。
下面的语料有 18 万个文档,100 维的模型训练工夫用了 500 秒,训练 300 维的模型用了 750 秒
def read_corpus(fname, tokens_only=False):
with smart_open.open(fname, encoding="utf8") as f:
for i, line in enumerate(f):
tokens = gensim.utils.simple_preprocess(line)
if tokens_only:
yield tokens
else:
# For training data, add tags
yield gensim.models.doc2vec.TaggedDocument(tokens, [i])
test_corpus = list(read_corpus('test.txt', tokens_only=True))
new_model = gensim.models.doc2vec.Doc2Vec.load('aip.model')
vectorlist = []
for i in range (len(test_corpus)):
vectorlist.append(new_model.infer_vector(test_corpus[i]))
import numpy as np
from gensim import matutils
line = 'Three hundred thirty-one Chinese school children on Taiwan were given an aqueous oil trachoma vaccine and 322 an aqueous oil placebo'
vector = new_model.infer_vector(gensim.utils.simple_preprocess(line))
for i in range(0,7):
similarity = np.dot(matutils.unitvec(vector), matutils.unitvec(vectorlist[i]))
print(similarity)
训练实现保留的模型,之后能够间接载入进行应用
类似度计算采纳余弦类似度
应用函数 matutils.unitvec() 将向量长度缩放为 1,因而间接计算向量的点积就失去了类似度
test.txt 里有 7 篇文章的摘要,最初的类似度计算是我在最初一篇文章截取的一段文字与 7 篇摘要别离进行计算的后果