文本多分类之Doc2Vec实战篇

article/2025/8/23 16:18:06

在我之前的几篇博客中,我介绍了两种文档向量化的表示方法,如Sklearn的CountVectorizer和TfidfTransformer,今天我们再来学习另外一种文档的向量化表示方法-Doc2Vec。如果你还不太了解Doc2Vec的话,我提供一些资料以便你可以对它有深入的了解:

  • Doc2Vec的简介及应用(gensim)
  • 基于gensim的Doc2Vec简析
  • 词语分布式表示及其组合性
  • 关于IMDB情感数据集的Gensim Doc2Vec教程
  • 使用word embeddings进行文档分类的教程

本文不会对Doc2Vec的原理进行深入的介绍,我们的目的在于“使用”和“实战”,如果想要深入了解Doc2Vec内部机制和原理可以参考我推荐的上述文档和教程。我们这次使的用数据来自于我上次的博客使用python和sklearn的中文文本多分类实战开发中使用的数据,不过这次我们不再使用CountVectorizer和TfidfTransformer,我们将使用Gensim的Doc2Vec技术对中文文本数据进行量化处理和文档多分类。好了,废话少说,让我们撸起袖子干起来吧!

数据

我们可以从这里下载数据,数据中包含了10 个类别(书籍、平板、手机、水果、洗发水、热水器、蒙牛、衣服、计算机、酒店),共 6 万多条评论数据 首先查看一下我们的数据,这些数据都是来自于电商网站的用户评价数据,我们最终的目的是把不同评价数据归类到不同的分类中去,且每条数据只能对应10个类中的一个类。

%matplotlib inline
import pandas as pd
import matplotlib
import numpy as np
import matplotlib.pyplot as plt
import jieba as jb
import re
from sklearn import utils
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from gensim.models.doc2vec import TaggedDocument
import multiprocessingdf = pd.read_csv('./data/shopping.csv')
df=df[['cat','review']]
print("数据总量: %d ." % len(df))
df.sample(10)

接下来我们还是要做一下数据清洗工作,删掉数据中的空值:

print("在 cat 列中总共有 %d 个空值." % df['cat'].isnull().sum())
print("在 review 列中总共有 %d 个空值." % df['review'].isnull().sum())
df[df.isnull().values==True]
df = df[pd.notnull(df['review'])]
df = df.reset_index(drop=True)

接下来我们统计一下各个类别的数据量:

d = {'cat':df['cat'].value_counts().index, 'count': df['cat'].value_counts()}
df_cat = pd.DataFrame(data=d).reset_index(drop=True)
print(df_cat)df_cat.plot(x='cat', y='count', kind='bar', legend=False,  figsize=(8, 5))
plt.title("类目数量分布")
plt.ylabel('数量', fontsize=18)
plt.xlabel('类目', fontsize=18)

 

我们看到各个类别的数据量不一致,洗发水、衣服、酒店、水果、平板的数据量最多各有1万条,而热水器的数据量最少只有574条,分布很不均匀。接下来还是老规矩,我们要做数据预处理的工作。

数据预处理

我们要删除文本中的标点符号,特殊符号,还要删除一些无意义的常用词(stopword),因为这些词和符号对系统分析预测文本的内容没有任何帮助,反而会增加计算的复杂度和增加系统开销,所有在使用这些文本数据之前必须要将它们清理干净。首先我们要定义几个清洗文本的函数:

#定义删除除字母,数字,汉字以外的所有符号的函数
def remove_punctuation(line):line = str(line)if line.strip()=='':return ''rule = re.compile(u"[^a-zA-Z0-9\u4E00-\u9FA5]")line = rule.sub('',line)return line#停用词列表
def stopwordslist(filepath):  stopwords = [line.strip() for line in open(filepath, 'r', encoding='utf-8').readlines()]  return stopwords  #加载停用词
stopwords = stopwordslist("./data/chineseStopWords.txt")

然后我们开始数据清洗工作,清洗工作包括删除标点符号和停用词等,我们将会在数据集中增加两个字段clean_review和cut_review。

#删除除字母,数字,汉字以外的所有符号
df['clean_review'] = df['review'].apply(remove_punctuation)#分词,并过滤停用词
# df['cut_review'] = df['clean_review'].apply(lambda x: " ".join([w for w in list(jb.cut(x)) if w not in stopwords]))
df['cut_review'] = df['clean_review'].apply(lambda x: [w for w in list(jb.cut(x)) if w not in stopwords])
df.head()

 

 数据清洗工作完成以后,我们要开始创建训练集和测试集,我们将使用7:3的比例来拆分数据,然后就是创建训练集和测试集的标签化文档TaggedDocument:

#创建训练集和测试集
train, test = train_test_split(df, test_size=0.3, random_state=42,stratify = df.cat.values)#创建标签化文档
train_tagged = train.apply(lambda r: TaggedDocument(words=r['cut_review'], tags=[r['cat']]), axis=1)
test_tagged = test.apply(lambda r: TaggedDocument(words=r['cut_review'], tags=[r['cat']]), axis=1)

Doc2vec模型配置

Doc2vec是基于Word2Vec的方法,在Word2Vec架构中有两个算法:连续词袋(CBOW)和Skip-gram(SG)。而在Doc2vec架构中也有两个算法与之相似的算法它们是分布式存储(DM)和分布式词袋(DBOW).

分布式词袋(DBOW)

我们将首先使用Doc2vec的DBOW算法,它类似于word2vec中的Skip-gram算法。 通过训练神经网络来获得文档向量,该神经网络用于预测段落中的单词的概率分布,给出来自段落的随机采样的单词。我们将使用下列DBOW算法的参数:

  • dm=0 : 使用Doc2vec的DBOW算法,如果dm=1 使用DM算法。
  • min_count=2 : 忽略词频小于2的词语。
  • negative=5 : 将使用负采样,并指定应绘制多少“噪音词”(通常在5-20之间)。 如果设置为0,则不使用负采样。
  • hs=0 :  如果设置为0,则负数将不为零,负采样将会用到。
  • sample=0 : 配置哪些高频词随机下采样的阈值,可以用范围是(0,1e-5)。
  • workers=cores : 指定多少个工作线程来训练模型(在多核CPU上训练,速度更快)。
#CPU内核数
cores = multiprocessing.cpu_count()

下面开始创建词汇表 

from gensim.models import Doc2Vec
from tqdm import tqdmmodel_dbow = Doc2Vec(dm=0,  negative=5, hs=0, min_count=2, sample = 0, workers=cores)
model_dbow.build_vocab([x for x in tqdm(train_tagged.values)])

 训练模型

 下面我们开始训练模型,我对模型进行30个周期的训练:

%%time
for epoch in range(30):model_dbow.train(utils.shuffle([x for x in tqdm(train_tagged.values)]), total_examples=len(train_tagged.values), epochs=1)model_dbow.alpha -= 0.002model_dbow.min_alpha = model_dbow.alpha

 我们完成了dbow模型训练耗时1分15秒。

 创建特征集

这里有些概念需要陈清一下,我们的模型dbow并不是用来预测的,训练模型的目的仅仅是让dbow可以生成文本的特征向量,其作用类似于Sklearn的CountVectorizer和TfidfTransformer。 模型训练完成以后就可以创建文本的特征向量。

def vec_for_learning(model, tagged_docs):sents = tagged_docs.valuestargets, regressors = zip(*[(doc.tags[0], model.infer_vector(doc.words, steps=20)) for doc in sents])return targets, regressorsy_train, X_train = vec_for_learning(model_dbow, train_tagged)
y_test, X_test = vec_for_learning(model_dbow, test_tagged)

预测

有了特征向量,接下来我们可以进行预测了,我们使用sklearn的逻辑回归来进行训练和预测。

#使用逻辑回归来预测
logreg = LogisticRegression(n_jobs=1, C=1e5)
logreg.fit(X_train, y_train)
y_pred = logreg.predict(X_test)

评估

预测完成以后,接下来我们对预测结果进行评估

from sklearn.metrics import accuracy_score, f1_scoreprint('Testing accuracy %s' % accuracy_score(y_test, y_pred))
print('Testing F1 score: {}'.format(f1_score(y_test, y_pred, average='weighted')))

准确率为77%,这个成绩还算只能算一般般,在我之前的博客中 我们用TfidfVectorizer分别在朴素贝叶斯、逻辑回归、支持向量机进行了预测和评估,其中其中逻辑回归和支持向量机的预测准确率都在80%以上,有心的读者可以将DBOW模型的特征向量在别的分类器上测试一下,看看效果如何。

分布式存储(DM)

接下来我们将使用Doc2vec的DM算法,它类似于word2vec中的CBOW算法。回我们将dm参数设置为1,同样在训练30个周期

model_dmm = Doc2Vec(dm=1, dm_mean=1, window=10, negative=5, min_count=1, workers=5, alpha=0.065, min_alpha=0.065)
model_dmm.build_vocab([x for x in tqdm(train_tagged.values)])
%%time
for epoch in range(30):model_dmm.train(utils.shuffle([x for x in tqdm(train_tagged.values)]), total_examples=len(train_tagged.values), epochs=1)model_dmm.alpha -= 0.002model_dmm.min_alpha = model_dmm.alpha

训练dm模型耗时3分9秒,这个要比前面训练dbow要慢一些。 接下来我们进行一下预测和评估:

y_train, X_train = vec_for_learning(model_dmm, train_tagged)
y_test, X_test = vec_for_learning(model_dmm, test_tagged)logreg.fit(X_train, y_train)
y_pred = logreg.predict(X_test)print('Testing accuracy %s' % accuracy_score(y_test, y_pred))
print('Testing F1 score: {}'.format(f1_score(y_test, y_pred, average='weighted')))

我们看到结果很不理想,准确率只有33.8%

合成一个新模型

在Gensim Doc2Vec Tutorial on the IMDB Sentiment Dataset教程中提到一个新的方法,就是将分布式存储(DM)和分布式存储(DM)合成为一个新模型,然后再用这个新模型来创建文档特征向量,据说这样能提高模型的性能,我们也来试一下吧。

首先,我们删除临时训练数据以释放RAM。

model_dbow.delete_temporary_training_data(keep_doctags_vectors=True, keep_inference=True)
model_dmm.delete_temporary_training_data(keep_doctags_vectors=True, keep_inference=True)

 然后我们合成一个新模型:

from gensim.test.test_doc2vec import ConcatenatedDoc2Vec
new_model = ConcatenatedDoc2Vec([model_dbow, model_dmm])

接下来我们创建文档向量

def get_vectors(model, tagged_docs):sents = tagged_docs.valuestargets, regressors = zip(*[(doc.tags[0], model.infer_vector(doc.words, steps=20)) for doc in sents])return targets, regressorsy_train, X_train = get_vectors(new_model, train_tagged)
y_test, X_test = get_vectors(new_model, test_tagged)

最后我们来预测和评估一下新模型的表现

logreg.fit(X_train, y_train)
y_pred = logreg.predict(X_test)print('Testing accuracy %s' % accuracy_score(y_test, y_pred))
print('Testing F1 score: {}'.format(f1_score(y_test, y_pred, average='weighted')))

似乎真的有改善,新模型的准确率比之前的分布式词袋(DBOW)模型提高了1%

 总结

今天我们学习了另一种文档表示法:Doc2vec,其中包含了2个算法:分布式词袋(DBOW)和分布式存储(DM)。在我们的数据集上经过测试后发现DBOW的表现要优于DM,但是将这两个模型合成一个新模型后,新模型的表现又比DBOW要好一些。总之如果大家还想更深入了解doc2vec的话请研读gensim的教程。

完整代码可以在此下载


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

相关文章

【NLP】 Word2Vec模型 Doc2Vec模型

🔎大家好,我是Sonhhxg_柒,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流🔎 📝个人主页-Sonhhxg_柒的博客_CSDN博客 📃 🎁欢迎各位→点赞…

基于gensim的doc2vec实践

1.“句向量”简介 word2vec提供了高质量的词向量,并在一些任务中表现良好。 关于word2vec的原理可以参考这几篇论文: https://arxiv.org/pdf/1310.4546.pdfhttps://arxiv.org/pdf/1301.3781.pdf 关于如何使用第三方库gensim训练word2vec可以参考这篇…

Word2vec And Doc2vec - 文本向量化

word2vec 与 doc2vec的区别: 两者从字面意思上就可以大致判断出区别来,word2vec主要针对与单词,而doc2vec主要针对于文本: 顾名思义,Word2Vec是在单个单词上训练的,而Doc2vec是在可变长度的文本上训练的,因…

doc2vec原理

doc2vec和word2vec类似,Doc2vec也有两种训练方式,分别是Distributed Memory(DM) 和 Distributed Bag of Words(DBOW)。 DM 试图在给定上下文和段落向量的情况下预测单词的概率,与word2vec中CBOW类似,在一个句子或者文档的训练过程…

Doc2vec论文阅读及源码理解

《Distributed representationss of Sentences and Documents》 Quoc Le and Tomas Mikolov, 2014 文章目录 《Distributed representationss of Sentences and Documents》1. Distributed Memory Model of Paragraph Vectors (PV-DM).1.1 模型架构图1.2 相关代码阅读 2. Dist…

doc2vec介绍和实践

简介 与其他方法的比较 bag of words (BOW):不会考虑词语出现的先后顺序。 Latent Dirichlet Allocation (LDA):更偏向于从文中提取关键词和核心思想extracting topics/keywords out of texts,但是非常难调参数并且难以评价模型的好坏。 …

doc2vec java_word2vec和doc2vec

word2vec基本思想 通过训练每个词映射成k维实数向量(k一般为模型中的超参数),通过词之间的距离来判断语义相似度。 word2vec采用一个三层的神经网络。 训练的时候按照词频将每个词语Huffman编码,词频越高的词语对应的编码越短。这三层的神经网络本身是对…

Doc2vec

目录 一:背景 二:基本原理 2.1:PV-DM 2.2:PV-DBOW 2.3:和word2vec区别 2.4:预测新文本的向量 三:代码实战 3.1:接口介绍 3.2:主要代码 一:背景 之前总结了Word2vec训练词向量的细节,讲解了一个词是如何通过wor…

关于doc2vec

原文地址:https://blog.csdn.net/john_xyz/article/details/79208564 1.“句向量”简介 word2vec提供了高质量的词向量,并在一些任务中表现良好。 关于word2vec的原理可以参考这几篇论文: https://arxiv.org/pdf/1310.4546.pdfhttps://arx…

doc2vec java_doc2vec

gensim 是处理文本的很强大的工具包,基于python环境下: 1.gensim可以做什么? 它可以完成的任务,参加gensim 主页API中给出的介绍,链接如下: http://radimrehurek.com/gensim/apiref.html 2.word2vec的使用 …

Doc2Vec的简介及应用(gensim)

作者:Gidi Shperber 在本文中,你将学习什么是doc2vec,它是如何构建的,它与word2vec有什么关系,你能用它做什么,并且没有复杂的数学公式。 介绍 文本文档的量化表示在机器学习中是一项具有挑战性的任务。很多应用都…

Doc2Vec模型介绍及使用

Doc2Vec模型 Doc2Vec模型 摘要背景段落向量 PV-DM模型PV-DBOW模型gensim实现Doc2Vec说明参考文献摘要 通过本文,你将了解到: Doc2Vec模型是如何产生的Doc2Vec模型细节Doc2Vec模型的特点Doc2Vec的使用及代码(gensim)背景 Doc2Vec模型的产生要从词向量表示(论文word2vec模型)开…

Doc2Vec - 计算文档之间的相似性

本文旨在向您介绍 Doc2Vec 模型,以及它在计算文档之间的相似性时如何提供帮助。 目录 前言 一、Word2Vec 1.Skip-Gram 2.Continuous Bag-of-Words (CBOW) 二、Doc2Vec 1.Distributed Memory version of Paragraph Vector (PV-DM) 2.Words version of Paragra…

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

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

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

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

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

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

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

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

游戏开发所需要的知识

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

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

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

游戏开发流程之完整指南

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