【TensorFlow小记】CNN文本分类原理

通过学习几篇不错的文章,再结合自己的理解,重新梳理了CNN做文本分类的实现原理,在此记录下学习笔记。

一、文本分类

  目前文本分类在工业界的应用场景非常普遍,从新闻的分类、商品评论信息的情感分类到微博信息打标签辅助推荐系统,都用到了这种技术。

二、数据准备

  在机器学习领域有一句话:数据决定了模型最终的高度,不断优化的模型只不过是为了不断逼近这个高度而已。
  
  文本分类作为一种有监督学习的任务,毫无疑问的需要一个可用于有监督学习的语料集(X,Y)。本文中使用以下标记,X为特征,文本分类中即为文本序列,Y是标签,即文本的分类名称。
  
  机器学习与传统编程技术的明显区别就是:机器学习是以数据为驱动的,传统的编程中,我们核心任务是人工设计分类规则(指令代码),然后实现输入特征X获得分类标签Y。而在机器学习的方式中,我们首要的是获得一个高质量的、大数据量的有监督语料集(X,Y),然后机器学习的方式会自动的从已构建的数据集上归纳出(训练出)一套分类规则(分类模型),最后我们利用获得的分类规则来实现对未标记文本的分类。
ml_vs_traditional_coding.png
  换言之,传统的编程方式输入的是指令代码,而机器学习输入的是结构化数据。
  因此,在机器学习任务中,数据的质量与数量对最终模型的预测结果好坏具有决定性的作用。
  常言道:Garbage in, garbage out!
  在文本分类中,语料集(X,Y)的质量、数量决定了文本分类模型的分类效果。

三、文本的预处理

  文本的预处理,主要针对剔除无意义的符号信息,或其它的冗余信息。例如,在使用爬虫获取的语料集上可能存在一些html的标签,这些符号对于文本分类任务来说应该是冗余的无意义信息,可以剔除掉。

  此外,针对中文、日语等无空格切分字词的语言,还需要进行分词处理,将一段文本序列划分为合理的词(字)序列。

  英文中天生的就有空格把每个词汇分割开来,所以不需要分词操作,但由于英文存在时态、缩写等问题,在预处理阶段会有词干提取、词性还原、大小写转换等。

  中文分词的工具有非常多的方案,可以参考中文分词原理,Python种最常用的有jieba分词器,使用非常的简单,使用pip install jieba就可以很方便的安装该工具包,jieba常用的API可以查看GitHub主页的实例

四、文本的数值化【词向量技术】

  我们知道,在图像的分类任务中,输入是一个图像数据(是一个矩阵,具有长和宽),而文本是一个字符串,如果能把文本转换成一种类似的格式(矩阵),那么很多之前在图像领域很适用的深度学习算法比如CNN等也可以很好地迁移到文本领域了。

  词向量技术就很好地解决了文本表示的问题。通过词向量技术,我们能将词汇信息映射到一个数值化的语义空间中,这个语义空间我们可以称之为词向量空间(词向量模型),于是,每个词汇都对应了一个指定维度的数组。

  简单地理解,就是我们把每一种语言中的每一个单词都与一串被叫做向量的数字联系起来了。
  
  文本转换成词向量(word embedding)的方式有很多种,例如:TF-IDF、BOW、One-Hot、分布式的表示方式(word2vec、Glove)等。一般常用的是word2vec工具。它是一种无监督的学习模型,可以在一个语料集上(不需要标记,主要思想是“具有相似邻近词分布的中心词之间具有一定的语义相似度”),实现词汇信息到语义空间的映射,最终获得一个词向量模型(每个词汇对应一个指定维度的数组)。

五、文本分类模型

  文本分类模型,从最经典的2013年Kim提出Text-CNN模型开始,深度学习模型在文本分类任务上具有广泛的应用。2016年Kim跳槽FaceBook后提出了工业界的文本分类模型的“新宠”—FastText。
  所以大家广泛认为,TextCNN是深度学习在文本分类中的鼻祖,如下图所示:
text_cnn_simple_structure.png
  本文选择使用2013年Kim提出的 Text-CNN 模型作为文本分类模型,通过验证实验以及业界的共识,在文本分类任务中,CNN模型已经能够取到比较好的结果,虽然在某些数据集上效果可能会比RNN稍差一点,但是CNN模型训练的效率更高。所以,一般认为CNN模型在文本分类任务中是兼具效率与质量的理想模型。

  关于什么是卷积神经网络,请阅读 CNN初探

  Text-CNN 模型的整体网络架构如下图所示,如果你学习过CNN或者CNN在图像中的使用,应该很容易就理解,因为该模型就是一个最简单、基础的CNN网络结构。
text_cnn_structure.png

  整个模型由四部分构成:输入层卷积层池化层全连接层

  它的过程大致是: 第一层是图中最左边的7乘5的句子矩阵,每行是词向量,维度=5,这个可以类比为图像中的原始像素点了。然后经过有 filter_size=(2,3,4) 的一维卷积层,每个filter_size 有两个输出 channel(每种filter_size设置了2个filter,如果只设置1个filter会略显单薄)。第三层是一个1-max pooling层,这样不同长度句子经过pooling层之后都能变成定长的表示了,最后接一层全连接的 softmax 层,输出每个类别的概率。
  
  ● 特征: 这里的特征就是词向量
  ● 通道(Channels): 图像中可以利用 (R, G, B) 作为不同channel,而文本的输入的channel通常是不同方式的embedding方式(比如 word2vec或Glove),实践中也有利用静态词向量和fine-tunning词向量作为不同channel的做法。
  ● 一维卷积(conv-1d): 图像是二维数据,经过词向量表达的文本为一维数据,因此在TextCNN卷积用的是一维卷积。一维卷积带来的问题是需要设计通过不同 filter_size 的 filter 获取不同宽度的视野。这里的设计是,分别对2,3,4个单词做一次卷积,因为不同个数的单词组合可能会带来不同的含义。

  下面对每个环节进行分别说明。

1. 输入层(词嵌入层)

  Text-CNN模型的输入层需要输入一个定长的文本序列,我们需要通过分析语料集样本的长度指定一个输入序列的长度L,比L短的样本序列需要填充(自己定义填充符),比L长的序列需要截取。最终输入层输入的是文本序列中各个词汇对应的分布式表示,即 词向量(word embedding)
text_cnn_word_embedding.png
  如上图所示,此时的输入不再是图片像素,而是以矩阵表示的句子或者文档。矩阵的每一行对应一个单词或者字符。也即每行代表一个词向量。在图像问题中,卷积核滑过的是图像的一“块”区域,但在自然语言领域里我们一般用卷积核滑过矩阵的一“行”(单词)。
  
  如果一个句子有6个词,每个词的词向量长度(也叫词向量的维度embedding_size)为7,那输入矩阵就是6x7,这就是我们的“图像”。可以理解为通道为1的图片。

2. 卷积层

  上一段提到,但在自然语言领域里我们一般用卷积核滑过矩阵的一“行”(单词),即卷积核的宽度与词向量的维度等宽,卷积核只进行一维的滑动。

  在Text-CNN模型中一般使用多个不同尺寸的卷积核。卷积核的高度,即窗口值,可以理解为N-gram模型中的N,即利用的局部词序的长度,窗口值也是一个超参数,需要在任务中尝试,一般选取2-8之间的值。
text_cnn_convolution.png

3. 池化层

  在Text-CNN模型的池化层中使用了Max-pool(最大值池化),既减少了模型的参数,又保证了在不定长的卷基层的输出上获得一个定长的全连接层的输入。
text_cnn_max_pool.png

池化层除了最大值池化之外,也有论文讨论过 Top K最大值池化,即选取每一个卷积层输出的Top k个最大值作为池化层的输出。
比如在情感分析场景,举个例子:“ 我觉得这个地方景色还不错,但是人也实在太多了 ”
虽然前半部分体现情感是正向的,全局文本表达的是偏负面的情感,利用 k-max pooling能够很好捕捉这类信息。

  卷积层与池化层在分类模型的核心作用就是特征提取的功能,从输入的定长文本序列中,利用局部词序信息,提取初级的特征,并组合初级的特征为高级特征,通过卷积与池化操作,省去了传统机器学习中的特征工程的步骤。
  但TextCNN的一个明显缺点就是,卷积、池化操作丢失了文本序列中的词汇的顺序、位置信息,比较难以捕获文本序列中的否定、反义等语义信息。

4. 全连接层

  全连接层的作用就是分类器,原始的Text-CNN模型使用了只有一层隐藏层的全连接网络,相当于把卷积与池化层提取的特征输入到一个LR分类器中进行分类。

  至此,Text-CNN的模型结构就算大体了解了,其实大部分情况下我们都是把深度学习模型看作一个黑盒子,知道格式化的输入,我们就可以利用别人搭建好的模型框架训练在自己的数据集上实现一定的功能。但是在不同的数据集上,模型的最佳状态也不唯一,这就需要我们在新的数据集上需要进行调优(调参)。

六、模型的效果评估与调优

  针对分类问题,一般可以使用准确率、召回率、F1值、混淆矩阵等指标,在文本多标签分类中一般还会考虑标签的位置加权等问题。

  分类模型中的主要参数:
  ● 词向量的维度(embedding_size
  ● 卷积核的个数(num_filters
  ● 卷积核的尺寸(filter_sizes
  ● L2的参数(l2_reg_lambda
  ● DropOut的参数
  ● 学习率
  ● 等等

  这是在模型优化的过程中需要重点关注的参数。此外,一般数据集的类别不均衡问题对模型的影响也是比较显著的,可以尝试使用不同的方法,评估不同方案的模型效果。

七、总结

  虽然大部分情况下应用深度学习,只需要把它当做一个黑盒,但如果不稍微了解一下理论原理,对这门技术的掌握会过于肤浅,遇到问题也容易解释不清。


参考
https://blog.csdn.net/heyc861221/article/details/80128748
https://www.jianshu.com/p/f69e8a306862
https://blog.csdn.net/huwenxing0801/article/details/85197722


  目录