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)

sim
训练完成保存的模型,之后可以直接载入进行使用
相似度计算采用余弦相似度
yuxian

使用函数matutils.unitvec() 将向量长度缩放为1,因此直接计算向量的点积就得到了相似度
test.txt里有7篇文章的摘要,最后的相似度计算是我在最后一篇文章截取的一段文字与7篇摘要分别进行计算的结果


lqxstars
14 声望1 粉丝

引用和评论

0 条评论