PaddlePaddle Fluid实战:使用百度Senta 情感分析系统

情感倾向分析针对带有主观描述的中文文本,可自动判断该文本的情感极性类别并给出相应的置信度。情感类型分为积极、消极、中性。情感倾向分析能够帮助企业理解用户消费习惯、分析热点话题和危机舆情监控,为企业提供有力的决策支持。

上一次的介绍中我们讲解了情感分析的作用以及应用场景,技术难点以及百度Senta 系统对这些问题的解决方法以及核心技术。本次的介绍我们则侧重于实践,即利用百度深度学习框架PaddlePaddle Fluid, 实战Senta 系统。

Senta 是百度开源的情感分析(Sentiment Analysis) 系统,项目的github 地址是(https://github.com/baidu/Senta),Senta 也为百度AI 开放平台(http://ai.baidu.com/tech/nlp/sentiment_classify)提供了情感倾向分析模块,供用户直接使用。

此次我们将讲解如何本地构建Senta, 利用PaddlePaddle Fluid深度学习框架来实现情感分析模型的训练和部署。

实验环境准备:安装PaddlePaddle Fluid

运行本目录下的程序示例需要使用PaddlePaddle Fluid v1.1/1.2 版本。

使用pip 安装最新稳定版

# Linux CPU

pip install paddlepaddle

# Linux GPU cuda9cudnn7

pip install paddlepaddle-gpu

# Linux GPU cuda8cudnn7

pip install paddlepaddle-gpu==1.1.0.post87

# Linux GPU cuda8cudnn5

pip install paddlepaddle-gpu==1.1.0.post85

更详细的whl包列表也可以参见whl 包列表.

源码编译安装

如果需要安装最新的开发版,请按照安装文档中的说明更新PaddlePaddle Fluid 版本。

Senta 代码结构

Senta 项目的代码结构以及简介如下,本文重点介绍如何利用FluidPython API完成模型的构建和训练,关于如何利用Fluid C-API进行模型的在线部署,可以参考该项目的说明文档。

Senta

├── C-API/ # 

模型预测C-API接口

├── data/ # 

数据集

│   ├── test_data/

│   │   └── corpus.test

│   ├── train_data/

│   │   └── corpus.train

│   └── train.vocab

├── eval.sh               # 

模型评价脚本

├── infer.sh # 

模型预测脚本

├── nets.py 

 # 本例中涉及的各种网络结构均定义在此文件中,│ # 若进一步修改模型结构,请查看此文件

├── README.md # 

说明文档

├── sentiment_classify.py # 

情感倾向分析主函数,包括训练、预估、预测│ # 部分

├── train.sh # 

模型训练脚本

└── utils.py # 

定义通用的函数,例如加载词典,读入数据等

模型概览

nets.py 中包含以下几个模型:

•         bow_net:Bow(Bag Of Words) 模型,是一个非序列模型。使用基本的全连接结构。

•         cnn_net:浅层CNN 模型,是一个基础的序列模型,能够处理变长的序列输入,提取一个局部区域之内的特征。

•         gru_net:单层GRU 模型,序列模型,能够较好地解序列文本中长距离依赖的问题。

•         lstm_net:单层LSTM 模型,序列模型,能够较好地解决序列文本中长距离依赖的问题。

•         bilstm_net:双向单层LSTM 模型,序列模型,通过采用双向lstm结构,更好地捕获句子中的语义特征。百度AI 平台上情感倾向分析模块采用此模型进行训练和预测。


数据准备

数据格式

训练数据格式是制表符分隔值(tsv) 的格式,每一行代表一条训练数据,以制表符作为分割符分为两个字段。第一个字段是情感倾向,取值为0 或1,分别代表消极和积极情感倾向;第二个字段是文本的内容。文本已经经过分词处理,词与词之间用空格分隔。示例训练样本如下:

0 方向盘向左稍有偏斜- - - - 上四轮定位调整两次OK 。价格80元,4S 要300多元,立马和他说

人非常多,团购的平日票,本来以为人会少点,没想到人山人海。有些项目小孩不能玩,小孩对造浪池比较感兴趣,其它真没什么可玩的。

环境口味我都很满意,可是那服务态度还真不能让人恭维!生意好也不能降低服务态度!味道再美味我消费的时候还要受气的话我也不会再去消费了!

国耻,不忘历史。

 测试数据以同样的方式进行分隔,但在情感类别标签方面和训练数据有一些差别。测试数据中情感倾向共有三类,取值为0, 1, 2, 分别代表消极,中性,积极。在模型的预测阶段,我们利用模型输出样例为积极和消极的概率,如果用于二分类,只要积极的概率比消极的概率高,就归入积极;而如果用于三分类,则在中间加入了中性,分类的依据是,样例为积极的概率小于45% 则为消极,大于55% 则为积极,介于二者之间则为中性,用户也可以根据需要调整中型情感的概率阈值。示例测试样本如下所示:

2 空间是可以了,后面坐三个170斤的人也不嫌挤,但矮了点,后备箱给力

满分是10分的话,性价比给8.5分吧!综合油耗偏高,如果开市区的就不太合算了。

后排中间的突起太高,中间坐人不好放脚。

一般,家用还可以。

训练数据词典构建

因为深度学习模型的需要,需要把每一个词对应地转化为一个整数,为此要根据训练数据构建一个词典。而且还可以根据词典对词典的大小进行限制。这里使用的词典文件格式非常简单,每行代表词典中的一个词。以下是词典的示例:

喜欢特脏兮兮

...

注:我们在data目录下,提供了示例词典数据,详见data/train.vocab.

关于词典构建的功能,参见utils.py中的prepare_data(data_path, word_dict_path, batch_size, mode)函数,词典加载的功能,参见utils.py中的load_vocab(file_path)函数。

使用自定义数据

因为实际使用的数据比较大,github 项目中仅自带了一份小的示例数据,如果需要使用自定义的数据,将训练和测试需要用的语料处理成符合上述要求的格式,存放为data/train_data/corpus.train和data/test_data/corpus.test即可。

模型训练与预测

模型的训练,评价和预测都集成在sentiment_classify.py文件里,默认使用的模型是bilstm_net双向LSTM 模型。默认使用cpu 进行模型训练,但还可以支持使用gpu,通过--use_gpu True打开。另外,训练还支持并行,通过--is_parallel参数设置。

具体支持的参数可以通过python sentisentiment_classify.py --help查看。

模型训练

python sentiment_classify.py \

   --train_data_path ./data/train_data/corpus.train \ # 

训练数据路径

   --word_dict_path ./data/train.vocab \ # 

词典路径

   --mode train \    # train

模式

   --model_path ./models # 

模型保存路径

使用GPU 的训练脚本

export CUDA_VISIBLE_DEVICES=0,1 # 指定可用的GPU 序号

python sentiment_classify.py \

   --train_data_path ./data/train_data/corpus.train \      # 

训练数据路径

   --word_dict_path ./data/train.vocab \ # 

词典路径

   --mode train \ # train

模式

   --model_path ./models # 

模型保存路径

   --use_gpu True                         # 

使用GPU 训练模型

   --is_parallel True # 

使用并行

执行后可以看到如下的输出:一共对训练语料进行了10 次迭代,并且输出了在测试数据集上的准确率和平均cost.

[train info]: pass_id: 0, avg_acc: 0.821615, avg_cost: 0.388542

[train info]: pass_id: 1, avg_acc: 0.960837, avg_cost: 0.122814

[train info]: pass_id: 2, avg_acc: 0.987280, avg_cost: 0.052349

[train info]: pass_id: 3, avg_acc: 0.994591, avg_cost: 0.024470

[train info]: pass_id: 4, avg_acc: 0.997796, avg_cost: 0.012553

[train info]: pass_id: 5, avg_acc: 0.998197, avg_cost: 0.008723

[train info]: pass_id: 6, avg_acc: 0.999599, avg_cost: 0.003929

[train info]: pass_id: 7, avg_acc: 0.999700, avg_cost: 0.002423

[train info]: pass_id: 8, avg_acc: 0.999900, avg_cost: 0.001672

[train info]: pass_id: 9, avg_acc: 0.999900, avg_cost: 0.001001

也可以直接使用目录下的train.sh 根据需要进行修改。

模型评价

python sentiment_classify.py \

   --test_data_path ./data/test_data/corpus.test \ # 

测试数据路径

   --word_dict_path ./data/train.vocab \ # 

词典路径

   --mode eval \ # eval

模式

   --model_path ./models/epoch9/ # 

预测模型路径

可以看到类似如下的输出

[test info] model_path: ./models/epoch9/, class2_acc: 0.828402, class3_acc: 0.710000

说明模型能够完成情感分类任务,只是因为示例数据集太小,过拟合比较明显,在训练数据集上准确率可以达到99.9%, 而测试数据集上的二分类准确率只有82.8%. 用户可以通过使用自定义的更大的数据集,以及调整模型超参数以获得更好的效果。

模型预测

python sentiment_classify.py \

   --test_data_path ./data/test_data/corpus.test \ # 

测试数据路径

   --word_dict_path ./data/train.vocab \                      # 

词典路径

   --mode infer \ # infer

模式

   --model_path ./models/epoch9/ # 

预测模型路径

即可执行预测,可以得到类似如下的输出

predict label: 0, pos_prob: 0.004343, neg_prob: 0.995657

predict label: 2, pos_prob: 0.798888, neg_prob: 0.201112

predict label: 0, pos_prob: 0.000564, neg_prob: 0.999436

predict label: 0, pos_prob: 0.024923, neg_prob: 0.975077

predict label: 2, pos_prob: 0.999526, neg_prob: 0.000474

predict label: 2, pos_prob: 0.994914, neg_prob: 0.005086

predict label: 0, pos_prob: 0.065424, neg_prob: 0.934576

predict label: 0, pos_prob: 0.000119, neg_prob: 0.999881

predict label: 0, pos_prob: 0.000709, neg_prob: 0.999291

predict label: 2, pos_prob: 0.986198, neg_prob: 0.013802

.......

可以观察模型对于每一个样例的预测结果和详细情况。

扩展:处理未经加工的原始语料

上述的实验中,使用的训练和测试语料都已经经过分词处理,并且都被人工标了情感极性标签,用于训练和评价模型的能力,但是在实际应用中,面对的语料都是生语料,比如线上商品的评价信息,并没有经过分词之类的处理。这种情况下需要预先对语料进行加工处理,百度也开源了词法分析提供工具LAC。

在本工程目录的C-API目录下,就有调用LAC 进行分词并且结合上述模型完成情感分析所需的文件,将分词处理和情感分析集成在一起。具体的使用方法,可以进一步参考Senta 项目的说明文档, 以及LAC 项目的说明文档.

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容