做者:尘心
连接:https://zhuanlan.zhihu.com/p/76003775
git
文本分类在文本处理中是很重要的一个模块,它的应用也很是普遍,好比:垃圾过滤,新闻分类,词性标注等等。它和其余的分类没有本质的区别,核心方法为首先提取分类数据的特征,而后选择最优的匹配,从而分类。可是文本也有本身的特色,根据文本的特色,文本分类的通常流程为:1.预处理;2.文本表示及特征选择;3.构造分类器;4.分类。github
一般来说,文本分类任务是指在给定的分类体系中,将文本指定分到某个或某几个类别中。被分类的对象有短文本,例如句子、标题、商品评论等等,长文本,如文章等。分类体系通常人工划分,例如:1)政治、体育、军事 2)正能量、负能量 3)好评、中性、差评。所以,对应的分类模式能够分为:二分类与多分类问题。算法
文本分类的应用十分普遍,能够将其应用在:网络
文本分类问题算是天然语言处理领域中一个很是经典的问题了,相关研究最先能够追溯专家规则(Pattern)进行分类,但显然费时费力,覆盖的范围和准确率都很是有限。app
后来伴随着统计学习方法的发展,特别是90年代后互联网在线文本数量增加和机器学习学科的兴起,逐渐造成了人工特征工程+浅层分类建模流程。框架
传统作法主要问题的文本表示是高纬度高稀疏的,特征表达能力很弱,此外须要人工进行特征工程,成本很高。而深度学习最初在图像和语音取得巨大成功,也相应的推进了深度学习在NLP上的发展,使得深度学习的模型在文本分类上也取得了不错的效果。dom
传统的机器学习分类方法将整个文本分类问题就拆分红了特征工程和分类器两部分。特征工程分为文本预处理、特征提取、文本表示三个部分,最终目的是把文本转换成计算机可理解的格式,并封装足够用于分类的信息,即很强的特征表达能力。机器学习
3.1.1 文本预处理:函数
文本预处理过程是在文本中提取关键词表示文本的过程,中文文本处理中主要包括文本分词和去停用词两个阶段。之因此进行分词,是由于不少研究代表特征粒度为词粒度远好于字粒度,其实很好理解,由于大部分分类算法不考虑词序信息。性能
中文分词技术:
1)基于字符串匹配的分词方法:
过程:这是一种基于词典的中文分词,核心是首先创建统一的词典表,当须要对一个句子进行分词时,首先将句子拆分红多个部分,将每个部分与字典一一对应,若是该词语在词典中,分词成功,不然继续拆分匹配直到成功。
核心: 字典,切分规则和匹配顺序是核心。
分析:优势是速度快,时间复杂度能够保持在O(n),实现简单,效果尚可;但对歧义和未登陆词处理效果不佳。
2)基于理解的分词方法:
基于理解的分词方法是经过让计算机模拟人对句子的理解,达到识别词的效果。其基本思想就是在分词的同时进行句法、语义分析,利用句法信息和语义信息来处理歧义现象。它一般包括三个部分:分词子系统、句法语义子系统、总控部分。在总控部分的协调下,分词子系统能够得到有关词、句子等的句法和语义信息来对分词歧义进行判断,即它模拟了人对句子的理解过程。这种分词方法须要使用大量的语言知识和信息。因为汉语语言知识的笼统、复杂性,难以将各类语言信息组织成机器可直接读取的形式,所以目前基于理解的分词系统还处在试验阶段。
3)基于统计的分词方法:
过程:统计学认为分词是一个几率最大化问题,即拆分句子,基于语料库,统计相邻的字组成的词语出现的几率,相邻的词出现的次数多,就出现的几率大,按照几率值进行分词,因此一个完整的语料库很重要。
主要的统计模型有: N元文法模型(N-gram),隐马尔可夫模型(Hidden Markov Model ,HMM),最大熵模型(ME),条件随机场模型(Conditional Random Fields,CRF)等。
英文分词技术:
英文分词相比中文分词要简单得多,能够根据空格和标点符号来分词,而后对每个单词进行词干还原和词形还原,去掉停用词和非英文内容
3.1.2 文本表示:
将文本转换成计算机可理解的方式。一篇文档表示成向量,整个语料库表示成矩阵
词袋法:
忽略其词序和语法,句法,将文本仅仅看作是一个词集合。若词集合共有NN个词,每一个文本表示为一个NN维向量,元素为0/1,表示该文本是否包含对应的词。( 0, 0, 0, 0, .... , 1, ... 0, 0, 0, 0)
通常来讲词库量至少都是百万级别,所以词袋模型有个两个最大的问题:高纬度、高稀疏性
n-gram词袋模型:
与词袋模型相似,考虑了局部的顺序信息,可是向量的维度过大,基本不采用。若是词集合大小为N,则bi-gram的单词总数为N2向量空间模型
向量空间模型:
以词袋模型为基础,向量空间模型经过特征选择下降维度,经过特征权重计算增长稠密性。
特征权重计算:
通常有布尔权重、TFIDF型权重、以及基于熵概念权重这几种方式,其中布尔权重是指若出现则为1,不然为0,也就是词袋模型;而TFIDF则是基于词频来进行定义权重;基于熵的则是将出如今同一文档的特征赋予较高的权重。
3.1.3 机器学习分类器
将文本表示为模型能够处理的向量数据后,就可使用机器学习模型来进行处理,经常使用的模型有:
上文介绍了传统的文本分类作法,传统作法主要问题的文本表示是高纬度高稀疏的,特征表达能力很弱,并且神经网络很不擅长对此类数据的处理;此外须要人工进行特征工程,成本很高。应用深度学习解决大规模文本分类问题最重要的是解决文本表示,再利用CNN/RNN等网络结构自动获取特征表达能力,去掉繁杂的人工特征工程,端到端的解决问题。
论文:Bag of Tricks for Efficient Text Classification
第一步:输入层
在word2vec中,它的输入就是单纯的把词袋向量化。可是在fasttext还加入了n-grams的思想。举个例子“我 喜欢 她“,若是只用这几个词的组合来反映这个句子,就是(”我”,”喜欢”,”她”),问题来了,句子“她 喜欢 我”的词的组合也是(”我”,”喜欢”,”她”),但这两个句子的意思彻底不一样,因此若是只用句子里的词来表明这个句子的意思,是不许确的,因此咱们要加入n-grams,好比说取n=2,那么此时句子“我 喜欢 她“的词语组合就是(”我”,”喜欢”,”她”,”我喜欢”,”喜欢她”)这就和句子”她喜欢我”所获得的词语组合不一样了,咱们也能所以区分开这两个句子。
因此此时咱们的输入就是(”我”,”喜欢”,”她”,”我喜欢”,”喜欢她”)向量化后的5个向量,词向量化参照。
第二步:中间层
其实这一步的思想更加朴素,就是将第一步中输入的向量相加再求平均,获得一个新的向量w,而后将这个向量输入到输出层。
第三步:输出层
采用了层次softmax的方法,思想实质上是将一个全局多分类的问题,转化成为了若干个二元分类问题,从而将计算复杂度从O(V)降到O(logV)。既根据label的频次创建哈夫曼树,每一个label对应一个哈夫曼编码,每一个哈夫曼树节点具备一个向量做为参数进行更新,预测的时候隐层输出与每一个哈夫曼树节点向量作点乘,根据结果决定向左右哪一个方向移动,最终落到某个label对应的节点上。
代码连接:https://github.com/liyibo/text-classification-demos
论文:Convolutional Neural Networks for Sentence Classification
模型
详细原理图:
TextCNN详细过程:
注:考虑了卷积核具备局部感觉野的特性
代码连接:https://github.com/liyibo/text-classification-demos
论文:Recurrent Neural Network for Text Classification with Multi-Task Learning
利用CNN进行文本分类,说到底仍是利用卷积核寻找n-gram特征。卷积核的大小是超参。而RNN则能够处理时间序列,它经过先后时刻的输出连接保证了“记忆”的留存。但RNN循环机制过于简单,先后时刻的连接采用了最简单的f=activate(ws+b)。这样在梯度反向传播时出现了时间上的连乘操做,从而致使了梯度消失和梯度爆炸的问题。RNN的变种LSTM/GRU在必定程度上减缓了梯度消失和梯度爆炸问题,所以如今使用的其实要比RNN更多。
利用RNN作文本分类也比较好理解,其实就是一个N vs 1模型。对于英文,都是基于词的。对于中文,首先要肯定是基于字的仍是基于词的。若是是基于词,要先对句子进行分词。以后,每一个字/词对应RNN的一个时刻,隐层输出做为下一时刻的输入。最后时刻的隐层输出h为整个句子的抽象特征,再接一个softmax进行分类。
详细的RNN的解释能够参考连接:https://zhuanlan.zhihu.com/p/28054589
代码连接:https://github.com/liyibo/text-classification-demos
论文:Recurrent Convolutional Neural Networks for Text Classification
RCNN算法过程:
首先,采用双向LSTM学习word的上下文
c_left = tf.concat([tf.zeros(shape), output_fw[:, :-1]], axis=1, name="context_left")
c_right = tf.concat([output_bw[:, 1:], tf.zeros(shape)], axis=1, name="context_right")
word_representation = tf.concat([c_left, embedding_inputs, c_right], axis=2, name="last")
以后再接跟TextCNN相同卷积层,pooling层便可,在seq_length维度进行 max pooling,而后进行fc操做就能够进行分类了,能够将该网络当作是fasttext 的改进版本。
代码连接:https://github.com/liyibo/text-classification-demos
论文:Hierarchical Attention Network for Document Classification
HAN为Hierarchical Attention Networks,将待分类文本,分为必定数量的句子,分别在word level和sentence level进行encoder和attention操做,从而实现对较长文本的分类。
本文是按照句子长度将文本分句的,实际操做中可按照标点符号等进行分句,理论上效果能好一点。
算法流程:
论文:Deep Pyramid Convolutional Neural Networks for Text Categorization
DPCNN主要的特点是引入了残差结构,增长了多尺度信息,而且增长了用于文本分类CNN的网络深度,以提取文本中远程关系特哼,而且并无带来较高的复杂度。实验代表,其效果比普通CNN结构要好。
代码连接:https://github.com/liyibo/text-classification-demos
Bert:
论文:BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding
BERT是一种预训练语言表示的方法,他将NLP模型的创建分为了两个阶段:Pre-training和fine-tuning。Pre-training是为了在大量文本语料(维基百科)上训练了一个通用的“语言理解”模型,而后用这个模型去执行想作的NLP任务。Fine-training则是在具体的NLP任务上进行相应的微调学习。
Bert模型结构主要是采用了transformer的编码结构,其主要创新点在于其训练方式采用了1)它在训练双向语言模型时以减少的几率把少许的词替成了Mask或者另外一个随机的词。感受其目的在于使模型被迫增长对上下文的记忆。2)增长了一个预测下一句的loss,迫使模型学习到句子之间的关系。
输入表示:
论文的输入表示(input representation)可以在一个token序列中明确地表示单个文本句子或一对文本句子(例如, [Question, Answer])。对于给定token,其输入表示经过对相应的token、segment和position embeddings进行求和来构造。图2是输入表示的直观表示:
关键创新:预训练任务
任务1: Masked LM
为了训练一个深度双向表示(deep bidirectional representation),研究团队采用了一种简单的方法,即随机屏蔽(masking)部分输入token,而后只预测那些被屏蔽的token。
数据生成器将执行如下操做,而不是始终用[MASK]替换所选单词:
任务2:下一句预测
在为了训练一个理解句子的模型关系,预先训练一个二进制化的下一句测任务,这一任务能够从任何单语语料库中生成。具体地说,当选择句子A和B做为预训练样本时,B有50%的多是A的下一个句子,也有50%的多是来自语料库的随机句子。
经过采用以上两种预训练方式,使得模型可以具备语义表征性质,在fine-tuning阶段就能够搭连一个NN结构完成文本分类任务。
代码连接:https://github.com/google-research/bert
论文:Densely Connected CNN with Multi-scale Feature Attention for Text Classification
若是说DPCNN算法是借鉴了计算机视觉中ResNet模型中残差块的想法,那么Densely Connected CNN则是借鉴了DenseNet的密集型链接的作法。Densely Connected CNN主要采用short-cut操做将以前卷积提取出的feature加入到后续层的输入,增长了多尺度信息的提取,使得卷积器真正观测到的原始句子序列中的视野是愈来愈大的。其次,模型对不一样尺度的feature采用了attention的作法,使得模型更好的利用feature信息。
代码连接:
https://github.com/wangshy31/Densely-Connected-CNN-withMultiscale-Feature-Attention.git
论文:Graph Convolutional Networks for Text Classification
图中节点的数量是单词数量+文档数量,O开头的是文档节点,其余的是词节点。图中黑线的线表明文档-词的边,灰色的表示词-词的边。R(x)表示x的embedding表示。节点的不一样颜色表明文档的不一样类型。
本文提出的TextGCN的初始输入向量是词和文档所有用one-hot编码表示。文档-词的边基于词在文档中的出现信息,使TF-ID做为边的权重。词-词的连边基于词的全局词共现信息。词共现信息使用一个固定大小的滑动窗口在语料库中滑动统计词共现信息,而后使用点互信息(PMI)计算两个词节点连线的权重。
这里的A是图G的邻接矩阵,D是图G的度矩阵。W0和W1分别是GCN第一层和第二层可学习的卷积核权重,也是须要被训练学习的。X是输入特征矩阵,是与节点数相同的维度的对角方形矩阵,这意味着输入是图中每一个节点的one-hot编码。最后将输出送到具备softmax函数的层,用于文本的分类。
代码连接:https://github.com/yao8839836/text_gcn
论文:Investigating Capsule Networks with Dynamic Routing for Text Classification
Zhao等人提出了一种基于胶囊网络的文本分类模型,并改进了Sabour等人提出的动态路由,提出了三种稳定动态路由。模型以下所示:
该模型首先利用标准的卷积网络,经过多个卷积滤波器提取句子的局部语义表征。而后将CNN的标量输出替换为向量输出胶囊,从而构建Primary Capsule层。接着输入到做者提出的改进的动态路由(共享机制的动态路由和非共享机制的动态路由),获得卷积胶囊层。最后将卷积胶囊层的胶囊压平,送入到全链接胶囊层,每一个胶囊表示属于每一个类别的几率。
代码连接:https://github.com/andyweizhao/capsule_text_classification.
论文:Variational Pretraining for Semi-supervised Text Classification
此篇论文讲述,通常的半监督的文本分类模型基于大量数据和高昂计算力,致使他们在资源受限的环境下使用受限。因而,做者提出了一种基于预训练半监督的文本分类轻量型模型。
此模型称之为VAMPIRE,它将variational autoencoder与document modeling相结合。
算法流程:
代码连接:http://github.com/allenai/vampire
论文:XLNet: Generalized Autoregressive Pretraining for Language Understanding
XLNet引入了自回归语言模型(根据上文内容预测下一个可能跟随的单词,就是常说的自左向右的语言模型任务)以及自编码语言模型(只能根据上文预测下一个单词,或者反过来,只能根据下文预测前面一个单词)的想法,可以同时利用上文和下文,因此信息利用充分。而BERT则是在第一个预训练阶段由于采起引入[Mask]标记来Mask掉部分单词的训练模式,而Fine-tuning阶段是看不到这种被强行加入的Mask标记的,因此两个阶段存在使用模式不一致的情形,这可能会带来必定的性能损失;另一个是,Bert在第一个预训练阶段,假设句子中多个单词被Mask掉,这些被Mask掉的单词之间没有任何关系,是条件独立的,而有时候这些单词之间是有关系的。
明白了二者的差别后,咱们就容易发现XLNet的思路也就比较简洁,通常来说,自回归语言模型有个缺点,要么从左到右,要么从右到左,若是咱们要根据上文,来预测某个单词Ti,那么它就无法看到下文的内容信息。怎么让模型具备从左向右的输入和预测模式,并且内部又引入了当前单词的上下文信息,则是XLNet主要的创新点。
具体的作法是,XLNet在第一阶段预训练时期,选择舍去mask操做,将顺序输入的句子进行随机排列组合。例如,句子输入顺序为:X1,X2,X3,X4,在transformer阶段采用了Attention掩码机制,将句子顺序变为X4,X2,X1, X三、X3,X2, X1, X4等等这样的序列,这样在X4,X2,X1, X3中,X1即可以看到X4,X2,的信息,在X3,X2, X1, X4序列中,X1即可以看到X3,X2的信息。
如上图所示,咱们在预测X3时,右上角图所示中序列为X2, X4 ,X3,X1,所以在预测X3时,使用了X2, X4的信息,其余图以此类推。
那么Attention掩码机制是什么意思呢?咱们经过上图来进行解释,若是把白色当作掩盖,红色看做为能看到信息,那么在右侧的Attention矩阵中能够看出,咱们一行一行对应来看,就能看到每一个X看到的信息在Attention矩阵中已经表达出来,最后的顺序也就变成了X3X2X4X1。
[此部分为双流自注意力机制]然而,这些都还不够。这种预训练方法可能会带来歧义。在一个句子里,咱们有可能针对不同的目标词,产生出如出一辙的context。仍是用名句"山下一群鹅,嘘声赶落河",假设咱们的分段长度为11,把整个句子(含标点)都包括进来了。这时针对"鹅"字,在众多的排列中,咱们能够有一个天然的序列"山下一群"来预测它。一样针对"河"字,咱们在众多排列中,也能够有一个排序过的序列"山下一群"来预测它。那么如出一辙的序列(“山下一群”)居然用来预测两个不一样的字,这致使了"鹅"和"河"在此时共享同样的模型的预测结果。(参考triplemeng博客)。
为了解决这个问题,一个简单的想法就是引入对位置的依赖,用一个新的函数 表示,经过加入不一样的被预测词的位置,把上述状况区分开了
在模型中,同时利用g和h,所谓的双流即query stream和content stream,在fine-tuning阶段,能够彻底忽略掉第一个公式,仅利用content stream就能够了。
其中:
query stream为:为预测token,只能利用它的位置信息即,但不利用。这里的称为query representation。
content stream为:在预测其余token时,须要编码信息来提供语境信息,因此这里须要content representation,。
代码连接:https://github.com/zihangdai/xlnet
论文:Transformable Convolutional Neural Network for Text Classification
这篇论文主要创新点在于提出了Transformable Convolution 和Transformable Pooling两个处理方式,主要目的在于想经过以上两种方式来获取静态特征信息和动态特征信息。
对于Transformable Convolution(Transformable Pooling也是一样的道理),文章将filter(卷积核)中position(p)的集合称之为C,为了将一部分的position与当前状态的feature相关联,将另外一部分与global信息关联,把C分为了两部分S和D,每一部分单独进行参数更新和计算。如上图右上角,D中信息是经过上层feature map卷积得到的动态信息,而S则是上图底部,经过反向传播更新得到的全局信息。最后将这两种信息经过如下公式进行综合计算。
文章指出,直接采起卷积核在实际使用中不易处理,因此在计算方式上采用了一种mask的方式,使得矩阵相乘时得以实现分块计算。
代码连接:无
论文:Towards Explainable NLP: A Generative Explanation Framework for Text Classification
通常来说,分类模型只会给出一个类别几率分布,没法给出解释性指标,来代表分类是否可信,因此Generative Explanation Framework的想法是:给出一个商品A,它具备quality, practicality, price三个属性,若模型给出商品A为good,而且可以指出分类理由是基于商品A的[quality:HIGH,practicality:HIGH,price:LOW]性质,咱们就认为这样的作法具备可解释性。
所以,该方法数据样本具备三个part:一个商品的描述文本、三个简评、一个整体分数。此框架想经过使用描述文本数据训练一个分类模型获得分类的类别y以及Ppred,以后再利用上图左侧classifier C获得的Pgold ,Pclassified分数,将三个P放入到度量公式EF(s)中获得分类的置信度。
代码连接:无