向量化算法 doc2vec

第1关:认识 Doc2vec

Doc2vec 算法简介

Doc2vec 又叫做 Paragraph2vec, Sentence embeddings,是一种非监督式算法,可以获得句子、段落、文档的向量表达,是 Word2vec 的拓展。学出来的向量可以通过计算距离来找句子、段落、文档之间的相似性,可以用于文本聚类,对于有标签的数据,还可以用监督学习的方法进行文本分类,例如经典的情感分析问题。

与 Word2vec 一样,Doc2Vec 有两种模型,分别为:Distributed Memory(DM)和 Distributed Bag of Words(DBOW)。DM 模型在给定上下文和文档向量的情况下预测单词的概率,DBOW 模型在给定文档向量的情况下预测文档中一组随机单词的概率。其中,在一个文档的训练过程中,文档向量共享,也就意味着在预测单词的概率时,都利用了整个文档的语义。

Doc2vec 算法模型

1、DM 模型 DM 模型在训练时,首先将每个文档的 ID 和语料库中的所有词初始化一个 K 维的向量,然后将文档向量和上下文词的向量输入模型,隐藏层将这些向量累加(或取均值、或直接拼接起来)得到中间向量,作为输出层 softmax 的输入。在一个文档的训练过程中,文档 ID 保持不变,共享着同一个文档向量,相当于在预测单词的概率时,都利用了整个句子的语义。DM 模型的结构如图1所示。

图 1 DM 模型

使用 gensim 实现 DM 模型: model = gensim.models.Doc2Vec(documents,dm = 1, alpha=0.1, size= 20, min_alpha=0.025)

函数的各个参数的具体含义为:

  • sentences 指代供训练的句子,可以使用简单的列表,但是对于大语料库,建议直接从磁盘/网络流迭代传输句子;

  • alpha 代表初始学习率;

  • size 表示向量的维度;

  • min_alpha 表示随着训练的进行,学习率线性下降到 min_alpha。

2、DBOW 模型 DBOW 模型的输入是文档的向量,预测的是该文档中随机抽样的词。这种模型的训练方法是忽略输入的上下文,让模型去预测段落中的随机一个单词,在每次迭代的时候,从文本中采样得到一个窗口,再从这个窗口中随机采样一个单词作为预测任务,让模型去预测,输入就是段落向量。

图 2 DBOW 模型

使用 gensim 实现 DBOW 模型: model = gensim.models.Doc2Vec(documents,dm = 0, alpha=0.1, size= 20, min_alpha=0.025)

第2关:Doc2vec 实战

Doc2vec 步骤简介

Doc2Vec 的目的是获得文档的一个固定长度的向量表达。在我们获得 Doc2Vec 模型之前,我们首先需要准备好数据,即多个文档,以及它们的标签(可以用标题作为标签)。

Doc2vec 算法的过程,主要有两步:

  1. 训练模型:在已知的训练数据中得到词向量 W ,softmax,以及段落向量/句向量;

  2. 推断过程:对于新的段落,得到其向量表达。在这个阶段中,可以呈现新文档,并且固定所有权重以计算文档向量。

其中,影响模型准确率的因素主要有:语料的大小,文档的数量,越多越高;文档的相似性,越相似越好。

Doc2vec 具体步骤

1、创建 Doc2vec

首先,我们使用 Gensim 的 Doc2Vec 创建一个模型,以备后面的训练。

复制代码
  1. import gensim
  2. LabeledSentence = gensim.models.doc2vec.LabeledSentence

我们需要先把所有文档的路径存进一个 array 中,以便后面读取文档数据。

复制代码
  1. from os import listdir
  2. from os.path import isfile, join
  3. docLabels = []
  4. docLabels = [f for f in listdir("myDirPath") if f.endswith('.txt')] # 将文件路径存入array

把所有文档的内容存入到 data 中:

复制代码
  1. data = []
  2. for doc in docLabels: # 将数据存入到data
  3. data.append(open("myDirPath/" + doc, 'r')

2、准备数据

如果是用句子集合来训练模型,我们可以:

复制代码
  1. class LabeledLineSentence(object):
  2. def __init__(self, filename):
  3. self.filename = filename
  4. def __iter__(self):
  5. for uid, line in enumerate(open(filename)):
  6. yield LabeledSentence(words=line.split(), labels=['SENT_%s' % uid])

在 gensim 中模型是以单词为单位训练的,所以不管是句子还是文档都得分解成单词。

3、训练模型,并保存以便使用

复制代码
  1. it = LabeledLineSentence(data, docLabels)
  2. model = gensim.models.Doc2Vec(size=300, window=10, min_count=5, workers=11,alpha=0.025, min_alpha=0.025) # 创建模型
  3. model.build_vocab(it)
  4. for epoch in range(10):
  5. model.train(it)
  6. model.alpha -= 0.002 # 降低学习率
  7. model.min_alpha = model.alpha # 调整学习率
  8. model.train(it)
  9. model.save("doc2vec.model") # 保存模型作为后续使用
编程要求

在右侧编辑器中的 Begin-End 之间补充 Python 代码,完成 Doc2vec 的模型训练过程,并保存模型。其中,训练集已由系统给出,文本内容通过 input 从后台获取。

测试说明

平台将使用测试集运行你编写的程序代码,若全部的运行结果正确,则通关。

测试输入: 自己

预期输出: [('可以', 0.999948263168335)] Congratulate!

from gensim.models.doc2vec import Doc2Vec,TaggedDocument
import pandas as pd
def D2V():
    article = pd.read_excel('data.xlsx') #data为训练集,繁体
    sentences = article['内容'].tolist()
    split_sentences = []
    
    for i in sentences:
        split_sentences.append(i.split(' '))
    documents = [TaggedDocument(doc, [i]) for i, doc in enumerate(split_sentences)]
# 任务:基于 gensim 构建 doc2vec 模型并命名为doc2vec_stock进行保存
# ********** Begin *********#
   
    model = Doc2Vec(documents, size=500, window=5, min_count=5, workers=4, epoch=5000)
    model.save("doc2vec_stock.model") 
# ********** End **********#
相关推荐
算法歌者8 分钟前
[算法]入门1.矩阵转置
算法
林开落L23 分钟前
前缀和算法习题篇(上)
c++·算法·leetcode
远望清一色24 分钟前
基于MATLAB边缘检测博文
开发语言·算法·matlab
tyler_download25 分钟前
手撸 chatgpt 大模型:简述 LLM 的架构,算法和训练流程
算法·chatgpt
SoraLuna1 小时前
「Mac玩转仓颉内测版7」入门篇7 - Cangjie控制结构(下)
算法·macos·动态规划·cangjie
我狠狠地刷刷刷刷刷1 小时前
中文分词模拟器
开发语言·python·算法
鸽鸽程序猿1 小时前
【算法】【优选算法】前缀和(上)
java·算法·前缀和
九圣残炎1 小时前
【从零开始的LeetCode-算法】2559. 统计范围内的元音字符串数
java·算法·leetcode
YSRM1 小时前
Experimental Analysis of Dedicated GPU in Virtual Framework using vGPU 论文分析
算法·gpu算力·vgpu·pci直通
韭菜盖饭2 小时前
LeetCode每日一题3261---统计满足 K 约束的子字符串数量 II
数据结构·算法·leetcode