基于Bert的文本情感分类

详细代码已上传到github: click mepython

摘  要:     情感分类是对带有感情色彩的主观性文本进行分析、推理的过程,即分析说话人的态度,推断其所包含的情感类别.传统机器学习在处理情感分类问题的时候一般是基于SVM、CRF、信息熵等传统算法,其优点在于具备对多种特征建模的能力,但要用人工标注的单个词做为特征,而语料的不足每每就是性能的瓶颈.对句子进行情感分类的难处在于如何抽取到句子中与情感表达紧密相关的特征,以人工标注的单个词做为特征会忽略单词所处的上下文语义信息,致使最终的分类效果不理想.为了解决特征抽取的难题,决定使用2018年Google提出的文本预训练模型Bert(bidirectional encoder representations from transformer)来挑战此次实验中的情感多分类任务.Bert利用transformer超强的特征抽取能力来学习词语的双向编码表示,融合了上下文信息的词语编码能更好地进行情感决策.实验结果也代表使用Bert的效果要比使用传统算法的baseline好不少.git

关键词:     情感分类;Bert;深度学习;单词嵌入;字符嵌入github

1     介绍

短信在现代人的通信中被普遍使用,大量的微表情被用来替代帮助人们更好得表达本身的情感.然而,对于对微表情不熟悉的人来讲,找到他想要的那个表情并非一件简单的事(也许你能够考虑下你的父母以及爷爷奶奶如何使用这些微表情).所以,颇有必要设计一个系统来基于短信的内容自动推荐合适的微表情.以前看Google I/O大会看到Google作的功能相似的一款产品,经过识别短信内容来提供给用户以微表情替代情感相关文本的选项,感受颇有趣.这项任务其实就是NLP领域经典的情感分类问题,经过对短信做情感分析来为其匹配一个最合适的微表情类.对这些短信进行情感分类的难点在于: 1.反讽问题,好比"你牛逼你上啊"; 2.领域相关的问题,"个人电脑散热声音很大"、"我家洗衣机声音很大"这些极可能是差评,而"我家音响声音很大"极可能就是好评; 3.网络流行语也会影响情感分析,好比"给力"、"不明觉厉"、"累觉不爱"、"细思极恐"等,这些词利用传统的分词通常都会被切开,并且会影响词性标注,若是想避免只能加入人工干预,修改分词的粒度和词性标注的结果; 4.文本比较短,省略较严重,致使出现歧义或指代错误等,好比"咬死猎人的狗".传统的统计+规则的方法不能很好得解决这些难点,须要引入深度学习强大的特征抽取能力.2018年10月份,Google公司提出了NLP集大成者Bert模型[1] .这个模型既引入了lstm的双向编码机制同时还采用了GPT中的Transformer来作特征抽取,具备很是强大的文本特征提取能力,能学习到句子中潜在的句法和语义信息.除此以外,Bert基于character-level作embedding,就不存在分词以及测试集包含训练集中未出现词的困扰了.这些优势使得Bert可以比较好得解决情感分类问题中的一些难点,实验基于Google开源的Bert预训练好的中文模型作fine-tuning,最终的实验效果要比采用传统方法获得得baseline好不少.算法

 

2     相关工做

现有研究已经产生了可用于情感分析多项任务的大量技术,包括监督和无监督方法.在监督方法中,早期论文使用全部监督机器学习方法(如支持向量机、最大熵、朴素贝叶斯等)和特征组合.无监督方法包括使用情感词典、语法分析和句法模式的不一样方法.大约十年前,深度学习成为强大的机器学习技术,在不少应用领域产生了当前最优的结果,包括计算机视觉、语音识别、NLP 等.近期将深度学习应用到情感分析也逐渐变得流行.shell

 

Fig 1  The relationship between Bert and other deep learning modelsjson

图1  Bert和其它深度学习模型之间的关系api

情感分析可划分为3种粒度:文档粒度,句子粒度,短语粒度.此次的实验任务主要是基于句子粒度来进行情感分类.Kim等人于2013年提出的CNN文本分类工做[2] ,成为句子级情感分类任务的重要baseline之一.基本的lstm模型加上pooling策略构成分类模型,也一般用来作句子级情感分析的方法.Tang等人于2015年发表的工做[3] 使用两种不一样的RNN网络,结合文本和主题进行情感分析.这几年情感分析方面的突破主要都集中在深度学习领域,深度学习经过学习文本编码表示来抽取文本深层次的特征,解决传统方法没法很好地学习到文本特征的难题.文献[4,8]是从2013年至2018年期间深度学习在文本特征抽取方面的几项重大成就,其中包括Word2Vec,GLoVe,Transformer,ELMo,GPT.而本次实验将采用Bert模型[1] 是这几项工做的集大成者,如上图1所示是Bert与ELMo等深度学习模型之间的关系,它结合了Transformer和ELMo的优势,相比LSTM能较好地解决上下文长距离依赖问题,学习到了句子的句法特征以及深层次的语义特征,具备更强的特征抽取能力.因为时间比较紧,就没有拿Bert与ELMo等其余几个深度学习模型做比较了,可是相比传统的机器学习方法,效果要好不少.bash

3     方法

3.1   数据预处理

由于Bert模型有一个很是重要的超参:输入序列的长度,因此要先肯定训练集和测试集中全部句子的最大长度,最终统计获得最长句长为293,所以将模型最大序列长设为300比较合适.若是设得过小模型也不会报错,可是会截断输入从而致使输入信息缺失而不能准确预测所含情感.网络

除此以外,训练集中的数据并非均匀分布的,也就是说各个表情所占比重不同,对各表情聚类统计后发现数据倾斜很是大,最多的表情”心”出现了74788次,最少的表情”哈欠”仅出现了1355次.为了让Bert更好得学习到数据集上的特征,减小数据样本分布不均衡的影响,须要调整不一样表情类的损失权重.表情对应样本数越多的,其权重值越小,而表情对应样本数越少的,其权重值越大.具体作法是先统计各表情类的比重,将各表情类的损失值初始化为对应比重,而后将比重最大和比重最小的2个表情类的对应损失值置换,再将次大和次小的损失值置换,以此循环直到全部表情类的损失值被置换.机器学习

实验任务给出的数据集中不包含验证集,须要从训练集中划分出一个验证集.从训练集每一类中随机划分出等数目的样本,拼凑在一块儿构成模型的验证集,验证集用于评估模型训练过程当中的      F1 score,将F1 score最高的几个模型保存到本地,后面预测的时候就能够加载历史保留下来的F1 score表现很好的chechpoint用于预测.

3.2   Bert模型

使用Bert模型的pytorch版本库pytorch-pretrained-bert,中文预训练模型使用Google Search 基于超大规模中文语料库训练的chinese_L-12_H-768_A-12,不过这个预训练模型是提供给tensorflow使用的,pytorch不能直接加载使用,须要先作一个转换.使用pip安装好pytorch-pretrained-bert以后,在命令行下执行

export BERT_BASE_DIR=/path/to/bert/chinese_L-12_H-768_A-12  
  
pytorch_pretrained_bert convert_tf_checkpoint_to_pytorch \  
  $BERT_BASE_DIR/bert_model.ckpt \  
  $BERT_BASE_DIR/bert_config.json \  
  $BERT_BASE_DIR/pytorch_model.bin  
View Code

其中BERT_BASE_DIR为下载解压后的预训练模型所在路径.执行完成将在BERT_BASE_DIR路径下生成名为pytorch_model.bin的pytorch可用预训练模型文件,此时对应路径下bert_model.ckpt开头的三个文件均可以删除了,由于它们已集成到pytorch_model.bin中,对pytorch已经没什么用了.

学习率设置也很关键,学习率设置太大不容易收敛到最优值,学习率过小收敛太慢,效率过低.能够在模型开始训练逐渐增大学习率来加快收敛,当增大到一个阈值时就开始减少学习率,减缓梯度变化,让模型更好地落入一个局部最优解.

3.3   baseline模型

baseline模型使用了传统的机器学习来作,先使用tf-idf提取2000个特征词,而后每一条短信文本表示成这2000个词表示的频率向量,整个训练集和测试集就被转换成维度为样本数*特征词数的频率矩阵.而后使用朴素贝叶斯分类器在频率矩阵上进行训练和预测.

4     实验

4.1   实验环境

实验环境:

python 3.6.7

configparser 3.7.4

numpy 1.15.4

tqdm 4.32.1

scikit-learn 0.20.2

torch 1.1.0

torchvision 0.3.0

tensorboradX 1.7

pytorch-pretrained-bert 0.6.2

cuda 9.0.176

cudnn 7.3.0

gpu型号: 双核11G的Tesla K80(4块)

4.2   实验参数

全部参数设置都写进一个shell脚本以下

#! /usr/bin/env bash
python sentiment_dev.py \
--data_dir '../input' \
--bert_model_dir '../input/pre_training_models/chinese_L-12_H-768_A-12' \
--output_dir '../output/models/' \
--checkpoint '../output/models/checkpoint-33426' \
--max_seq_length 300 \
--do_predict \
--do_lower_case \
--train_batch_size 60 \
--gradient_accumulation_steps 3 \
--predict_batch_size 15 \
--learning_rate 2e-5 \
--num_train_epochs 3
View Code

4.3   实验结果其中data_dir为训练集、验证集、测试集所在目录.bert_model_dir为Bert中文预训练模型所在目录.output_dir为训练模型保存目录以及预测结果输出目录.checkpoint为模型加载文件,经过指定的checkpoint来预测或者从指定checkpoint处开始训练以节省训练时间,若是想从新开始训练则去除checkpoint这个参数.max_seq_len为输入序列的最大长度,由于数据集中最长句长为293,因此这里设为300以确保能保留全部输入文本的完整信息.do_predict表示预测,这个参数改成do_train则表示训练.do_lower_case表示忽略大小写,英文字母都转换成小写.train_batch_size为一次送入训练的样本数目.gradient_accumulation_steps为梯度累积次数,每gradient_accumulation_steps次梯度计算与反向传播后更改一次学习率,并将梯度归零,实际每次送入训练的样本数目为train_batch_size/gradient_accumulation_steps个样本.predict_batch_size为一次预测的样本数目.learning_rate为学习率,num_train_epoches为训练集上的训练轮数.

下图2是提交在kaggle上的结果截图,其中用红色方框圈出来的结果是提交过的最好结果,这是在训练集上训练3轮的结果,test.predict-33426是在训练集上训练2轮半提早终止的结果,submission_2epoch是在训练集上训练2轮的结果.能够看到训练得越久最终的private score越高,代表训练程度还不够饱和,还有一些特征没有学习到,须要更深一步的训练.可是训练时耗太长了,没来得及作更多轮的训练做对比.baseline_nb是用第3章提到的baseline model获得的结果,与Bert获得的结果相差甚远,Bert预测结果的F1 score差很少是baseline的10倍左右.终榜前提交的最好成绩是0.18777,榜上排名12.

 

Fig 2  submission results of experiment on kaggle

图2  实验在kaggle上的提交结果

5     总结

文本情感分类是NLP领域的一个经典问题,也是NLP领域的一个难题.本次实验任务的最大挑战在于它不是简单地判别情感的好与坏,而是须要判别每一条短信中所蕴含的具体情感,而后给它匹配最合适的表情.然而标签数据一共包含72类表情,有时候一条短信可能包含不止一种情感,人为判断会以为能够匹配多类表情,可是数据集中是每一条短信对应一个表情,这无疑给情感分类带来巨大挑战.Bert可能学习到了短信中的多种情感特征,可是只能给出一种表情,很容易与真实标签不一致.所以Bert虽然在这个任务上的表现比baseline好不少,可是光看其在测试集上的F1 score仍是很低的.

本次实验数据预处理的工做作得不多,只作了一些简单的统计,没有对数据进行清洗.训练集中包含大量的非中文文本,而实验中使用的是中文预训练模型,对于非中文文本的编码表示学习效果可能不太好,后续能够引入混合多种语言文本的外部语料库进行训练,提高模型对非中文文本的特征学习能力.

References:

   [1]    Jacob Devlin, Ming-Wei Chang, Kenton Lee, and Kristina Toutanova. Bert: pre-training of deepbidirectional transformers for language understanding. CoRR, 2018,abs/1810.04805.

   [2]    Yoon Kim. Convolutional neural networks for sentence classification. CoRR, 2014,abs/1408.5882.

   [3]    Duyu Tang, Bing Qin, Xiaocheng Feng, and Ting Liu. Target-dependent sentiment classificationwith long short term memory. CoRR,2015,abs/1512.01100.

   [4]    Tomas Mikolov, Kai Chen, Greg Corrado, and Jeffrey Dean. Efficient estimation of word represen-tations in vector space. arXiv preprint arXiv, 2013,1301.3781.

   [5]    Jeffrey Pennington, Richard Socher, and Christopher Manning. Glove: Global vectors for wordrepresentation. In: Proceedings of the 2014 conference on empirical methods in natural languageprocessing (EMNLP), 2014. 1532–1543.

   [6]    Ashish Vaswani, Noam Shazeer, Niki Parmar, Jakob Uszkoreit, Llion Jones, Aidan N Gomez,Łukasz Kaiser, and Illia Polosukhin. Attention is all you need. In: Advances in neural informationprocessing systems, 2017. 5998–6008.

   [7]    Matthew E. Peters, Mark Neumann, Mohit Iyyer, Matt Gardner, Christopher Clark, Kenton Lee,and Luke Zettlemoyer. Deep contextualized word representations. CoRR, 2018,abs/1802.05365.

   [8]    Alec Radford, Karthik Narasimhan, Tim Salimans, and Ilya Sutskever. Improving languageunderstanding by generative pre-training. URL https://s3-us-west-2. amazonaws. com/openai-assets/research-covers/languageunsupervised/language understanding paper. pdf, 2018.

相关文章
相关标签/搜索