
在自然语言处理中,情感分析一般是指判断一段文本所表达的情绪状态。其中,一段文本可以是一个句子,一个段落或一个文档。情绪状态可以是两类,如(正面,负面),(高兴,悲伤);也可以是三类,如(积极,消极,中性)等等。
在自然语言处理中,情感分析一般是指判断一段文本所表达的情绪状态。其中,一段文本可以是一个句子,一个段落或一个文档。情绪状态可以是两类,如(正面,负面),(高兴,悲伤);也可以是三类,如(积极,消极,中性)等等。
情感分析的应用场景十分广泛,如把用户在购物网站(亚马逊、天猫、淘宝等)、旅游网站、电影评论网站上发表的评论分成正面评论和负面评论;或为了分析用户对于某一产品的整体使用感受,抓取产品的用户评论并进行情感分析等等。
今天是 5 月 20 日,PaddlePaddle 教你用情感分析算法(https://github.com/PaddlePaddle/book/blob/develop/06.understand_sentiment/README.cn.md)体会女神心意。在下文中,我们将以情感分析为例,介绍使用深度学习的方法进行端对端的短文本分类,并使用 PaddlePaddle 完成全部相关实验。
一、应用背景
在自然语言处理中,情感分析属于典型的文本分类问题,即把需要进行情感分析的文本划分为其所属类别。文本分类涉及文本表示和分类方法两个问题。
在深度学习的方法出现之前,主流的文本表示方法为词袋模型 BOW(bag of words),话题模型等等;分类方法有 SVM(support vector machine), LR(logistic regression) 等等。
对于一段文本,BOW 表示会忽略其词顺序、语法和句法,将这段文本仅仅看做是一个词集合,因此 BOW 方法并不能充分表示文本的语义信息。
例如,句子「这部电影糟糕透了」和「一个乏味,空洞,没有内涵的作品」在情感分析中具有很高的语义相似度,但是它们的 BOW 表示的相似度为 0。又如,句子「一个空洞,没有内涵的作品」和「一个不空洞而且有内涵的作品」的 BOW 相似度很高,但实际上它们的意思很不一样。
在本教程中,我们所要介绍的深度学习模型克服了 BOW 表示的上述缺陷,它在考虑词顺序的基础上把文本映射到低维度的语义空间,并且以端对端(end to end)的方式进行文本表示及分类,其性能相对于传统方法有显著的提升 [1]。
二、模型概览
本教程所使用的文本表示模型为卷积神经网络(Convolutional Neural Networks)和循环神经网络 (Recurrent Neural Networks) 及其扩展。下面依次介绍这几个模型。
1. 文本卷积神经网络简介(CNN)
对卷积神经网络来说,首先使用卷积处理输入的词向量序列,产生一个特征图(feature map),对特征图采用时间维度上的最大池化(max pooling over time)操作得到此卷积核对应的整句话的特征,最后,将所有卷积核得到的特征拼接起来即为文本的定长向量表示,对于文本分类问题,将其连接至 softmax 即构建出完整的模型。
在实际应用中,我们会使用多个卷积核来处理句子,窗口大小相同的卷积核堆叠起来形成一个矩阵,这样可以更高效的完成运算。另外,我们也可使用窗口大小不同的卷积核来处理句子,图 1 表示卷积神经网络文本分类模型,不同颜色表示不同大小的卷积核操作。
对于一般的短文本分类问题,上文所述的简单的文本卷积网络即可达到很高的正确率 [1]。若想得到更抽象更高级的文本特征表示,可以构建深层文本卷积神经网络 [2,3]。
2. 循环神经网络(RNN)
循环神经网络是一种能对序列数据进行精确建模的有力工具。实际上,循环神经网络的理论计算能力是图灵完备的 [4]。自然语言是一种典型的序列数据(词序列),近年来,循环神经网络及其变体(如 long short term memory[5] 等)在自然语言处理的多个领域,如语言模型、句法解析、语义角色标注(或一般的序列标注)、语义表示、图文生成、对话、机器翻译等任务上均表现优异甚至成为目前效果最好的方法。
3. 长短期记忆网络(LSTM)
对于较长的序列数据,循环神经网络的训练过程中容易出现梯度消失或爆炸现象 [6]。LSTM 能够解决这一问题。相比于简单的循环神经网络,LSTM 增加了记忆单元 c、输入门 i、遗忘门 f 及输出门 o。这些门及记忆单元组合起来大大提升了循环神经网络处理长序列数据的能力。若将基于 LSTM 的循环神经网络表示的函数记为 F,则其公式为:
F 由下列公式组合而成 [7]:
LSTM 通过给简单的循环神经网络增加记忆及控制门的方式,增强了其处理远距离依赖问题的能力。类似原理的改进还有 Gated Recurrent Unit (GRU)[8],其设计更为简洁一些。这些改进虽然各有不同,但是它们的宏观描述却与简单的循环神经网络一样(如图 2 所示),即隐状态依据当前输入及前一时刻的隐状态来改变,不断地循环这一过程直至输入处理完毕:
其中,Recrurent 可以表示简单的循环神经网络、GRU 或 LSTM。
4. 栈式双向 LSTM(Stacked Bidirectional LSTM)
如图 4 所示(以三层为例),奇数层 LSTM 正向,偶数层 LSTM 反向,高一层的 LSTM 使用低一层 LSTM 及之前所有层的信息作为输入,对最高层 LSTM 序列使用时间维度上的最大池化即可得到文本的定长向量表示(这一表示充分融合了文本的上下文信息,并且对文本进行了深层次抽象),最后我们将文本表示连接至 softmax 构建分类模型。
三、基于 PaddlePaddle 的实战
1. PaddlePaddle 简介
PaddlePaddle(paddlepaddle.org) 是百度研发的深度学习框架。除了核心框架之外,PaddlePaddle 还提供了丰富的工具组件。官方开源了多个工业级应用模型,涵盖自然语言处理、计算机视觉、推荐引擎等多个领域,并开放了多个领先的预训练中文模型。4 月 23 日深度学习开发者峰会上,PaddlePaddle 发布了一系列新特性和应用案例。
2. 数据集介绍
我们以 IMDB 情感分析数据集为例进行介绍。IMDB 数据集的训练集和测试集分别包含 25000 个已标注过的电影评论。其中,负面评论的得分小于等于 4,正面评论的得分大于等于 7,满分 10 分。
PaddlePaddle 在 dataset/imdb.py 中实现了 imdb 数据集的自动下载和读取,并提供了读取字典、训练数据、测试数据等 API。
3. 配置模型
在该示例中,我们实现了两种文本分类算法,文本卷积神经网络,和栈式双向 LSTM。我们首先引入要用到的库和定义全局变量:
4. 文本卷积神经网络
我们构建神经网络 convolution_net,示例代码如下。需要注意的是:fluid.nets.sequence_conv_pool 包含卷积和池化层两个操作。
网络的输入 input_dim 表示的是词典的大小,class_dim 表示类别数。这里,我们使用 sequence_conv_pool API 实现了卷积和池化操作。
5. 栈式双向 LSTM
栈式双向神经网络 stacked_lstm_net 的代码片段如下:
以上的栈式双向 LSTM 抽象出了高级特征并把其映射到和分类类别数同样大小的向量上。最后一个全连接层的』softmax』激活函数用来计算分类属于某个类别的概率。
重申一下,此处我们可以调用 convolution_net 或 stacked_lstm_net 的任何一个网络结构进行训练学习。我们以 convolution_net 为例。
接下来我们定义预测程序(inference_program)。预测程序使用 convolution_net 来对 fluid.layer.data 的输入进行预测。
我们这里定义了 training_program。它使用了从 inference_program 返回的结果来计算误差。我们同时定义了优化函数 optimizer_func。
因为是有监督的学习,训练集的标签也在 fluid.layers.data 中定义了。在训练过程中,交叉熵用来在 fluid.layer.cross_entropy 中作为损失函数。
在测试过程中,分类器会计算各个输出的概率。第一个返回的数值规定为 cost。
四、训练模型
1. 定义训练环境
定义你的训练是在 CPU 上还是在 GPU 上:
2. 定义数据提供器
下一步是为训练和测试定义数据提供器。提供器读入一个大小为 BATCH_SIZE 的数据。paddle.dataset.imdb.word_dict 每次会在乱序化后提供一个大小为 BATCH_SIZE 的数据,乱序化的大小为缓存大小 buf_size。
注意:读取 IMDB 的数据可能会花费几分钟的时间,请耐心等待。
word_dict 是一个字典序列,是词和 label 的对应关系,运行下一行可以看到具体内容:
每行是如(』limited』: 1726)的对应关系,该行表示单词 limited 所对应的 label 是 1726。
3. 构造训练器
训练器需要一个训练程序和一个训练优化函数。
该函数用来计算训练中模型在 test 数据集上的结果
4. 提供数据并构建主训练循环
feed_order 用来定义每条产生的数据和 fluid.layers.data 之间的映射关系。比如,imdb.train 产生的第一列的数据对应的是 words 这个特征。
5. 训练过程处理
我们在训练主循环里打印了每一步输出,可以观察训练情况。
6. 开始训练
最后,我们启动训练主循环来开始训练。训练时间较长,如果为了更快的返回结果,可以通过调整损耗值范围或者训练步数,以减少准确率的代价来缩短训练时间。
五、应用模型
1. 构建预测器
和训练过程一样,我们需要创建一个预测过程,并使用训练得到的模型和参数来进行预测,params_dirname 用来存放训练过程中的各个参数。
2. 生成测试用输入数据
为了进行预测,我们任意选取 3 个评论。请随意选取您看好的 3 个。我们把评论中的每个词对应到 word_dict 中的 id。如果词典中没有这个词,则设为 unknown。然后我们用 create_lod_tensor 来创建细节层次的张量
六、应用模型并进行预测
现在我们可以对每一条评论进行正面或者负面的预测啦。
感兴趣的小伙伴可以在 PaddlePaddle 官网上阅读其他相关文档内容:http://www.paddlepaddle.org/
七、参考文献:
Kim Y. Convolutional neural networks for sentence classification[J]. arXiv preprint arXiv:1408.5882, 2014.
Kalchbrenner N, Grefenstette E, Blunsom P. A convolutional neural network for modelling sentences[J]. arXiv preprint arXiv:1404.2188, 2014.
Yann N. Dauphin, et al. Language Modeling with Gated Convolutional Networks[J] arXiv preprint arXiv:1612.08083, 2016.
Siegelmann H T, Sontag E D. On the computational power of neural nets[C]//Proceedings of the fifth annual workshop on Computational learning theory. ACM, 1992: 440-449.
Hochreiter S, Schmidhuber J. Long short-term memory[J]. Neural computation, 1997, 9(8): 1735-1780.
Bengio Y, Simard P, Frasconi P. Learning long-term dependencies with gradient descent is difficult[J]. IEEE transactions on neural networks, 1994, 5(2): 157-166.
Graves A. Generating sequences with recurrent neural networks[J]. arXiv preprint arXiv:1308.0850, 2013.
Cho K, Van Merriënboer B, Gulcehre C, et al. Learning phrase representations using RNN encoder-decoder for statistical machine translation[J]. arXiv preprint arXiv:1406.1078, 2014.
Zhou J, Xu W. End-to-end learning of semantic role labeling using recurrent neural networks[C]//Proceedings of the Annual Meeting of the Association for Computational Linguistics. 2015.