近期阅读了一些深度学习在文本分类中的应用相关论文(论文笔记:http://t.cn/RHea2Rs ),同时也参加了 CCF 大数据与计算智能大赛(BDCI)2017 的一个文本分类问题的比赛:让 AI 当法官,并取得了最终评测第四名的成绩 (比赛的具体思路和代码参见 github 项目 repo:http://t.cn/RHeaczg )。因此,本文总结了文本分类相关的深度学习模型、优化思路以及今后可以进行的一些工作。
文本分类任务介绍
文本分类是自然语言处理的一个基本任务,试图推断出给定的文本(句子、文档等)的标签或标签集合。
文本分类的应用非常广泛。如:
垃圾邮件分类:二分类问题,判断邮件是否为垃圾邮件 情感分析二分类问题,判断文本情感是积极 (positive) 还是消极 (negative) 多分类问题,判断文本情感属于 {非常消极,消极,中立,积极,非常积极} 中的哪一类 新闻主题分类:判断新闻属于哪个类别,如财经、体育、娱乐等 自动问答系统中的问句分类 社区问答系统中的问题分类:多标签分类,如知乎看山杯(http://t.cn/RHeSSzM ) 更多应用:让 AI 当法官(http://t.cn/RHeaczg ): 基于案件事实描述文本的罚金等级分类(多分类)和法条分类(多标签分类)。 判断新闻是否为机器人所写(http://t.cn/RO5u0Ik ): 二分类 ...... 不同类型的文本分类往往有不同的评价指标,具体如下:
二分类:accuracy,precision,recall,f1-score,(http://t.cn/RqSDNXI )... 多分类: Micro-Averaged-F1, Macro-Averaged-F1, ... 多标签分类:Jaccard 相似系数, ... 传统机器学习方法
传统的机器学习方法主要利用自然语言处理中的 n-gram 概念对文本进行特征提取,并且使用 TFIDF 对 n-gram 特征权重进行调整,然后将提取到的文本特征输入到 Logistics 回归、SVM 等分类器中进行训练。但是,上述的特征提取方法存在数据稀疏 和维度爆炸 等问题,这对分类器来说是灾难性的,并且使得训练的模型泛化能力有限。因此,往往需要采取一些策略进行降维:
人工降维:停用词过滤,低频 n-gram 过滤等 自动降维:LDA 等 值得指出的是,将深度学习中的 word2vec,doc2vec 作为文本特征与上文提取的特征进行融合,常常可以提高模型精度。
CNN 用于文本分类
论文 Convolutional Neural Networks for Sentence Classification(http://t.cn/RHeoxpT )提出了使用 CNN 进行句子分类的方法。
CNN 模型推导 一个句子是由多个词拼接而成的,如果一个句子有n个词,且第 i 个词表示为x_{i} ,词x_{i} 通过 embedding 后表示为 k 维的向量,即x_{i} \in \Re^k ,则一个句子x_{i:n} 为n∗k的矩阵,可以形式化如下:
X1:n=x1⊕x2⊕⋯⊕xn 一个包含hh个的词的词窗口表示为:x_{i:i+h-1} \in \Re^{hk} 一个 filter 是大小为h∗k的矩阵,表示为:W \in \Re^{hk} 通过一个 filter 作用一个词窗口提取可以提取一个特征c_{i} ,如下:c_{i}=f(W \centerdot X_{i:i+h-1}+b) 其中,b\in \Re 是 bias 值,ff为激活函数如 Relu 等。
卷积操作:通过一个 filter 在整个句子上从句首到句尾扫描一遍,提取每个词窗口的特征,可以得到一个特征图 (feature map)C\in \Re^{n-h+1} ,表示如下 (这里默认不对句子进行 padding):c=[c1,c2,…,cn−h+1] 池化操作:对一个 filter 提取到的 feature map 进行 max pooling,得到\widehat{c} \in \Re 即:\widehat{c}= max(c) 若有m个 filter,则通过一层卷积、一层池化后可以得到一个长度为m的向量z\in \Re^m :z=[\widehat{c}_{1},\widehat{c}_{2},...,\widehat{c}_{m}] 最后,将向量z输入到全连接层,得到最终的特征提取向量y(这里的W为全连接层的权重,注意与 filter 进行区分):y=W⋅z+b 优化 CNN 模型 词向量 随机初始化 (CNN-rand) 预训练词向量进行初始化,在训练过程中固定 (CNN-static) 预训练词向量进行初始化,在训练过程中进行微调 (CNN-non-static) 多通道 (CNN-multichannel): 将固定的预训练词向量和微调的词向量分别当作一个通道 (channel),卷积操作同时在这两个通道上进行,可以类比于图像 RGB 三通道。 上图为模型架构示例,在示例中,句长n=9n=9,词向量维度k=6k=6,filter 有两种窗口大小(或者说 kernel size),每种有 2 个,因此 filter 总个数m=4m=4,其中:一种的窗口大小h=2h=2(红色框),卷积后的向量维度为n−h+1=8n−h+1=8 另一种窗口大小h=3h=3(黄色框),卷积后的向量维度为n−h+1=7n−h+1=7
(论文原图中少画了一个维度,感谢 @shoufengwei 指正) 正则化
Dropout: 对全连接层的输入zz向量进行 dropouty=W \cdot(z \cdot r)+b 其中r\in \Re^{m} 为 masking 向量(每个维度值非 0 即 1,可以通过伯努利分布随机生成),和向量z进行元素与元素对应相乘,让r向量值为 0 的位置对应的z向量中的元素值失效(梯度无法更新)。
L2-norms: 对 L2 正则化项增加限制:当正则项||W||_{2}=s 时, 令||W||_{2}=s ,其中s为超参数。 一些结论 Multichannel vs. Single Channel Models: 虽然作者一开始认为多通道可以预防过拟合,从而应该表现更高,尤其是在小规模数据集上。但事实是,单通道在一些语料上比多通道更好; Static vs. Non-static Representations: 在大部分的语料上,CNN-non-static 都优于 CNN-static,一个解释:预训练词向量可能认为‘good’和‘bad’类似(可能它们有许多类似的上下文),但是对于情感分析任务,good 和 bad 应该要有明显的区分,如果使用 CNN-static 就无法做调整了; Dropout 可以提高 2%–4% 性能 (performance); 对于不在预训练的 word2vec 中的词,使用均匀分布U[-a,a] 随机初始化,并且调整aa使得随机初始化的词向量和预训练的词向量保持相近的方差,可以有微弱提升;
可以尝试其他的词向量预训练语料,如 Wikipedia[Collobert et al. (2011)] Adadelta(Zeiler, 2012) 和 Adagrad(Duchi et al., 2011) 可以得到相近的结果,但是所需 epoch 更少。 进一步思考 CNN 为什么 CNN 能够用于文本分类(NLP)? filter 相当于 N-gram ?(http://t.cn/RoN3rFb )
filter 只提取局部特征?全局特征怎么办?可以融合吗?
RNN 可以提取全局特征 RCNN(下文说明): RNN 和 CNN 的结合 3.4.2 超参数怎么调? 论文 A Sensitivity Analysis of (and Practitioners' Guide to) Convolutional Neural Networks for Sentence Classification(http://t.cn/RHepR6w ) 提供了一些策略。
用什么样的词向量使用预训练词向量比随机初始化的效果要好 采取微调策略(non-static)的效果比固定词向量(static)的效果要好 无法确定用哪种预训练词向量 (Google word2vec / GloVe representations) 更好,不同的任务结果不同,应该对于你当前的任务进行实验; filter 窗口大小、数量在实践中,100 到 600 是一个比较合理的搜索空间。 每次使用一种类型的 filter 进行实验,表明 filter 的窗口大小设置在 1 到 10 之间是一个比较合理的选择。 首先在一种类型的 filter 大小上执行搜索,以找到当前数据集的 “最佳” 大小,然后探索这个最佳大小附近的多种 filter 大小的组合。 每种窗口类型的 filter 对应的 “最好” 的 filter 个数 (feature map 数量) 取决于具体数据集; 但是,可以看出,当 feature map 数量超过 600 时,performance 提高有限,甚至会损害 performance,这可能是过多的 feature map 数量导致过拟合了; 激活函数 (tanh, relu, ...)Sigmoid, Cube, and tanh cube 相较于 Relu 和 Tanh 的激活函数,表现很糟糕; tanh 比 sigmoid 好,这可能是由于 tanh 具有 zero centering property(过原点); 与 Sigmoid 相比,ReLU 具有非饱和形式 (a non-saturating form) 的优点,并能够加速 SGD 的收敛。 对于某些数据集,线性变换 (Iden,即不使用非线性激活函数) 足够捕获词嵌入与输出标签之间的相关性。(但是如果有多个隐藏层,相较于非线性激活函数,Iden 就不太适合了,因为完全用线性激活函数,即使有多个隐藏层,组合后整个模型还是线性的,表达能力可能不足,无法捕获足够信息); 因此,建议首先考虑 ReLU 和 tanh,也可以尝试 Iden 池化策略:最大池化就是最好的吗对于句子分类任务,1-max pooling 往往比其他池化策略要好; 这可能是因为上下文的具体位置对于预测 Label 可能并不是很重要,而句子某个具体的 n-gram(1-max pooling 后 filter 提取出来的的特征) 可能更可以刻画整个句子的某些含义,对于预测 label 更有意义; (但是在其他任务如释义识别 ,k-max pooling 可能更好。) 正则化0.1 到 0.5 之间的非零 dropout rates 能够提高一些 performance(尽管提升幅度很小),具体的最佳设置取决于具体数据集; 对 l2 norm 加上一个约束往往不会提高 performance(除了 Opi 数据集); 当 feature map 的数量大于 100 时,可能导致过拟合,影响 performance,而 dropout 将减轻这种影响; 在卷积层上进行 dropout 帮助很小,而且较大的 dropout rate 对 performance 有坏的影响。 字符级别的 CNN 用于文本分类 论文 Character-level convolutional networks for text classification(http://t.cn/RHe037w ) 将文本看成字符级别的序列,使用字符级别(Character-level)的 CNN 进行文本分类。
字符级 CNN 的模型设计 首先需要对字符进行数字化(quantization)。具体如下:
定义字母表 (Alphabet):大小为m (对于英文 m=70,如下图,之后会考虑将大小写字母都包含在内作为对比) 字符数字化(编码): "one-hot" 编码 序列(文本)长度:l_{0} (定值)
然后论文设计了两种类型的卷积网络:Large 和 Small (作为对照实验) 它们都有 9 层,其中 6 层为卷积层 (convolutional layer);3 层为全连接层 (fully-connected layer): Dropout 的概率都为 0.5 使用高斯分布 (Gaussian distribution) 对权重进行初始化: 最后一层卷积层单个 filter 输出特征长度 (the output frame length)为l_{6}=(l_{0}-96)/27 ,推 第一层全连接层的输入维度 (其中 1024 和 256 为 filter 个数或者说 frame/feature size): 下图为模型的一个图解示例。其中文本长度为 10,第一层卷积的 kernel size 为 3(半透明黄色正方形),卷积个数为 9(Feature=9),步长为 1,因此 Length=10-3+1=8,然后进行非重叠的 max-pooling(即 pooling 的 stride=size),pooling size 为 2,因此池化后的 Length = 8 / 2 = 4。
字符级 CNN 的相关总结与思考 字符级 CNN 是一个有效的方法 数据集的大小可以为选择传统方法还是卷积网络模型提供指导 :对于几百上千等小规模数据集,可以优先考虑传统方法,对于百万规模的数据集,字符级 CNN 开始表现不错。字符级卷积网络很适用于用户生成数据 (user-generated data) (如拼写错误,表情符号等),没有免费的午餐 (There is no free lunch) 中文怎么办 中文中的同音词非常多,如何克服? 如果把中文中的每个字作为一个字符,那么字母表将非常大 是否可以把中文先转为拼音 (pinyin)? 论文 Character-level Convolutional Network for Text Classification Applied to Chinese Corpus(https://arxiv.org/abs/1611.04358 )进行了相关实验。 将字符级和词级进行结合是否结果更好 使用同义词表进行数据增强 对于深度学习模型,采用适当的数据增强 (Data Augmentation) 技术可以提高模型的泛化能力。数据增强在计算机视觉领域比较常见,例如对图像进行旋转,适当扭曲,随机增加噪声等操作。对于 NLP,最理想的数据增强方法是使用人类复述句子(human rephrases of sentences),但是这比较不现实并且对于大规模语料来说代价昂贵。
一个更自然的选择是使用词语或短语的同义词或同义短语进行替换,从而达到数据增强的目的。具体做法如下:
英文同义词典: from the mytheas component used in LibreOffice1 project. http://www.libreoffice.org/ 从给定的文本中抽取出所有可以替换的词,然后随机选择rr个进行替换,其中rr由一个参数为pp的几何分布 (geometric distribution) 确定,即P[r]\sim p^r 给定一个待替换的词,其同义词可能有多个(一个列表),选择第ss个的概率也通过另一个几何分布确定,即P[s]\sim q^s 。这样是为了当前词的同义词列表中的距离较远 (ss较大) 的同义词被选的概率更小。
RNN 用于文本分类
策略 1:直接使用 RNN 的最后一个单元输出向量作为文本特征 策略 2:使用双向 RNN 的两个方向的输出向量的连接(concatenate)或均值作为文本特征 策略 3:将所有 RNN 单元的输出向量的均值 pooling 或者 max-pooling 作为文本特征 策略 4:层次 RNN+Attention, Hierarchical Attention Networks(https://www.cs.cmu.edu/~diyiy/docs/naacl16.pdf) RCNN(RNN+CNN)用于文本分类
论文 Recurrent Convolutional Neural Networks for Text Classification(http://t.cn/RHeTMTZ ) 设计了一种 RNN 和 CNN 结合的模型用于文本分类。 RCNN 模型推导 词表示学习 使用双向 RNN 分别学习当前词w_{i} 的左上下文表示c_{i}(w_{i}) 和右上下文表示c_{r}(w_{i}) ,再与当前词自身的表示e(w_{i}) 连接,构成卷积层的输入x_{i} 。具体如下:
然后将x_{i} 作为w_{i} 的表示,输入到激活函数为 tanh,kernel size 为 1 的卷积层,得到w_{i} 的潜在语义向量 (latent semantic vector)
将 kernel size 设置为 1 是因为x_{i} 中已经包含w_{i} 左右上下文的信息,无需再使用窗口大于 1 的 filter 进行特征提取。但是需要说明的是,在实践中仍然可以同时使用多种 kernel size 的 filter,如 [1, 2, 3],可能取得更好的效果,一种可能的解释是窗口大于 1 的 filter 强化了w_{i} 的左右最近的上下文信息。此外,实践中可以使用更复杂的 RNN 来捕获w_{i} 的上下文信息如 LSTM 和 GRU 等。
文本表示学习
经过卷积层后,获得了所有词的表示,然后在经过最大池化层和全连接层得到文本的表示,最后通过 softmax 层进行分类。具体如下:
Softmax layer:
下图为上述过程的一个图解: RCNN 相关总结 NN vs. traditional methods: 在该论文的所有实验数据集上,神经网络比传统方法的效果都要好 Convolution-based vs. RecursiveNN: 基于卷积的方法比基于递归神经网络的方法要好 RCNN vs. CFG and C&J: The RCNN 可以捕获更长的模式 (patterns) RCNN vs. CNN: 在该论文的所有实验数据集上,RCNN 比 CNN 更好 CNNs 使用固定的词窗口 (window of words), 实验结果受窗口大小影响 RCNNs 使用循环结构捕获广泛的上下文信息 一定要 CNN/RNN 吗
上述的深度学习方法通过引入 CNN 或 RNN 进行特征提取,可以达到比较好的效果,但是也存在一些问题,如参数较多导致训练时间过长,超参数较多模型调整麻烦等。下面两篇论文提出了一些简单的模型用于文本分类,并且在简单的模型上采用了一些优化策略。
深层无序组合方法 论文 Deep Unordered Composition Rivals Syntactic Methods for Text Classification(http://t.cn/RHeQmNe ) 提出了 NBOW (Neural Bag-of-Words) 模型和 DAN (Deep Averaging Networks) 模型。对比了深层无序组合方法 (Deep Unordered Composition) 和句法方法 (Syntactic Methods) 应用在文本分类任务中的优缺点,强调深层无序组合方法的有效性、效率以及灵活性。
Neural Bag-of-Words Models 论文首先提出了一个最简单的无序模型 Neural Bag-of-Words Models (NBOW model)。该模型直接将文本中所有词向量的平均值作为文本的表示,然后输入到 softmax 层,形式化表示如下:
Considering Syntax for Composition 一些考虑语法的方法:
Recursive neural networks (RecNNs ) 可以考虑一些复杂的语言学现象,如否定、转折等 (优点 ) 实现效果依赖输入序列(文本)的句法树(可能不适合长文本和不太规范的文本) 需要更多的训练时间 Using a convolutional network instead of a RecNN 时间复杂度同样比较大,甚至更大(通过实验结果得出的结论,这取决于 filter 大小、个数等超参数的设置) Deep Averaging Networks Deep Averaging Networks (DAN ) 是在 NBOW model 的基础上,通过增加多个隐藏层,增加网络的深度 (Deep)。下图为带有两层隐藏层的 DAN 与 RecNN 模型的对比。
Word Dropout Improves Robustness 针对 DAN 模型,论文提出一种 word dropout 策略:在求平均词向量前,随机使得文本中的某些单词 (token) 失效。形式化表示如下:
Word Dropout 可能会使得某些非常重要的 token 失效。然而,使用 word dropout 往往确实有提升,这可能是因为,一些对标签预测起到关键性作用的 word 数量往往小于无关紧要的 word 数量。例如,对于情感分析任务,中立 (neutral) 的单词往往是最多的。 Word dropout 同样可以用于其他基于神经网络的方法。 Word Dropout 或许起到了类似数据增强 (Data Augmentation) 的作用? fastText
论文 Bag of Tricks for Efficient Text Classification(http://t.cn/RHe8pd5 ) 提出一个快速进行文本分类的模型和一些 trick。
fastText 模型架构 fastText 模型直接对所有进行 embedded 的特征取均值,作为文本的特征表示,如下图。
特点 当类别数量较大时,使用 Hierachical Softmax 将 N-gram 融入特征中,并且使用 Hashing trick[Weinberger et al.2009,http://t.cn/RHe8dus ] 提高效率 最新研究 根据 github repo: state-of-the-art-result-for-machine-learning-problems ,下面两篇论文提出的模型可以在文本分类取得最优的结果 (让 AI 当法官比赛第一名使用了论文 Learning Structured Text Representations 中的模型):Learning Structured Text Representations Attentive Convolution 论文 Multi-Task Label Embedding for Text Classification 认为标签与标签之间有可能有联系,所以不是像之前的深度学习模型把标签看成 one-hot vector,而是对每个标签进行 embedding 学习,以提高文本分类的精度。 References [1] Le and Mikolov - 2014 - Distributed representations of sentences and documents
[2] Kim - 2014 - Convolutional neural networks for sentence classification
[3] Zhang and Wallace - 2015 - A Sensitivity Analysis of (and Practitioners' Guide to) Convolutional Neural Networks for Sentence Classification
[4] Zhang et al. - 2015 - Character-level convolutional networks for text classification
[5] Lai et al. - 2015 - Recurrent Convolutional Neural Networks for Text Classification
[6] Iyyer et al. - 2015 - Deep unordered composition rivals syntactic methods for Text Classification
[7] Joulin et al. - 2016 - Bag of tricks for efficient text classification
[8] Liu and Lapata - 2017 - Learning Structured Text Representations
[9] Yin and Schütze - 2017 - Attentive Convolution
[10] Zhang et al. - 2017 - Multi-Task Label Embedding for Text Classification