内容简介:Doc2vec是一个NLP工具,用于将文档表示为向量,是word2vec方法的推广。为了理解doc2vec,最好理解word2vec方法。Doc2vec是一个NLP工具,用于将文档表示为向量,是word2vec方法的推广。 为了理解doc2vec,最好理解word2vec方法。但是,完整的数学细节超出了本文的范围。如果您是word2vec和doc2vec的新手,以下资源可以帮助您入门:
Doc2vec是一个NLP工具,用于将文档表示为向量,是word2vec方法的推广。为了理解doc2vec,最好理解word2vec方法。
Doc2vec是一个NLP工具,用于将文档表示为向量,是word2vec方法的推广。 为了理解doc2vec,最好理解word2vec方法。但是,完整的数学细节超出了本文的范围。如果您是word2vec和doc2vec的新手,以下资源可以帮助您入门:
在使用Scikit-Learn进行多类文本分类时使用相同的数据集,在本文中,我们将使用Gensim中的doc2vec技术对产品的投诉进行分类。让我们开始吧!
数据
目标是将消费者金融投诉分为预先定义好的12类。这些数据可以从data.gov下载。
import pandas as pd import numpy as np from tqdm import tqdm tqdm.pandas(desc="progress-bar") from gensim.models import Doc2Vec from sklearn import utils from sklearn.model_selection import train_test_split import gensim from sklearn.linear_model import LogisticRegression from gensim.models.doc2vec import TaggedDocument import re import seaborn as sns import matplotlib.pyplot as plt df = pd.read_csv('Consumer_Complaints.csv') df = df[['Consumer complaint narrative','Product']] df = df[pd.notnull(df['Consumer complaint narrative'])] df.rename(columns = {'Consumer complaint narrative':'narrative'}, inplace = True) df.head(10)
在删除叙述性列中的null值之后,我们需要重新索引数据框架。
df.shape
(318718, 2)
df.index = range(318718) df['narrative'].apply(lambda x: len(x.split(' '))).sum()
我们有超过6300万字,这是一个比较大的数据集。
探索
cnt_pro = df['Product'].value_counts() plt.figure(figsize=(12,4)) sns.barplot(cnt_pro.index, cnt_pro.values, alpha=0.8) plt.ylabel('Number of Occurrences', fontsize=12) plt.xlabel('Product', fontsize=12) plt.xticks(rotation=90) plt.show();
然而,这些类是不平衡的,一个朴素分类器预测所有要收债的东西只会达到20%以上的准确率。 让我们看几个投诉叙述及其相关产品的例子。
def print_complaint(index): example = df[df.index == index][['narrative', 'Product']].values[0] if len(example) > 0: print(example[0]) print('Product:', example[1]) print_complaint(12) print_complaint(20)
文本预处理
下面我们定义了一个函数,用于将文本转换为小写,并从单词中删除标点/符号等等。
from bs4 import BeautifulSoup def cleanText(text): text = BeautifulSoup(text, "lxml").text text = re.sub(r'\|\|\|', r' ', text) text = re.sub(r'http\S+', r'<URL>', text) text = text.lower() text = text.replace('x', '') return text df['narrative'] = df['narrative'].apply(cleanText)
下面的步骤包括训练测试分离为70/30,使用NLTK标记器删除停止字和标记文字。在我们的第一次尝试中,我们给每一个投诉故事都贴上了产品标签。
train, test = train_test_split(df, test_size=0.3, random_state=42) import nltk from nltk.corpus import stopwords def tokenize_text(text): tokens = [] for sent in nltk.sent_tokenize(text): for word in nltk.word_tokenize(sent): if len(word) < 2: continue tokens.append(word.lower()) return tokens train_tagged = train.apply( lambda r: TaggedDocument(words=tokenize_text(r['narrative']), tags=[r.Product]), axis=1) test_tagged = test.apply( lambda r: TaggedDocument(words=tokenize_text(r['narrative']), tags=[r.Product]), axis=1)
这就是培训条目的样子——一个以“信用报告”为标签的投诉叙述示例。
train_tagged.values[30]
建立Doc2Vec训练/评估模型
首先,我们实例化一个doc2vec模型——分布式词袋(DBOW)。在word2vec体系结构中,两个算法名称分别为“连续词袋”(CBOW)和“skip-gram”(SG);在doc2vec架构中,相应的算法有“分布式内存”(DM)和“分布式词袋”(DBOW)。
分布式词袋(DBOW)
DBOW是doc2vec模型,类似于word2vec中的Skip-gram模型。通过训练神经网络来预测段落中随机抽取的单词的概率分布,得到段落向量。 我们会更改以下参数:
- 如果dm=0,则使用分布式词袋包(PV-DBOW);如果dm=1,则使用“分布式内存”(PV-DM)。
- 300维特征向量。
- min_count=2,忽略总频率低于这个值的所有单词。
- negative = 5, 指定应该绘制多少个“噪声字”。
- hs=0,负是非零,用负抽样。
- sample=0,用于配置哪些高频率单词是随机向下采样的阈值。
- workers=cores,使用这些工人线程来训练模型(=用多核机器进行更快的训练)。
import multiprocessing cores = multiprocessing.cpu_count()
建立词汇
model_dbow = Doc2Vec(dm=0, vector_size=300, negative=5, hs=0, min_count=2, sample = 0, workers=cores) model_dbow.build_vocab([x for x in tqdm(train_tagged.values)])
在Gensim中,doc2vec模型的训练相当简单,我们对模型进行了初始化,并对其进行了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.002 model_dbow.min_alpha = model_dbow.alpha
为分类器构建最终的向量特征
def vec_for_learning(model, tagged_docs): sents = tagged_docs.values targets, regressors = zip(*[(doc.tags[0], model.infer_vector(doc.words, steps=20)) for doc in sents]) return targets, regressorsdef vec_for_learning(model, tagged_docs): sents = tagged_docs.values targets, regressors = zip(*[(doc.tags[0], model.infer_vector(doc.words, steps=20)) for doc in sents]) return targets, regressors
训练逻辑回归分类器。
y_train, X_train = vec_for_learning(model_dbow, train_tagged) y_test, X_test = vec_for_learning(model_dbow, test_tagged) 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_score print('Testing accuracy %s' % accuracy_score(y_test, y_pred)) print('Testing F1 score: {}'.format(f1_score(y_test, y_pred, average='weighted')))
Testing accuracy 0.6683609437751004 Testing F1 score: 0.651646431211616
分布式内存(DM)
分布式内存(DM)充当的是一种内存,它可以记住当前上下文中缺少的内容——或者作为段落的主题。虽然单词向量表示单词的概念,但是文档向量打算表示文档的概念。我们再次实例化一个向量大小为300字的Doc2Vec模型,并在训练语料库中迭代30次。
model_dmm = Doc2Vec(dm=1, dm_mean=1, vector_size=300, 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.002 model_dmm.min_alpha = model_dmm.alpha
训练逻辑回顾分类器
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')))
Testing accuracy 0.47498326639892907 Testing F1 score: 0.4445833078167434
模型匹配
根据Gensim doc2vec教程关于IMDB情绪数据集的介绍,将分布式词汇包(DBOW)和分布式内存(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.values targets, regressors = zip(*[(doc.tags[0], model.infer_vector(doc.words, steps=20)) for doc in sents]) return targets, regressors
训练逻辑回归模型
y_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')))
Testing accuracy 0.6778572623828648 Testing F1 score: 0.664561533967402
结果提高了1%。 在本文中,我使用训练集对doc2vec进行训练,但是在 Gensim的教程 中,使用整个数据集进行训练,我尝试了这种方法,使用整个数据集对doc2vec分类器进行训练,用于我们的消费者投诉分类,我的准确率达到了70%。你可以在这里找到 Notebook ,这是一个不同的方法。
上面分析的 Jupyter笔记本 可以在 Github 上找到。我期待着听到任何问题。
作者:Susan Li 原文链接: https://www.kdnuggets.com/2018/11/multi-class-text-classification-doc2vec-logistic-regression.html
版权声明: 作者保留权利。文章为作者独立观点,不代表数据人网立场。严禁修改,转载请注明原文链接:http://shujuren.org/article/777.html
数据人网: 数据人学习,交流和分享的平台,诚邀您创造和分享数据知识,共建和共享数据智库。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 文本编辑器 Notepad++ 7.7.1 发布,修复回归问题
- 机器学习算法之岭回归、Lasso回归和ElasticNet回归
- [机器学习实战-Logistic回归]使用Logistic回归预测各种实例
- 线性回归背后的数学
- PyTorch 学习:线性回归
- 逻辑回归——详细概述
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
深度探索C++对象模型
[美] Stanley B. Lippman / 侯捷 / 华中科技大学出版社 / 2001-5 / 54.00元
这本书探索“对象导向程序所支持的C++对象模型”下的程序行为。对于“对象导向性质之基础实现技术”以及“各种性质背后的隐含利益交换”提供一个清楚的认识。检验由程序变形所带来的效率冲击。提供丰富的程序范例、图片,以及对象导向观念和底层对象模型之间的效率测量。一起来看看 《深度探索C++对象模型》 这本书的介绍吧!