字幕组双语原文:NLP之文本分类:「Tf-Idf、Word2Vec和BERT」三种模型比较

英语原文:Text Classification with NLP: Tf-Idf vs Word2Vec vs BERT

翻译:雷锋字幕组(关山、wiige)

概要

在本文中,我将使用NLP和Python来解释3种不同的文本多分类策略:老式的词袋法(tf-ldf),著名的词嵌入法(Word2Vec)和最先进的语言模型(BERT)。

NLP(自然语言处理)是人工智能的一个领域,它研究计算机和人类语言之间的交互作用,特别是如何通过计算机编程来处理和分析大量的自然语言数据。NLP常用于文本数据的分类。文本分类是指根据文本数据内容对其进行分类的问题。

我们有多种技术从原始文本数据中提取信息,并用它来训练分类模型。本教程比较了传统的词袋法(与简单的机器学习算法一起使用)、流行的词嵌入模型(与深度学习神经网络一起使用)和最先进的语言模型(和基于attention的transformers模型中的迁移学习一起使用),语言模型彻底改变了NLP的格局。

我将介绍一些有用的Python代码,这些代码可以轻松地应用在其他类似的案例中(仅需复制、粘贴、运行),并对代码逐行添加注释,以便你能复现这个例子(下面是全部代码的链接)。

mdipietro09/DataScience_ArtificialIntelligence_Utils

我将使用“新闻类别数据集”(News category dataset),这个数据集提供了从HuffPost获取的2012-2018年间所有的新闻标题,我们的任务是把这些新闻标题正确分类,这是一个多类别分类问题(数据集链接如下)。

News Category Dataset

特别地,我要讲的是:

设置:导入包,读取数据,预处理,分区。词袋法:用scikit-learn进行特征工程、特征选择以及机器学习,测试和评估,用lime解释。词嵌入法:用gensim拟合Word2Vec,用tensorflow/keras进行特征工程和深度学习,测试和评估,用Attention机制解释。语言模型:用transformers进行特征工程,用transformers和tensorflow/keras进行预训练BERT的迁移学习,测试和评估。设置

首先,我们需要导入下面的库:

该数据集包含在一个jason文件中,所以我们首先将其读取到一个带有json的字典列表中,然后将其转换为pandas的DataFrame。

原始数据集包含30多个类别,但出于本教程中的目的,我将使用其中的3个类别:娱乐(Entertainment)、政治(Politics)和科技(Tech)。

从图中可以看出,数据集是不均衡的:和其他类别相比,科技新闻的占比很小,这会使模型很难识别科技新闻。

在解释和构建模型之前,我将给出一个预处理示例,包括清理文本、删除停用词以及应用词形还原。我们要写一个函数,并将其用于整个数据集上。

该函数从语料库中删除了一组单词(如果有的话)。我们可以用nltk创建一个英语词汇的通用停用词列表(我们可以通过添加和删除单词来编辑此列表)。

现在,我将在整个数据集中应用编写的函数,并将结果存储在名为“text_clean”的新列中,以便你选择使用原始的语料库,或经过预处理的文本。

如果你对更深入的文本分析和预处理感兴趣,你可以查看这篇文章。我将数据集划分为训练集(70%)和测试集(30%),以评估模型的性能。

让我们开始吧!

词袋法

词袋法的模型很简单:从文档语料库构建一个词汇表,并计算单词在每个文档中出现的次数。换句话说,词汇表中的每个单词都成为一个特征,文档由具有相同词汇量长度的矢量(一个“词袋”)表示。例如,我们有3个句子,并用这种方法表示它们:

特征矩阵的形状:文档数x词汇表长度

可以想象,这种方法将会导致很严重的维度问题:文件越多,词汇表越大,因此特征矩阵将是一个巨大的稀疏矩阵。所以,为了减少维度问题,词袋法模型通常需要先进行重要的预处理(词清除、删除停用词、词干提取/词形还原)。

词频不一定是文本的最佳表示方法。实际上我们会发现,有些常用词在语料库中出现频率很高,但是它们对目标变量的预测能力却很小。为了解决此问题,有一种词袋法的高级变体,它使用词频-逆向文件频率(Tf-Idf)代替简单的计数。基本上,一个单词的值和它的计数成正比地增加,但是和它在语料库中出现的频率成反比。

先从特征工程开始,我们通过这个流程从数据中提取信息来建立特征。使用Tf-Idf向量器(vectorizer),限制为1万个单词(所以词长度将是1万),捕捉一元文法(即 "new "和 "york")和 二元文法(即 "new york")。以下是经典的计数向量器的代码:

现在将在训练集的预处理语料上使用向量器来提取词表并创建特征矩阵。

特征矩阵X_train的尺寸为34265(训练集中的文档数)×10000(词长度),这个矩阵很稀疏:

从特征矩阵中随机抽样(黑色为非零值)

为了知道某个单词的位置,可以这样在词表中查询:

如果词表中存在这个词,这行脚本会输出一个数字N,表示矩阵的第N个特征就是这个词。

为了降低矩阵的维度所以需要去掉一些列,我们可以进行一些特征选择(Feature Selection),这个流程就是选择相关变量的子集。操作如下:

将每个类别视为一个二进制位(例如,"科技"类别中的科技新闻将分类为1,否则为0);进行卡方检验,以便确定某个特征和其(二进制)结果是否独立;只保留卡方检验中有特定p值的特征。

这将特征的数量从10000个减少到3152个,保留了最有统计意义的特征。选一些打印出来是这样的:

我们将这组新的词表作为输入,在语料上重新拟合向量器。这将输出一个更小的特征矩阵和更短的词表。

新的特征矩阵X_train的尺寸是34265(训练中的文档数量)×3152(给定的词表长度)。你看矩阵是不是没那么稀疏了:

从新的特征矩阵中随机抽样(非零值为黑色)

现在我们该训练一个机器学习模型试试了。我推荐使用朴素贝叶斯算法:它是一种利用贝叶斯定理的概率分类器,贝叶斯定理根据可能相关条件的先验知识进行概率预测。这种算法最适合这种大型数据集了,因为它会独立考察每个特征,计算每个类别的概率,然后预测概率最高的类别。

我们在特征矩阵上训练这个分类器,然后在经过特征提取后的测试集上测试它。因此我们需要一个scikit-learn流水线:这个流水线包含一系列变换和最后接一个estimator。将Tf-Idf向量器和朴素贝叶斯分类器放入流水线,就能轻松完成对测试数据的变换和预测。

至此我们可以使用以下指标评估词袋模型了:

准确率: 模型预测正确的比例。混淆矩阵: 是一张记录每类别预测正确和预测错误数量的汇总表。ROC: 不同阈值下,真正例率与假正例率的对比图。曲线下的面积(AUC)表示分类器中随机选择的正观察值排序比负观察值更靠前的概率。精确率: "所有被正确检索的样本数(TP)"占所有"实际被检索到的(TP+FP)"的比例。召回率: 所有"被正确检索的样本数(TP)"占所有"应该检索到的结果(TP+FN)"的比例。

词袋模型能够在测试集上正确分类85%的样本(准确率为0.85),但在辨别科技新闻方面却很吃力(只有252条预测正确)。

让我们探究一下为什么模型会将新闻分类为其他类别,顺便看看预测结果是不是能解释些什么。lime包可以帮助我们建立一个解释器。为让这更好理解,我们从测试集中随机采样一次, 看看能发现些什么:

这就一目了然了:虽然"舞台(stage)"这个词在娱乐新闻中更常见, "克林顿(Clinton) "和 "GOP "这两个词依然为模型提供了引导(政治新闻)。

词嵌入

词嵌入(Word Embedding)是将中词表中的词映射为实数向量的特征学习技术的统称。这些向量是根据每个词出现在另一个词之前或之后的概率分布计算出来的。换一种说法,上下文相同的单词通常会一起出现在语料库中,所以它们在向量空间中也会很接近。例如,我们以前面例子中的3个句子为例:

二维向量空间中的词嵌入

在本教程中,我门将使用这类模型的开山怪: Google的Word2Vec(2013)。其他流行的词嵌入模型还有斯坦福大学的GloVe(2014)和Facebook的FastText(2016)。

Word2Vec生成一个包含语料库中的每个独特单词的向量空间,通常有几百维, 这样在语料库中拥有共同上下文的单词在向量空间中的位置就会相互靠近。有两种不同的方法可以生成词嵌入:从某一个词来预测其上下文(Skip-gram)或根据上下文预测某一个词(Continuous Bag-of-Words)。

在Python中,可以像这样从genism-data中加载一个预训练好的词嵌入模型:

我将不使用预先训练好的模型,而是用gensim在训练数据上自己训练一个Word2Vec。在训练模型之前,需要将语料转换为n元文法列表。具体来说,就是尝试捕获一元文法("york")、二元文法("new york")和三元文法("new york city")。

在训练Word2Vec时,需要设置一些参数:

词向量维度设置为300;窗口大小,即句子中当前词和预测词之间的最大距离,这里使用语料库中文本的平均长度;训练算法使用 skip-grams (sg=1),因为一般来说它的效果更好。

现在我们有了词嵌入模型,所以现在可以从语料库中任意选择一个词,将其转化为一个300维的向量。

甚至可以通过某些维度缩减算法(比如TSNE),将一个单词及其上下文可视化到一个更低的维度空间(2D或3D)。

这非常酷,但词嵌入在预测新闻类别这样的任务上有何裨益呢?词向量可以作为神经网络的权重。具体是这样的:

首先,将语料转化为单词id的填充(padded)序列,得到一个特征矩阵。然后,创建一个嵌入矩阵,使id为N的词向量位于第N行。最后,建立一个带有嵌入层的神经网络,对序列中的每一个词都用相应的向量进行加权。还是从特征工程开始,用 tensorflow/keras 将 Word2Vec 的同款预处理语料(n-grams 列表)转化为文本序列的列表:

特征矩阵X_train的尺寸为34265×15(序列数×序列最大长度)。可视化一下是这样的:

特征矩阵(34 265 x 15)

现在语料库中的每一个文本都是一个长度为15的id序列。例如,如果一个文本中有10个词符,那么这个序列由10个id和5个0组成,这个0这就是填充元素(而词表中没有的词其id为1)。我们来输出一下看看一段训练集文本是如何被转化成一个带有填充元素的词序列:

记得在测试集上也要做这个特征工程:

X_test (14,697 x 15)

现在我们就有了X_train和X_test,现在需要创建嵌入矩阵,它将作为神经网络分类器的权重矩阵.

这段代码生成的矩阵尺寸为22338×300(从语料库中提取的词表长度×向量维度)。它可以通过词表中的词id。

终于要建立深度学习模型了! 我门在神经网络的第一个Embedding层中使用嵌入矩阵,训练它之后就能用来进行新闻分类。输入序列中的每个id将被视为访问嵌入矩阵的索引。这个嵌入层的输出是一个 包含输入序列中每个词id对应词向量的二维矩阵(序列长度 x 词向量维度)。以 "我喜欢这篇文章(I like this article) "这个句子为例:

我的神经网络的结构如下:

一个嵌入层,如前文所述, 将文本序列作为输入, 词向量作为权重。一个简单的Attention层,它不会影响预测,但它可以捕捉每个样本的权重, 以便将作为一个不错的解释器(对于预测来说它不是必需的,只是为了提供可解释性,所以其实可以不用加它)。这篇论文(2014)提出了序列模型(比如LSTM)的Attention机制,探究了长文本中哪些部分实际相关。两层双向LSTM,用来建模序列中词的两个方向。最后两层全连接层,可以预测每个新闻类别的概率。

现在来训练模型,不过在实际测试集上测试之前,我们要在训练集上划一小块验证集来验证模型性能。

Nice!在某些epoch中准确率达到了0.89。为了对词嵌入模型进行评估,在测试集上也要进行预测,并用相同指标进行对比(评价指标的代码与之前相同)。

该模式的表现与前一个模型差不多。 其实,它的科技新闻分类也不怎么样。

但它也具有可解释性吗? 是的! 因为在神经网络中放了一个Attention层来提取每个词的权重,我们可以了解这些权重对一个样本的分类贡献有多大。所以这里我将尝试使用Attention权重来构建一个解释器(类似于上一节里的那个):

就像之前一样,"克林顿 (clinton)"和 "老大党(gop) "这两个词激活了模型的神经元,而且这次发现 "高(high) "和 "班加西(benghazi) "与预测也略有关联。

语言模型

语言模型, 即上下文/动态词嵌入(Contextualized/Dynamic Word Embeddings),克服了经典词嵌入方法的最大局限:多义词消歧义,一个具有不同含义的词(如" bank "或" stick")只需一个向量就能识别。最早流行的是 ELMO(2018),它并没有采用固定的嵌入,而是利用双向 LSTM观察整个句子,然后给每个词分配一个嵌入。

到Transformers时代, 谷歌的论文Attention is All You Need(2017)提出的一种新的语言建模技术,在该论文中,证明了序列模型(如LSTM)可以完全被Attention机制取代,甚至获得更好的性能。

而后谷歌的BERT(Bidirectional Encoder Representations from Transformers,2018)包含了ELMO的上下文嵌入和几个Transformers,而且它是双向的(这是对Transformers的一大创新改进)。BERT分配给一个词的向量是整个句子的函数,因此,一个词可以根据上下文不同而有不同的词向量。我们输入岸河(bank river)到Transformer试试:

如果将输入文字改为 "银行资金(bank money)",则会得到这样的结果:

为了完成文本分类任务,可以用3种不同的方式来使用BERT:

从零训练它,并将其作为分类器使用。提取词嵌入,并在嵌入层中使用它们(就像上面用Word2Vec那样)。对预训练模型进行精调(迁移学习)。我打算用第三种方式,从预训练的轻量 BERT 中进行迁移学习,人称 Distil-BERT (用6600 万个参数替代1.1 亿个参数)

在训练模型之前,还是需要做一些特征工程,但这次会比较棘手。为了说明我们需要做什么,还是以我们这句 "我喜欢这篇文章(I like this article) "为例,他得被转化为3个向量(Ids, Mask, Segment):

尺寸为 3 x 序列 长度

首先,我们需要确定最大序列长度。这次要选择一个大得多的数字(比如50),因为BERT会将未知词分割成子词符(sub-token),直到找到一个已知的单字。比如若给定一个像 "zzdata "这样的虚构词,BERT会把它分割成["z","##z","##data"]。除此之外, 我们还要在输入文本中插入特殊的词符,然后生成掩码(musks)和分段(segments)向量。最后,把它们放进一个张量里得到特征矩阵,其尺寸为3(id、musk、segment)x 语料库中的文档数 x 序列长度。

这里我使用原始文本作为语料(前面一直用的是clean_text列)。

特征矩阵X_train的尺寸为3×34265×50。我们可以从特征矩阵中随机挑一个出来看看:

这段代码在dtf_test["text"]上跑一下就能得到X_test。

现在要从预练好的 BERT 中用迁移学习一个深度学习模型。具体就是,把 BERT 的输出用平均池化压成一个向量,然后在最后添加两个全连接层来预测每个新闻类别的概率.

下面是使用BERT原始版本的代码(记得用正确的tokenizer重做特征工程):

这里用轻量级的Distil-BERT来代替BERT:

最后我们训练.测试并评估该模型 (评价代码与前文一致):

BERT的表现要比之前的模型稍好,它能识别的科技新闻要比其他模型多一些.

结语

本文是一个通俗教程,展示了如何将不同的NLP模型应用于多类分类任务上。文中比较了3种流行的方法: 用Tf-Idf的词袋模型, 用Word2Vec的词嵌入, 和用BERT的语言模型. 每个模型都介绍了其特征工程与特征选择、模型设计与测试、模型评价与模型解释,并在(可行时的)每一步中比较了这3种模型。

雷锋字幕组是一个由AI爱好者组成的翻译团队,汇聚五五多位志愿者的力量,分享最新的海外AI资讯,交流关于人工智能技术领域的行业转变与技术创新的见解。

团队成员有大数据专家,算法工程师,图像处理工程师,产品经理,产品运营,IT咨询人,在校师生;志愿者们来自IBM,AVL,Adobe,阿里,百度等知名企业,北大,清华,港大,中科院,南卡罗莱纳大学,早稻田大学等海内外高校研究所。

如果,你也是位热爱分享的AI爱好者。欢迎与雷锋字幕组一起,学习新知,分享成长。

bert模型可以做文本主题识别吗_NLP之文本分类:「Tf-Idf、Word2Vec和BERT」三种模型比较...相关推荐

  1. word2vec模型评估_NLP之文本分类:「Tf-Idf、Word2Vec和BERT」三种模型比较

    字幕组双语原文:NLP之文本分类:「Tf-Idf.Word2Vec和BERT」三种模型比较 英语原文:Text Classification with NLP: Tf-Idf vs Word2Vec ...

  2. NLP之文本分类:「Tf-Idf、Word2Vec和BERT」三种模型比较

    英语原文:Text Classification with NLP: Tf-Idf vs Word2Vec vs BERT 翻译:雷锋字幕组(关山.wiige) 概要 在本文中,我将使用NLP和Pyt ...

  3. 基于主题模型的专利文本主题挖掘与应用研究- 专利文本主题挖掘方法

    基于分类 需要认为提前设定好一定的分类标准,并需要规定好各个主题类别信息,它是一种有监督或者半监督的方法,对于一个新文本的归类过程也是对其文本主题信息解读的过程. 基于聚类 无监督 通过对聚类各个类簇 ...

  4. 用隐马尔可夫模型(HMM)做命名实体识别——NER系列(二)

    上一篇文章里<用规则做命名实体识别--NER系列(一)>,介绍了最简单的做命名实体识别的方法–规则.这一篇,我们循序渐进,继续介绍下一个模型--隐马尔可夫模型. 隐马尔可夫模型,看上去,和 ...

  5. 用隐马尔可夫模型(HMM)做命名实体识别——NER系列(一)

    原博python2写的,文末是我改的python3代码 隐马尔可夫模型,看上去,和序列标注问题是天然适配的,所以自然而然的,早期很多做命名实体识别和词性标注的算法,都采用了这个模型. 这篇文章我将基于 ...

  6. 产品路线图的三种模型(RICE/MoSCoW/Kano),教你如何对需求进行优先级排序

    前言 RICE/MoSCoW/Kano三种模型,教你如何对需求进行优先级排序. 也许你会让业务提供一份ROI,记得前不久参加过一场立项会评审,一位很有意思的小产品在会上讲不清楚ROI,评审们要求会后重 ...

  7. Javascript事件模型系列(一)事件及事件的三种模型

    一.开篇 在学习javascript之初,就在网上看过不少介绍javascript事件的文章,毕竟是js基础中的基础,文章零零散散有不少,但遗憾的是没有看到比较全面的系列文章.犹记得去年这个时候,参加 ...

  8. UML建模(三种模型)

    文章目录 一.UML建模(三种模型) 1.类模型 2.状态模型 3.交互模型 二.uml建模的步骤 一.UML建模(三种模型) 1.类模型 描述系统内部对象及其关系的静态结构.类模型由类图构建,类图中 ...

  9. 机器学习番外篇—朴素贝叶斯三种模型(多项式,高斯,伯努利)

    朴素贝叶斯三种模型(多项式,高斯,伯努利) 高斯 有些特征可能是连续型变量,比如说人的身高,物体的长度,这些特征可以转换成离散型的值,比如如果身高在160cm以下,特征值为1:在160cm和170cm ...

最新文章

  1. 全球5G专利能力榜T0P15出炉:谁是冠军?
  2. 从上市公司数据读懂我国新兴产业发展态势
  3. 利用被入侵的路由器迈入内网——抓包,利用路由器漏洞入侵,进行流量劫持...
  4. 笔记本电脑性价比排行2019_办公笔记本电脑排名2019 五款适合办公的笔记本电脑推荐...
  5. 解决:Request header field Content-Type is not allowed by Access-Control-Allow-Headers
  6. 前端面试题(重点整理):谈谈你对web标准和W3c的认识、什么是ECMA、什么是html、浏览器和开发工具介绍
  7. 【Elasticsearch】es如何停用节点
  8. zabbix再爆高危SQL注入漏洞,可获系统权限
  9. pagehelper Jar包下载
  10. ubuntu下交叉编译libyuv到RK3399平台(ARM64)((提高YUV图像转换效率)
  11. 无限条码扫描枪,手机充当扫描器
  12. 电子传真在金融业务的应用
  13. python文献检索工具与技巧答案_文献检索(答案)
  14. android常用颜色
  15. 如何使用QuickTime Player一键视频压缩
  16. 智慧农业实验室第一次成果
  17. 玩转prometheus告警 alertmanger(二)之alertmanger 邮件 钉钉告警
  18. 391、Java框架46 -【Hibernate - 查询HQL、查询Criteria、查询标准SQL】 2020.10.19
  19. 使用CAS实现SSO.
  20. linux 下文件夹无法删除(报:Device or resource busy),然后进入文件夹也无法创建新的文件夹(Permission denied)

热门文章

  1. 4.1.3 消费者轮询的流程
  2. 今天高兴,分享一个我亲自测试的网上赚钱方法......
  3. mysql如何进行算术运算_MySQL教程53-MySQL算术运算符
  4. Mac常用快捷键一览
  5. android安全模式
  6. Converted Tween Animation Class in AS3
  7. 安发生物|醒醒吧!不吃晚饭=增肥!来听听钟南山院士的建议......
  8. vuejs项目纯js导出word、在线下载富文本内容或者网页另存为word文件
  9. 前端白屏出现的原因及一些解决方式
  10. IGARSS 2019点云分类挑战赛中遇到的传统方法