Doc2Vec模型的介绍与gensim中Doc2Vec的使用

article/2025/8/23 19:55:30

文章目录

      • 一、Doc2Vec模型
        • 1 、PV-DM
        • 2 、PV-DBOW
      • 二、gensim实现
        • 1、gensim实现Doc2Vec(IMDB数据集)
        • 2、gensim实现Doc2Vec(中文数据集)
      • 三、总结
      • 四、程序编写时遇到的错误:
      • gensim包中相关函数说明:
    • 参考资料:

一、Doc2Vec模型

  许多机器学习算法需要的输入是一个固定长度的向量,当涉及到短文时,最常用的固定长度的向量方法是词袋模型(bag-of-words)。尽管它很流行,但是词袋模型存在两个主要的缺点:一个是词袋模型忽略词序,如果两个不同的句子由相同的词但是顺序不同组成,词袋模型会将这两句话定义为同一个表达;另一个是词袋模型忽略了语义,这样训练出来的模型会造成类似’powerful’,'strong’和’Paris’的距离是相同的,而其实’powerful’应该相对于’Paris’距离’strong’更近才对。

  Doc2vec又叫Paragraph Vector是Tomas Mikolov基于word2vec模型提出的,其具有一些优点,比如不用固定句子长度,可以接受不同长度的句子做训练样本,Doc2vec是一个无监督学习算法,该算法用于向量来表示文档,该模型的结构潜在的克服了词袋模型的缺点。

  另外,word2vec预测词向量时,预测出来的词是含有词义的,比如上文提到的词向量’powerful’会相对于’Paris’离’strong’距离更近,在Doc2vec中也构建了相同的结构。所以Doc2vec克服了词袋模型中没有语义的去缺点。假设现在存在训练样本,每个句子是训练样本。


1 、PV-DM

  Doc2vec有两种训练方式,一种是PV-DM(Distributed Memory Model of paragraphvectors)类似于word2vec中的CBOW模型,如下图

在这里插入图片描述

图:PV-DM模型

  PV-DM模型,每次从一句话中滑动采样固定长度的词,取其中一个词作预测词,其他的作输入词。输入词对应的词向量word vector和本句话对应的句子向量Paragraph vector作为输入层的输入,将本句话的向量和本次采样的词向量相加求平均或者累加构成一个新的向量X,进而使用这个向量X预测此次窗口内的预测词。

  Doc2vec相对于word2vec不同之处在于,在输入层,增添了一个新句子向量Paragraph vector,Paragraph vector可以被看作是另一个词向量,它扮演了一个记忆。词袋模型中,因为每次训练只会截取句子中一小部分词训练,而忽略了除了本次训练词以外该句子中的其他词,这样仅仅训练出来每个词的向量表达,句子只是每个词的向量累加在一起表达的。正如上文所说的词袋模型的缺点,忽略了文本的词序问题。而Doc2vec中的Paragraph vector则弥补了这方面的不足,它每次训练也是滑动截取句子中一小部分词来训练,Paragraph Vector在同一个句子的若干次训练中是共享的,所以同一句话会有多次训练,每次训练中输入都包含Paragraph vector。它可以被看作是句子的主旨,有了它,该句子的主旨每次都会被放入作为输入的一部分来训练。这样每次训练过程中,不光是训练了词,得到了词向量。同时随着一句话每次滑动取若干词训练的过程中,作为每次训练的输入层一部分的共享Paragraph vector,该向量表达的主旨会越来越准确。Doc2vec中PV-DM模型具体的训练过程和word2vec中的CBOW模型训练方式相同,都是采用随机梯度下降来进行优化模型的参数的。

  训练完,就会得到训练样本中所有的词向量和每句话对应的句子向量,那么Doc2vec是怎么预测新的句子Paragraph vector呢?其实在预测新的句子的时候,还是会将该Paragraph vector随机初始化,放入模型中再重新根据随机梯度下降不断迭代求得最终稳定下来的句子向量。不过在预测过程中,模型里的词向量还有投影层到输出层的softmax weights参数是不会变的,这样在不断迭代中只会更新Paragraph vector,其他参数均已固定,只需很少的时间就能计算出带预测的Paragraph vector。


2 、PV-DBOW

  Paragraph Vector的另一种模型是PV-DBOW(Distributed Bag of Words of paragraph vector)类似于word2vec中的skip-gram模型,如下图:
在这里插入图片描述

图:PV-DBOW模型

  该模型原理和PV-DM模型相同,但是该模型的输入是paragraph id的句向量,在随机梯度下降的每一次迭代中采样一个文本窗口(text window),再从该文本窗口中随机采样一个词,从而形成一个给定段落向量进行词预测的多分类任务。该模型和Skip-gram模型相似。

二、gensim实现

1、gensim实现Doc2Vec(IMDB数据集)

  使用Doc2Vec进行分类任务,我们使用 IMDB电影评论数据集作为分类例子,测试gensim的Doc2Vec的有效性。数据集中包含25000条正向评价,25000条负面评价以及50000条未标注评价。

2、gensim实现Doc2Vec(中文数据集)

  在python中gensim包就很好的实现了Doc2vec,我们调用使用方便快捷,在这简单演示下。
1、数据集:从网上下载的“基于社交媒体的海南旅游景区评价数据集”。另外停用词表也是从网上下载的。
下载地址为:http://www.sciencedb.cn/dataSet/handle/714
  因为数据集是分布在多个excel文件中的,所以我编写了函数get_file_data_to_a_file(),将美团文件夹下的前4个文件中的数据合并到一个excel文件train_excel.xlsx中。共7319条数据。代码如下:

# -*- coding: utf-8 -*-import xlrd
import xlsxwriter
import osdef get_file_data_to_a_file(path):'''读取文件路径下的所有文件到一个文件路径列表中,并依次读取每个文件中的数据最后将所有数据保存到一个文件中'''paths = os.listdir(path)file_paths = []for file_name in paths:if os.path.splitext(file_name)[1] == ".xlsx":file_paths.append(path+file_name)rvalues =[]for i, file in enumerate(file_paths): #遍历文件列表pathsfh = xlrd.open_workbook(file) #打开一个excel文件
#            sheet_name = os.path.splitext(file_name)[0]table = fh.sheets()[0] #获取excel文件的第一个sheet表num_rows = table.nrows #该表的的所有行数for row in range(num_rows):rdata=table.row_values(row) #获取每一行的数据rvalues.append(rdata)endfile='train_excel.xlsx'wb1=xlsxwriter.Workbook(endfile)ws=wb1.add_worksheet() #添加一个新的工作表for a in range(len(rvalues)):for b in range(len(rvalues[a])):c=rvalues[a][b]ws.write(a,b,c)wb1.close()print("文件合并完成")if __name__ == "__main__":get_file_data_to_a_file("./meituan/")

2、具体的Doc2vec训练Paragraph vector步骤如下:

步骤1:导入数据集,提取comment列(该列是用户评价的内容)。

def getText(path):df_train = pd.read_excel('train_excel.xlsx')comment_train = list(df_train['comment'].astype(str))return comment_traintext = getText("./")
print(text[0:10]) #打印前10行数据

运行结果如下:
在这里插入图片描述
步骤2:将提取好的comment列中的内容进行分词,并去除停用词。

def cut_sentence(text):stop_list = [line[:-1] for line in open("中文停用词表.txt",encoding='gb18030', errors='ignore')]result = []for each in text:each_cut = jieba.cut(each)each_split = ' '.join(each_cut).split()each_result = [word for word in each_split if word not in stop_list] #去除停用词result.append(' '.join(each_result))return resultb = cut_sentence(text)
print(b[0:10])

运行结果如下:
在这里插入图片描述
步骤3:改变成Doc2vec所需要的输入样本格式,由于gensim里Doc2vec模型需要的输入为固定格式,输入样本为:[句子,句子序号],这里需要用gensim中Doc2vec里的TaggedDocument来包装输入的句子。

TaggededDocument=gensim.models.doc2vec.TaggedDocumentdef X_train(cut_sentence):x_train = []for i, text in enumerate(cut_sentence):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_trainc = X_train(b)
print(c[0:10])

运行结果如下:
在这里插入图片描述
步骤4:加载Doc2vec模型,并开始训练。

def train(x_train, size=300):model = Doc2Vec(x_train,min_count=1,window=3,size=size,sample=1e-3,negative=5,workers=4)model.train(x_train,total_examples=model.corpus_count,epochs=10)return modelmodel_dm = train(c)

步骤5:模型训练完毕以后,就可以预测新的句子的向量Paragraph vector了,这里用gensim里Doc2Vec.infer_vector()预测新的句子,这里根据经验,alpha(学习步长)设置小一些,迭代次数设置大一些。找到训练样本中与这个句子最相近的10个句子。可以看到训练出来的结果与测试的新句子是有关联的。

#str1 = u'这里 的 演出 真的 很 棒 !'
str1 = u'一点 都 不 好玩'
test_text = str1.split(' ')
inferred_vector = model_dm.infer_vector(doc_words=test_text,alpha=0.025,steps=300)sims = model_dm.docvecs.most_similar([inferred_vector],topn=10)
for count,sim in sims:sentence = text[count]words = ''for word in sentence:words = words + word + ' 'print(words, sim, len(sentence))

运行结果如下:
在这里插入图片描述
从结果可以看出,预测的相似的句子还是有一定的可信度的。

三、总结

  Doc2vec是基于Word2vec基础上构建的,相比于Word2vec,Doc2vec不仅能训练处词向量还能训练处句子向量并预测新的句子向量。Doc2vec模型结构相对于Word2vec,不同点在于在输入层上多增加了一个Paragraph vector句子向量,该向量在同一句下的不同的训练中是权值共享的,这样训练出来的Paragraph vector就会逐渐在每句子中的几次训练中不断稳定下来,形成该句子的主旨。这样就训练出来了我们需要的句子向量。在预测新的句子向量时,是需要重新训练的,此时该模型的词向量和投影层到输出层的soft weights参数固定,只剩下Paragraph vector用梯度下降法求得,所以预测新句子时虽然也要放入模型中不断迭代求出,相比于训练时,速度会快得多。本次使用的数据集为情感分析,且大多数样本偏向于好评,样本内容比较单一,所以训练出来的结果都是偏向于哪里好玩,好不好这类的意思,对于一些特定的问题之类的句子准确性还没有验证,目前用于情感分析还是可以的。下次会尝试使用新的数据集,调试参数看是否会取得更好的结果。

四、程序编写时遇到的错误:

  1. 通过python读取停用词表文本内容时,出现如下错误:
    在这里插入图片描述
    解决方法:
    使用‘ignore’属性忽略非法字符,如:
    在这里插入图片描述
  2. jieba分词出现如下错误:AttributeError: ‘float’ object has no attribute ‘decode’
    解决方法:
    在这里插入图片描述

gensim包中相关函数说明:

gensim.models.doc2vec.Doc2Vec(
documents=None, 
size=300, 
alpha=0.025, 
window=8, 
min_count=5, 
max_vocab_size=None, 
sample=0,
seed=1, 
workers=1, 
min_alpha=0.0001, 
dm=1, 
hs=1, 
negative=0, 
dbow_words=0, 
dm_mean=0, 
dm_concat=0, 
dm_tag_count=1, 
docvecs=None,
docvecs_mapfile=None, 
comment=None, 
trim_rule=None, 
**kwargs)
  • size 是特征向量的纬度。

  • window 是要预测的词和文档中用来预测的上下文词之间的最大距离。

  • alpha 是初始化的学习速率,会随着训练过程线性下降。

  • seed 是随机数生成器。.需要注意的是,对于一个完全明确的重复运行(fully deterministically-reproducible run),你必须同时限制模型单线程工作以消除操作系统线程调度中的有序抖动。(在python3中,解释器启动的再现要求使用PYTHONHASHSEED环境变量来控制散列随机化)

  • min_count 忽略总频数小于此的所有的词。

  • max_vocab_size 在词汇累积的时候限制内存。如果有很多独特的词多于此,则将频率低的删去。每一千万词类大概需要1G的内存,设为None以不限制(默认)。

  • sample 高频词被随机地降低采样的阈值。默认为0(不降低采样),较为常用的事1e-5。

  • dm 定义了训练的算法。默认是dm=1,使用 ‘distributed memory’ (PV-DM),否则 distributed bag of words (PV-DBOW)。

  • workers 使用多少现成来训练模型(越快的训练需要越多核的机器)。

  • iter 语料库的迭代次数。从Word2Vec中继承得到的默认是5,但在已经发布的‘Paragraph Vector’中,设为10或者20是很正常的。

  • hs 如果为1 (默认),分层采样将被用于模型训练(否则设为0)。

  • negative 如果 > 0,将使用负采样,它的值决定干扰词的个数(通常为5-20)。

  • dm_mean 如果为0(默认),使用上下文词向量的和;如果为1,使用均值。(仅在dm被用在非拼接模型时使用)

  • dm_concat 如果为1,使用上下文词向量的拼接,默认是0。注意,拼接的结果是一个更大的模型,输入的大小不再是一个词向量(采样或算术结合),而是标签和上下文中所有词结合在一起的大小。

  • dm_tag_count 每个文件期望的文本标签数,在使用dm_concat模式时默认为1。

  • dbow_words 如果设为1,训练word-vectors (in skip-gram fashion) 的同时训练 DBOW doc-vector。默认是0 (仅训练doc-vectors时更快)。

  • trim_rule 词汇表修建规则,用来指定某个词是否要被留下来。被删去或者作默认处理 (如果词的频数< min_count则删去)。可以设为None (将使用min_count),或者是随时可调参 (word, count, min_count) 并返回util.RULE_DISCARD,util.RULE_KEEP ,util.RULE_DEFAULT之一。注意:这个规则只是在build_vocab()中用来修剪词汇表,而且没被保存。

参考资料:

1、基于社交媒体的海南旅游景区评价数据集:http://www.sciencedb.cn/dataSet/handle/714
2、博客: https://yq.aliyun.com/articles/623606?spm=a2c4e.11153940.0.0.91a74a54EwRIda
3、gensim 官网: https://radimrehurek.com/gensim/models/doc2vec.html
4、论文《Distributed representations of sentences and documents 》


http://chatgpt.dhexx.cn/article/cxJH1uWT.shtml

相关文章

如何自学游戏引擎的开发?

PS&#xff1a;题猪分得清游戏和游戏引擎的区别&#xff0c;所以各位答主不需要劳神解释两者的区别关系什么的了 PS&#xff1a;这里的游戏引擎暂时指图形模块&#xff0c;其他的声音&#xff0c;物理&#xff0c;网络&#xff0c;UI等等模块暂时不考虑 题猪一直自学编程&#…

游戏开发完整学习路线(各个版本都有)

来自&#xff1a;微浪科技 作者&#xff1a;若朝若曦 在软件开发中&#xff0c;游戏开发这个方向看起来目标很明确&#xff0c;但其实是个领域很广的方向&#xff0c;入门的时候如果得不到指点一二&#xff0c;很容易误入歧途&#xff0c;相反&#xff0c;如果走这条路之前能…

智力开发小游戏集含游戏过程中数据存取-C#入门教学程序

对于初学C#程序开发的学员&#xff0c;一般进行采取开发小游戏程序&#xff0c;这样做首先不会让学员失去学习的兴趣&#xff0c;其次可以将C#中基本的控件与类的写法整合到这些游戏程序中&#xff0c;再次将对数据库的操作也教给学员。通过几年的观察这样的教学有它的好处。所…

游戏开发所需要的知识

从放弃求职回家已经一个半月了&#xff0c;一直都在备考事业编。发现这玩意比游戏开发简单太多了&#xff0c;没有人刁难&#xff0c;没有人催促&#xff0c;几个月举办一次&#xff0c;一天只需要学习3-4个小时&#xff0c;其余时间都是自由安排&#xff0c;太舒服了。考上编后…

零基础游戏开发笔记1——游戏开发流程

万事开头难&#xff0c;多学多练习&#xff0c;熟悉游戏开发的主要流程&#xff0c;莫要强行记忆。 首先&#xff0c;我们来了解一下游戏的开发流程。 第一就是立案&#xff0c;建立策划案。 策划案包含很多东西&#xff0c;包括游戏介绍、游戏内容、游戏模型介绍、游戏数值、…

游戏开发流程之完整指南

“现在&#xff0c;是时候改进您的游戏开发流程了。在这里&#xff0c;无论您是在独立的初创公司亦或大型游戏工作室中&#xff0c;我们都可以调度资源&#xff0c;使您的工作室的开发和设计工作晋升一个层次。” 您可以把本指引当做游戏开发流程改进的参考 我们将覆盖所有您…

游戏开发笔记(二)——开发流程和项目管理

前一篇说到分工&#xff0c;这里再说说流程和开发管理。 组织形式 从公司角度来看一个游戏工作室是一个业务比较独立的研发部门&#xff0c;研发方面的大小事务&#xff08;除了立项&#xff09;拥有高度自治权。而从一个工作室角度来看&#xff0c;通常内部又由多个项目组组成…

游戏开发 - 开发流程 - 收集

1.应用场景 主要用于了解&#xff0c;掌握游戏开发的整个流程。 2.学习/操作 1.文档阅读 复习课 | 带你梳理客户端开发的三个重点-极客时间 2.整理输出 2.1 游戏开发流程 -- 参考 按照游戏开发中的三大模块策划、程序、美术&#xff0c;画了一个图。 开发游戏的时候&#xf…

游戏开发完整流程

1. 立项 一个项目立项的原因可能性非常多&#xff0c;有可能是公司拿到一个好的IP&#xff0c;也有可能是几个负责人有个很棒的idea&#xff0c;亦或是老板的梦想是做一个XX类型的游戏&#xff0c;这边不做过多的讨论。 立项过程中应该包含市场调查和产品定位&#xff0c…

如何开发一款游戏?【游戏开发所需技能和开发流程】

开发一款游戏需要的技能包括&#xff1a;编程、设计、音效和项目管理。每个角色都需要掌握其特定领域的知识和技能&#xff0c;并与其他团队成员合作。在本文中&#xff0c;我们将深入探讨如何开发一款游戏。 1. 游戏开发流程 游戏开发流程可以分为以下几个阶段&#xff1a; …

如何开发一款游戏:游戏开发流程及所需工具

本文来自作者 goto先生 在 GitChat 上分享 「如何开发一款游戏&#xff1a;游戏开发流程及所需工具」 编辑 | 哈比 游戏作为娱乐生活的一个方面&#xff0c;参与其中的人越来越多&#xff0c;而大部分参与其中的人都是以玩家的身份。 他们热爱一款游戏&#xff0c;或是被游戏的…

文本识别CRNN模型介绍以及pytorch代码实现

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、CRNN模型介绍1.模型结构2.CTCLossbeam search 二、使用pytorch实现crnn数据集 前言 文本识别是图像领域的一个常见任务&#xff0c;场景文字识别OCR任务中…

crnn 学习笔记

常用文本识别算法有两种&#xff1a; CNNRNNCTC&#xff08;CRNNCTC&#xff09;CNNSeq2SeqAttention 其中CTC与Attention相当于是一种对齐方式&#xff0c;具体算法原理比较复杂&#xff0c;就不做详细的探讨。其中CTC可参考这篇博文&#xff0c;关于Attention机制的介绍&am…

智能驾驶 车牌检测和识别(三)《CRNN和LPRNet实现车牌识别(含车牌识别数据集和训练代码)》

智能驾驶 车牌检测和识别&#xff08;三&#xff09;《CRNN和LPRNet实现车牌识别&#xff08;含车牌识别数据集和训练代码&#xff09;》 目录 智能驾驶 车牌检测和识别&#xff08;三&#xff09;《CRNN和LPRNet实现车牌识别&#xff08;含车牌识别数据集和训练代码&#xf…

pytorch(11)-- crnn 车牌端到端识别

车牌图片端到端识别 一、前言二、数据集处理三、crnn模型文件四、训练验证代码五、测试代码六、代码搬自 一、前言 本文主要记录了使用crnn 对车牌图片做端到端识别&#xff0c;即不用对车牌字符做逐个字符分割识别&#xff0c;车牌第一个字符为汉字&#xff0c;共有31个&#…

CRNN 论文翻译

《An End-to-End Trainable Neural Network for Image-based Sequence Recognition and Its Application to Scene Text Recognition》论文翻译 摘要 基于图像的序列识别一直是计算机视觉中长期存在的研究课题。在本文中&#xff0c;我们研究了场景文本识别的问题&#xff0c;…

CRNN算法详解

《An End-to-End Trainable Neural Network for Image-based Sequence Recognition and Its Application to Scene Text Recognition》&#xff0c;是比较老的一篇文章了&#xff0c;在2015年6月发表在arxiv上&#xff0c;但是该方法还是被广泛运用。 文章思想&#xff1a;文章…

文本识别论文CRNN

目录 1. 解读文本识别论文CRNN1.1 CRNN文字识别整体流程1.2 理解CTC Loss1.2.1 CTC loss是如何做的1.2.2 以一个具体的例子来展现CTC loss的过程 2. 总结3. 参考资料 1. 解读文本识别论文CRNN 本文解读的是一篇来自2015年的一篇文字识别论文 [ 1 ] ^{[1]} [1]。里面的CTC Loss相…

opencv pytorch CRNN验证码识别

文章目录 前言&#xff1a;效果预览&#xff1a;搭建CRNN模型&#xff1a;验证码数据集制作&#xff1a;模型训练&#xff1a;项目结构与源码下载&#xff1a; 前言&#xff1a; 本文使用crnn网络识别验证码&#xff0c;使用的验证码数据集有三种&#xff0c;准确率都很高。 …

CRNN笔记

参考链接&#xff1a; 一文读懂CRNNCTC文字识别 - 知乎 CTC loss - 知乎 1、背景 文字识别主流的两种算法 1.1 基于CRNNCTC 1.2 基于CNNSeq2SeqAttention 2、CRNNCTC原理解析 CRNNCTC结构图 以下是根据paddleocr中以mobilenetv3为backbone的网络结构图 model …