资源技术动态万字干货 | 文本分类不知从何着手?看这一篇就够了

万字干货 | 文本分类不知从何着手?看这一篇就够了

2019-11-19 | |  100 |   0

原标题:万字干货 | 文本分类不知从何着手?看这一篇就够了

来源:今日头条          链接:https://www.toutiao.com/a6759470202947125772/


近日,来自Alpaca的数据科学家Imad El Hanafi分享了一篇NLP新闻分类实战的文章,该文章重点讨论了文本分类的问题。

Imad El Hanafi 毕业于ENSTA ParisTech,拥有应用数学的学士学位和数据科学与机器学习的硕士学位。

image.png


Imad El Hanafi

数据采集

数据探索和清理

文本清理和标记化

保存数据--Feather

特征提取-TF-IDF

机器学习分类器

image.png


简介


GutHub repo:

https://github.com/imadelh/NLP-news-classification

Live version:

https://nlp.imadelhanafi.com/

自然语言处理(NLP)推动了诸如翻译、个人助理应用等日常应用程序和工具的发展。

近来,在NLP (BERT、ULMFiT、XLNet等)方面取得的进展,使得在NLP基准上构建超越人类基线性能的模型成为可能。

本文将重点讨论文本分类的问题。文本分类在网络搜索、信息分类等很多应用程序中都是不可或缺的

数据准备

新闻数据量是巨大的,可以在不同的网站或推特上获得(每天5亿条推特)。对新闻进行分类是一个具有挑战性的问题,手动分类是不可行的。

数据收集

要构建新闻标题的文本分类器,首先要收集数据。我们需要具有相关标签(新闻类型)的新闻集合。

可以在新闻APIhttps://newsapi.org中从全球30,000个来源中搜索文章,并可以指定新闻的类别。

我计划使用这个工具来构建数据集,但是开发人员计划(每天500个请求和1个月的历史数据) 限制了大型数据集的构建。

另一种解决方案是使用来自HuffPost4的公开可用数据集,其中包含约20万条具有相应类别的新闻标题。

数据探索和清理

Notebook提供了数据探索和清理的步骤,可在Notebooks / data_prepation.ipynb获取。

初始数据集包含41个不平衡的类别。

以下饼图提供了与每个类别的标题所占的百分比。

image.png


有许多类别代表了相同的基础类别(例如TASTE和FOOD&DRINK)。合并这些类别,最终得到34个分类。

初始数据集包含不同的特性,比如文章的作者或发布日期。因为我们想要构建通用的新闻分类器,因此仅使用带有简短说明的标题。

image.png


清除非ASCII字符后,可以观察句子长度的分布。

image.png


文本理和标记化


要从上面定义的文本构建简单的功能(例如二进制功能,TF-IDF或嵌入),必须对文本进行一些预处理。

此处理包括:

  • 停止删除单词:删除最常用的单词,这些单词通常含义不大,例如“ the”,“ a”,“ for”…

  • 词形还原:返回单词的基数或字典形式。

可以使用NLTK或SPaCY库实现预处理。在我们的例子中,我使用SPACY来获取令牌并进行词形还原。

image.png


此步骤中的数据集包括3列:text、clean_text、category.

image.png


对于语言模型,将使用适用于特定算法/模型的其他标记化过程。


使用Feather-保存数据

使用Feather(https://github.com/wesm/feather)导出数据。

Feather为数据帧提供了二进制序列化,它旨在有效地读取和写入数据帧。

数据集包含超过20万的观察值,为了更快地进行机器学习实验和迭代,我们保存了两个版本的数据:

  • 一个平衡的数据集中每个类有1004个观察值。该数据集将用于快速测试模型,并在开发ML解决方案时具有更快的迭代。

  • 完整的数据集将用于训练在生产中使用的ML模型。

基准模型

在跳到复杂的模型之前,必须建立一个简单的基线。完成所需任务的基本机器学习模型。

对于新闻分类问题,将使用term frequency - inverse document frequency (TF-IDF)建立一个基线,结合Logistic回归或SVM等简单分类器进行特征提取。

特征提取-TF-IDF

从文本中提取特征包括用数字向量表示文档(新闻)。TF-IDF是获得此表示的一种方法。它被视为词频和逆文件频率的乘积。词频是一个单词在给定文档中出现次数的计数。

逆文件频率是单词在文档语料库中出现的次数。TF-IDF用于根据单词的重要性对其进行加权。在许多文档中经常使用的单词权重较低,而很少使用的单词的权重较高。

此过程可以分为两个步骤

  • Count Vectorizer5:将文本数据集合转换为稀疏矩阵。每个原始文档将代表一个文档(新闻),列是所有文档(词汇)中单词集合的ID。TF出现(文档i,单词j)=单词j在文档i中的出现。Scikit-learn implementation提供了关于如何控制词频阈值的选项。

  • TF-IDF transformer6:通过对词频加权,将稀疏矩阵转换为tf-idf表示形式,如下所示:

image.png


其中dfjdfj是包含wordj的文档数,并且TF(documenti,wordj)是词频,被定义为TFoccurence(word_j的总出现次数之和)。

最后,将稀疏矩阵的原始数据归一化(代表每个文档的向量归一化)。

此过程(tf-idf)应用于在数据准备步骤中的clean_text列。


机器学习分类器

  • 算法

建立文本的数字表示后,可以尝试训练分类器。使用两个经典常用的分类器:SVM和Logistic回归。

1、 逻辑回归

Logistic回归的目标是构建一个线性分类器,该线性分类器通过建模来预测属于一个类别或另一个类别的概率p(y∣x)(判别学习算法)。

在我们的例子中,有多个类。一种常用的技术是为每个类训练一个One-vs- all分类器。

想象一下训练数据集t (xj,yj)j=1N 中有K个类且yj∈{1,…,K}.

对于每个i类,通过将其余数据视为负样本,将i类中的所有元素视为正样本来训练二元逻辑回归。

这将导致把K个分类器定义为hθk(x)= P(y = k∣x;θk),并且每个分类器都由一组参数θk参数化。

在x作出预测, 从(hθk (x)) K = 1 K中计算K概率,然后用与x相关的标签得出

image.png


现在来考虑二元逻辑回归的情况,其中yi∈{0,1},概率p(y∣x)由以下模型给出:

image.png


可以用紧凑的方式写成

image.png


为了找到最佳θ,我们将N个观测数据点最大化

image.png


这等于最小化负对数似然

image.png


并通过在负对数似然函数中替换p(y∣x;θ)=hθ(x)y(1-hθ(x))(1-y)得到损失函数l(θ)(逻辑损失函数) 最小化以找到最佳参数θ∗

image.png


应该注意的是,我们忽略了先前计算中的偏差,但是问题的表述保持不变。为了包括偏差b,我们可以考虑一个新的参数β=(θ,b),使βTx=θTx+ b,然后最小化损耗l(β)。此外,还可以将L1或L2正则项添加到损耗函数中。


如果考虑yi∈{−1,1的情况,我们会得到与损失函数略有不同的公式,但优化问题仍然是等效的。


本文提供了详细的计算:

https://stats.stackexchange.com/questions/250937/which-loss-function-is-correct-for-logistic-regression/279698#279698

存在另一种用于处理多类分类的方法,称为“多项式逻辑回归”,该方法基于二进制分类的情况下使用多项式分布而不是二项式分布。

2、 支持向量机

对于SVM分类器,我们仅考虑二进制分类的情况。如前所述,可以通过使用“一对多”分类器来获得One-vs-All分类器。

  • 可分离的数据

考虑一个训练数据集(xi,yi)i=1N ,其中yi∈{−1,1}并且数据点是线性可分离的(稍后我们将讨论数据不可分离的情况)。

SVM是一个线性分类器,旨在找到一个超平面(子空间,其维数小于观测值x),该超平面将两个类中到最接近的数据点的距离最大化。它是具有最大余量的超平面。

超平面由(w,b)定义为一组点H={x∣wTx+b=0}。裕度γ定义为从超平面H到这两个类别的最接近点的距离。

让我们考虑点x和xp在超平面H上的投影。令d是从xp到x的最小长度的向量。d=x−xp

d与H正交,因此对于α∈R,d =αw

image.png


由于xp∈H,wTxp + b = 0。通过用(x−d)替换xp可以写wT(x-d)+ b = wT(x-αw)+ b = 0

这意味着 α=wTwwTx+b,x和xp之间的距离由d的范数给出,可以写成

image.png


关于某些训练数据点(xi)i = 1i = N的余量γγ可以写成γ(w,b)=ximin∣∣w∣∣2∣wTxi+b∣

现在我们有了属性的定义,可以提出属性最大化的问题。

对于训练数据集(xi,yi)i = 1i = N使得yi∈{−1,1},如果yi(wTxi + b)≥0,则分类器(由超平面定义)做出正确的预测。

目的是在所有预测均正确的约束下最大化余量γ。

image.png


通过在此优化问题中插入边距的定义,我们得到

image.png


由于超平面是尺度不变的,因此在某种意义上说,可以将w和b乘以任何实非零值,并且仍然定义相同的超平面,因此可以重新调整w和b,使得xi∣wTxi + b∣ = 1min。添加此约束,可以将优化问题写为

image.png


相当于

image.png

这是具有线性约束的二次优化,解决方案将定义最佳超平面以分离数据。

  • 数据不可分离

在两个类之间没有分离的超平面的情况下,我们通过引入变量≥i≥0并将约束重写为yi(wTxi + b)≥1来允许约束yi(wTxi + b)≥1 −ϵi。这意味着允许某些输入xi靠近超平面或在错误的一侧。

优化问题可以写成

image.png


如果将ϵ的这种闭合形式插入优化问题中,我们将获得无约束版本的SVM作为铰链损耗和L2正则化器的总和

image.png


指标

要评估机器学习模型,需要确定一个指标。

我们使用的数据集是具有34个类的不平衡数据集。只看准确性可能会产生偏见,并且没有任何信息。

对于不平衡的类别,F1评分是一种广泛使用的指标,该指标在同一指标中结合了精度和召回率。

以一个包含3个类的简单示例来了解精度,召回率和F1得分。

image.png

对于每个类别,我们将定义“真阳性”(TP),“假阳性”(FP)和“假阴性”(FN)。


然后,为每个类别计算精度,召回率和F1分数,并取它们的平均值以获得宏观得分,或者按每个类别的出现率加权平均以获得加权得分。

TP,FP和FN定义如下:

TP:预计具有正确标签的样本。

FP:预测的样本与真实标签不同。

FN:来自真实标签的样本得到了错误的预测。

使用混淆矩阵能够更好地理解这些数量。

image.png


从上面的例子和第一列,我们有一个错误的预测。这可以算作第2类的FP和第1类的FN。对于第二列,我们得到了正确的预测,这可以作为第2类的TP。


下面是每个类的TP、FN和FP的总结

image.png


然后,可以如下计算每个类别的精度、召回率和F1分数,并取各个类别的平均值以获得宏观指标。

  • 精度P = TP /(TP + FP)衡量分类器仅将真正正样本预测为正样本的能力。

  • 回想一下,R = TP /(TP + FN)测量的是实际归为正样本的样本数量。

  • F1 = 2 * P * R /(P + R)。

除了F1得分外,我们还将使用top3准确性(在前3个预测中具有真实标签)来评估模型的性能。

  • 参数搜索和训练过程

定义了算法和评价指标后,就可以开始训练和参数搜索的过程。目标是找到最好的超参数,使我们能够很好地概括测试数据集。

支持向量机的超参数是误差项的惩罚C,而logistic回归的超参数是正则化强度。我们将使用交叉验证和网格搜索方法来找到最佳参数。

一个测试集是保留的,将用于最后的评估,训练集分为k-折叠。对于每一个由超参数定义的模型,我们都遵循以下步骤:

  • 对模型进行k - 1次折叠训练;

  • 在剩余折叠上计算性能(度量)

每次拆分都重复这个过程,并报告性能的平均值。

image.png


对于超参数网格中的每个值,我们将获得一个使用交叉验证过程计算的平均度量。最好的超参数就是给出最高度量的参数。最后,我们在测试数据集上评估最佳模型。

脚本sklearn_models/params_search.py实现了这个过程,能够选择超参数空间并保存搜索过程的日志。

image.png


上述方法是建立基准的简单方法。可以考虑使用其他解决方案来提高性能,例如平衡类,使用通过嵌入向量加权的TF-IDF,不同分类器的集合等。

语言模型

建立基准之后,我们尝试通过使用基于深度学习的现代文本分类方法来提高性能。

2018年,J. Howard和S. Ruder针对NLP问题提出了一种新的迁移学习方法,称为文本分类通用语言模型微调(Universal Language Model Fine-tuning for Text Classification, ULMFit)11。

ULMFit允许我们构建模型来解决特定的NLP任务,同时使用在大型文本语料库上进行训练的预训练语言模型(LM)。

ULMFit包括三个阶段

image.png

1、 LM预训练

ULMFit的第一步是训练深度学习语言模型,以预测大型文本数据集上序列中的下一个单词。

在这种情况下,使用包含1.03亿个单词的WikiText-103数据集来训练最新的语言模型AWD-LSTM(https://arxiv.org/pdf/1708.02182.pdf)。

训练语言模型仅执行一次,并且生成的LM可以用于不同的任务。在此阶段结束时,该模型已学习了训练数据集中提供的语言的一般特征和英语句子的结构。


2、 LM微调

此步骤用于我们要解决的NLP任务。通过使用前面步骤中的预训练语言模型,我们将对目标数据的LM进行微调。

作者建议使用判别式微调,该微调包括对每一层参数使用特定的学习速率和斜三角学习率(STLR),其中学习速率根据本文公式11给出的具体更新时间表,首先线性增加,然后线性衰减。语言模型的架构如下所示:

image.png


3、分类器微调

在对目标数据进行LM微调之后,我们将模型扩展为两个线性层,最后一层为softmax,以使概率分布在数据集的各个类别上。这些层中的每一个都使用批处理规范化、退出和ReLu激活。

使用逐步解冻和斜三角学习率对生成的分类器在目标任务上进行微调。

作者在论文中解释说,同时训练分类器的所有层可能会导致“灾难性的遗忘”。他们建议从最后一层开始逐步解冻模型的各层。

首先解冻最后一层,并在一个epoch中对所有未冻结层进行微调。然后解冻下一个较低的冻结层,重复此过程直到微调所有层到最后一次迭代收敛为止。

image.png


对于实现,我们使用fast.ai 12库,因为它提供了必要的blocks和工具来微调ULMFit。

ulmfit / 01_ulmfit_balanced_dataset.ipynb中提供了用于训练和保存模型的代码。点击链接下载完整数据集上训练的模型。

GitHub:

https://github.com/imadelh/NLP-news-classification/releases/download/v1.0/ulmfit_model

image.png


部署方式


为了将训练好的模型提供给用户,我们将使用Flask和Gunicorn构建一个简单的API,这个API使用测试数据集生成的或者用户给出的标题,并输出前3个预测。推断在CPU上完成。

  • 对于sklearn模型,使用Joblib导出经过训练的模型。 为了进行推断,我们创建了一个模型程序包app / ml_models / model_package_sklearn.py,它接受原始文本并执行所有预处理(就像在培训期间所做的那样),然后生成预测。

  • ULMFit-代码:在这种情况下,我们还将创建一个模型包app / ml_models / model_package_ulmfit.py,该模型使用相关模型并对原始文本进行必要的预处理,然后返回相关的前3个预测。

使用Docker为应用程序创建一个容器,然后将其部署在云实例或无服务器容器服务(例如Google Run)上。

部署详细信息在Github:

https://github.com/imadelh/NLP-news-classification

结论

在这篇文章中,我们使用TF-IDF等经典方法建立了一个文本分类的机器学习模型,然后我们使用ULMFit等更现代的模型演示了如何提高性能。

本文中建议的解决方案可以看作是机器学习项目中的第一个迭代。对该问题以及其他算法进行详细的研究,可以帮助我们获得更好的性能。

最后,这里是NLP可以解决的不同问题的列表:文本分类和分类,命名实体识别,词性标记,语义分析和问题回答,意译检测,语言生成和多文档摘要,机器翻译,语音识别,字符识别,拼写检查。

原文链接:

https://imadelhanafi.com/posts/text_classification_ulmfit/

THE END

免责声明:本文来自互联网新闻客户端自媒体,不代表本网的观点和立场。

合作及投稿邮箱:E-mail:editor@tusaishared.com

上一篇:如何用 Python 和深度迁移学习做文本分类?

下一篇:关于深度学习中的卷积神经网络,你需要知道这些

用户评价
全部评价

热门资源

  • 应用笔画宽度变换...

    应用背景:是盲人辅助系统,城市环境中的机器导航...

  • GAN之根据文本描述...

    一些比较好玩的任务也就应运而生,比如图像修复、...

  • 端到端语音识别时...

    从上世纪 50 年代诞生到 2012 年引入 DNN 后识别效...

  • 人体姿态估计的过...

    人体姿态估计是计算机视觉中一个很基础的问题。从...

  • 谷歌发布TyDi QA语...

    为了鼓励对多语言问答技术的研究,谷歌发布了 TyDi...