当前位置:   article > 正文

百度AI攻略:情感分析的多种方法_百度情感分心

百度情感分心

1. 简介

现在情感分析有很广泛的应用,例如:

评论分析与决策,通过对产品多维度评论观点进行倾向性分析,给用户提供该产品全方位的评价,方便用户进行决策
评论分类,通过对评论进行情感倾向性分析,将不同用户对同一事件或对象的评论内容按情感极性予以分类展示
舆情监控,通过对需要舆情监控的实时文字数据流进行情感倾向性分析,把握用户对热点信息的情感倾向性变化
等等

百度针对情感分析也提供了多种解决方案,包括:

百度情感倾向分析服务:对包含主观信息的文本进行情感倾向性判断,可支持在线训练模型调优效果,为口碑分析、话题监控、舆情分析等应用提供帮助。

ERINE模型:今年百度发布了知识增强的语义表示模型 ERNIE(Enhanced Representation from kNowledge IntEgration),并发布了基于 PaddlePaddle 的开源代码与模型,在语言推断、语义相似度、命名实体识别、情感分析、问答匹配等自然语言处理(NLP)各类中文任务上的验证显示,模型效果全面超越 BERT。

情感倾向分析(Sentiment Classification,简称Senta)针对带有主观描述的中文文本,可自动判断该文本的情感极性类别并给出相应的置信度,能够帮助企业理解用户消费习惯、分析热点话题和危机舆情监控,为企业提供有利的决策支持。PaddleHub现在这方面的模型有:senta_lstm,senta_gru,senta_cnn,senta_bow,senta_bilstm,emotion_detection_textcnn等。这些PaddleHub Module预训练数据集为百度自建数据集,支持预测和Fine-tune。

本文对使用百度情感倾向分析服务进行在线情感分析及使用百度ERINE模型、PaddleHub情感分析模型进行离线情感分析进行评测分析,并提供了详细的使用攻略及代码,方便大家使用。

2 情感倾向分析API调用攻略(Python3)

2.1 认证授权:

在开始调用任何API之前需要先进行认证授权,具体的说明请参考:

http://ai.baidu.com/docs#/Auth/top

具体Python3代码如下:

  1. # -*- coding: utf-8 -*-
  2. #!/usr/bin/env python
  3. import urllib
  4. import json
  5. #client_id 为官网获取的AK, client_secret 为官网获取的SK
  6. client_id =【百度云应用的AK】
  7. client_secret =【百度云应用的SK】
  8. #获取token
  9. def get_token():
  10. host = 'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=' + client_id + '&client_secret=' + client_secret
  11. request = urllib.request.Request(host)
  12. request.add_header('Content-Type', 'application/json; charset=UTF-8')
  13. response = urllib.request.urlopen(request)
  14. token_content = response.read()
  15. if token_content:
  16. token_info = json.loads(token_content)
  17. token_key = token_info['access_token']
  18. return token_key



2.2 情感倾向分析接口调用:
详细说明请参考:http://ai.baidu.com/docs#/NLP-API/57b9b630

接口描述
情感倾向分析接口(通用版):自动对包含主观信息的文本进行情感倾向性判断(积极、消极、中性),并给出相应的置信度。为口碑分析、话题监控、舆情分析等应用提供基础技术支持,同时支持用户自行定制模型效果调优。

请求说明
HTTP方法: POST
请求URL: https://aip.baidubce.com/rpc/2.0/nlp/v1/sentiment_classify

URL参数:
参数 值
access_token 通过API Key和Secret Key获取的access_token,参考“Access Token获取”

Header如下:
参数 值
Content-Type application/json

Body请求示例:
{
"text": "苹果是一家伟大的公司"
}

请求参数
参数 类型 描述 是否必填
text string 文本内容,最大2048字节


返回说明
参数 说明 描述
log_id uint64 请求唯一标识码
sentiment int 表示情感极性分类结果,0:负向,1:中性,2:正向
confidence float 表示分类的置信度,取值范围[0,1]
positive_prob float 表示属于积极类别的概率 ,取值范围[0,1]
negative_prob float 表示属于消极类别的概率,取值范围[0,1]

Python3调用代码如下:

  1. #调用情感分类接口
  2. def get_classify(content):
  3. print (content)
  4. token=get_token()
  5. url = 'https://aip.baidubce.com/rpc/2.0/nlp/v1/sentiment_classify'
  6. params = dict()
  7. params['text'] = content
  8. params = json.dumps(params).encode('utf-8')
  9. access_token = token
  10. url = url + "?access_token=" + access_token
  11. request = urllib.request.Request(url=url, data=params)
  12. request.add_header('Content-Type', 'application/json')
  13. response = urllib.request.urlopen(request)
  14. content = response.read()
  15. if content:
  16. content=content.decode('gb2312')
  17. #print (content)
  18. data = json.loads(content)
  19. data=data['items'][0]
  20. sentiment=data['sentiment']
  21. if sentiment==0:
  22. sentiment='负向'
  23. elif sentiment==1:
  24. sentiment='中性'
  25. else:
  26. sentiment='正向'
  27. print ('情感分类结果:',sentiment)
  28. print ('分类的置信度:',data['confidence'])
  29. print ('积极类别概率:',data['positive_prob'])
  30. print ('消极类别概率:',data['negative_prob'])
  31. test_list = [
  32. "这个宾馆比较陈旧了,特价的房间也很一般。总体来说一般",
  33. "交通方便;环境很好;服务态度很好 房间较小",
  34. "稍微重了点,可能是硬盘大的原故,还要再轻半斤就好了。" ,
  35. "服务很不错,下次还会来。" ,
  36. "前台接待太差,下次不会再选择入住此店啦",
  37. "菜做的很好,味道很不错。" ,
  38. "19天硬盘就罢工了,算上运来的一周都没用上15天,你说这算什么事呀",
  39. "现在是高峰期,人太多了,我们晚点来吧"
  40. ]
  41. import datetime
  42. print (datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
  43. for text in test_list:
  44. get_classify(text)
  45. print (datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))

 

3、ERINE模型

ERNIE 通过建模海量数据中的词、实体及实体关系,学习真实世界的语义知识。相较于 BERT 学习原始语言信号,ERNIE 直接对先验语义知识单元进行建模,增强了模型语义表示能力,以 Transformer 为网络基本组件,以Masked Bi-Language Model和 Next Sentence Prediction 为训练目标,通过预训练得到通用语义表示,再结合简单的输出层,应用到下游的 NLP 任务。我们可以使用ERINE进行情感分类,具体步骤如下:

1,首先我们要在PaddleHub中选择ernie作为预训练模型,进行Fine-tune。ChnSentiCorp数据集是一个中文情感分类数据集。PaddleHub已支持加载该数据集。关于该数据集,详情请查看ChnSentiCorp数据集使用。
https://github.com/PaddlePaddle/PaddleHub/wiki/PaddleHub-API:-Dataset

2,生成Reader:接着生成一个文本分类的reader,reader负责将dataset的数据进行预处理,首先对文本进行切词,接着以特定格式组织并输入给模型进行训练。
ClassifyReader的参数有以下三个:
dataset: 传入PaddleHub Dataset;
vocab_path: 传入ERNIE/BERT模型对应的词表文件路径;
max_seq_len: ERNIE模型的最大序列长度,若序列长度不足,会通过padding方式补到max_seq_len, 若序列长度大于该值,则会以截断方式让序列长度为max_seq_len;

3,选择Fine-Tune优化策略,适用于ERNIE/BERT这类Transformer模型的迁移优化策略为AdamWeightDecayStrategy。详情请查看Strategy。

AdamWeightDecayStrategy的参数有以下三个:
learning_rate: 最大学习率
lr_scheduler: 有linear_decay和noam_decay两种衰减策略可选
warmup_proprotion: 训练预热的比例,若设置为0.1, 则会在前10%的训练step中学习率逐步提升到learning_rate
weight_decay: 权重衰减,类似模型正则项策略,避免模型overfitting
optimizer_name: 优化器名称,使用Adam

4,选择运行时配置
在进行Finetune前,我们可以设置一些运行时的配置,例如如下代码中的配置,表示:
use_cuda:设置为False表示使用CPU进行训练。如果您本机支持GPU,且安装的是GPU版本的PaddlePaddle,我们建议您将这个选项设置为True;
epoch:要求Finetune的任务只遍历1次训练集;
batch_size:每次训练的时候,给模型输入的每批数据大小为32,模型训练时能够并行处理批数据,因此batch_size越大,训练的效率越高,但是同时带来了内存的负荷,过大的batch_size可能导致内存不足而无法训练,因此选择一个合适的batch_size是很重要的一步;
log_interval:每隔10 step打印一次训练日志;
eval_interval:每隔50 step在验证集上进行一次性能评估;
checkpoint_dir:将训练的参数和数据保存到ernie_txt_cls_turtorial_demo目录中;
strategy:使用DefaultFinetuneStrategy策略进行finetune;
更多运行配置,请查看RunConfig

5,组建Finetune Task
有了合适的预训练模型和准备要迁移的数据集后,我们开始组建一个Task。
获取module的上下文环境,包括输入和输出的变量,以及Paddle Program;
从输出变量中找到用于情感分类的文本特征pooled_output;
在pooled_output后面接入一个全连接层,生成Task;

6,开始Finetune
选择finetune_and_eval接口来进行模型训练,这个接口在finetune的过程中,会周期性的进行模型效果的评估,以便我们了解整个训练过程的性能变化。

7,使用模型进行预测
当Finetune完成后,使用模型来进行预测

具体代码如下:

  1. from paddle.fluid.framework import switch_main_program
  2. import paddlehub as hub
  3. import paddle.fluid as fluid
  4. module = hub.Module(name="ernie", version="1.0.1")
  5. dataset = hub.dataset.ChnSentiCorp()
  6. #生成Reader
  7. reader = hub.reader.ClassifyReader(
  8. dataset=dataset,
  9. vocab_path=module.get_vocab_path(),
  10. max_seq_len=128)
  11. #选择Fine-Tune优化策略
  12. strategy = hub.AdamWeightDecayStrategy(
  13. weight_decay=0.01,
  14. warmup_proportion=0.1,
  15. learning_rate=5e-5,
  16. lr_scheduler="linear_decay",
  17. optimizer_name="adam")
  18. #选择运行时配置
  19. config = hub.RunConfig(
  20. use_cuda=True,
  21. num_epoch=1,
  22. checkpoint_dir="ernie_txt_cls_turtorial_demo",
  23. batch_size=32,
  24. log_interval=10,
  25. eval_interval=50,
  26. strategy=strategy)
  27. #组建Finetune Task
  28. inputs, outputs, program = module.context(
  29. trainable=True, max_seq_len=128)
  30. # Use "pooled_output" for classification tasks on an entire sentence.
  31. pooled_output = outputs["pooled_output"]
  32. feed_list = [
  33. inputs["input_ids"].name,
  34. inputs["position_ids"].name,
  35. inputs["segment_ids"].name,
  36. inputs["input_mask"].name,
  37. ]
  38. cls_task = hub.TextClassifierTask(
  39. data_reader=reader,
  40. feature=pooled_output,
  41. feed_list=feed_list,
  42. num_classes=dataset.num_labels,
  43. config=config)
  44. #开始Finetune
  45. cls_task.finetune_and_eval()
  46. #使用模型进行预测
  47. # coding: utf-8
  48. from __future__ import absolute_import
  49. from __future__ import division
  50. from __future__ import print_function
  51. import numpy as np
  52. import os
  53. import paddle
  54. import paddle.fluid as fluid
  55. import paddlehub as hub
  56. # loading Paddlehub ERNIE pretrained model
  57. module = hub.Module(name="ernie")
  58. inputs, outputs, program = module.context(max_seq_len=128)
  59. # Sentence classification dataset reader
  60. dataset = hub.dataset.ChnSentiCorp()
  61. reader = hub.reader.ClassifyReader(
  62. dataset=dataset,
  63. vocab_path=module.get_vocab_path(),
  64. max_seq_len=128)
  65. # Construct transfer learning network
  66. # Use "pooled_output" for classification tasks on an entire sentence.
  67. # Use "sequence_output" for token-level output.
  68. pooled_output = outputs["pooled_output"]
  69. # Setup feed list for data feeder
  70. # Must feed all the tensor of ERNIE's module need
  71. feed_list = [
  72. inputs["input_ids"].name,
  73. inputs["position_ids"].name,
  74. inputs["segment_ids"].name,
  75. inputs["input_mask"].name,
  76. ]
  77. strategy = hub.AdamWeightDecayStrategy(
  78. weight_decay=0.01,
  79. warmup_proportion=0.1,
  80. learning_rate=5e-5,
  81. lr_scheduler="linear_decay",
  82. optimizer_name="adam")
  83. # Setup runing config for PaddleHub Finetune API
  84. config = hub.RunConfig(
  85. use_data_parallel=False,
  86. use_pyreader=False,
  87. use_cuda=True,
  88. batch_size=32,
  89. enable_memory_optim=False,
  90. checkpoint_dir="ernie_txt_cls_turtorial_demo",
  91. strategy=strategy)
  92. # Define a classfication finetune task by PaddleHub's API
  93. cls_task = hub.TextClassifierTask(
  94. data_reader=reader,
  95. feature=pooled_output,
  96. feed_list=feed_list,
  97. num_classes=dataset.num_labels,
  98. config=config)
  99. # Data to be prdicted
  100. data = [
  101. ["这个宾馆比较陈旧了,特价的房间也很一般。总体来说一般"],
  102. ["交通方便;环境很好;服务态度很好 房间较小"],
  103. ["稍微重了点,可能是硬盘大的原故,还要再轻半斤就好了。" ],
  104. ["服务很不错,下次还会来。" ],
  105. ["前台接待太差,下次不会再选择入住此店啦"],
  106. ["菜做的很好,味道很不错。" ],
  107. ["19天硬盘就罢工了,算上运来的一周都没用上15天,你说这算什么事呀"],
  108. ["现在是高峰期,人太多了,我们晚点来吧"]
  109. ]
  110. index = 0
  111. run_states = cls_task.predict(data=data)
  112. results = [run_state.run_results for run_state in run_states]
  113. for batch_result in results:
  114. # get predict index
  115. batch_result = np.argmax(batch_result, axis=2)[0]
  116. for result in batch_result:
  117. if result==1:
  118. result='正向'
  119. else:
  120. result='负向'
  121. print(data[index][0], result)
  122. index += 1

 

4、PaddleHub情感分析模型(以senta_bilstm为例)

模型概述
情感倾向分析(Sentiment Classification,简称Senta)针对带有主观描述的中文文本,可自动判断该文本的情感极性类别并给出相应的置信度,能够帮助企业理解用户消费习惯、分析热点话题和危机舆情监控,为企业提供有利的决策支持。该模型基于一个双向LSTM结构,情感类型分为积极、消极。该PaddleHub Module支持预测和Fine-tune。

参数:

data:dict类型,key为text,str类型;value为待预测文本,list类型。

返回:

results:list类型,每个元素为对应输入文本的预测结果。预测结果为dict类型,有以下字段:

text字段存放原输入待预测文本;
sentiment_label为情感分类结果对应的label;
sentiment_key表示分类结果为positive或是negative;
positive_probs为原输入文本对应positive的概率值;
negative_probs为原输入文本对应negative的概率值;

调用代码:

  1. import paddlehub as hub
  2. senta = hub.Module(name="senta_bilstm")
  3. test_text = [
  4. "这个宾馆比较陈旧了,特价的房间也很一般。总体来说一般",
  5. "交通方便;环境很好;服务态度很好 房间较小",
  6. "稍微重了点,可能是硬盘大的原故,还要再轻半斤就好了。" ,
  7. "服务很不错,下次还会来。" ,
  8. "前台接待太差,下次不会再选择入住此店啦",
  9. "菜做的很好,味道很不错。" ,
  10. "19天硬盘就罢工了,算上运来的一周都没用上15天,你说这算什么事呀",
  11. "现在是高峰期,人太多了,我们晚点来吧"
  12. ]
  13. input_dict = {"text": test_text}
  14. results = senta.sentiment_classify(data=input_dict)
  15. for result in results:
  16. print(result['text'])
  17. print(result['sentiment_label'])
  18. print(result['sentiment_key'])
  19. print(result['positive_probs'])
  20. print(result['negative_probs'])


5、功能评测:
选用不同的数据对情感分类的准确性进行测试。具体案例如下:
"这个宾馆比较陈旧了,特价的房间也很一般。总体来说一般",
"交通方便;环境很好;服务态度很好 房间较小",
"稍微重了点,可能是硬盘大的原故,还要再轻半斤就好了。" ,
"服务很不错,下次还会来。" ,
"前台接待太差,下次不会再选择入住此店啦",
"菜做的很好,味道很不错。" ,
"19天硬盘就罢工了,算上运来的一周都没用上15天,你说这算什么事呀",
"现在是高峰期,人太多了,我们晚点来吧"

5.1 情感分析API结果:
这个宾馆比较陈旧了,特价的房间也很一般。总体来说一般
情感分类结果: 负向
分类的置信度: 0.943242
积极类别概率: 0.025541
消极类别概率: 0.974459
交通方便;环境很好;服务态度很好 房间较小
情感分类结果: 正向
分类的置信度: 0.890898
积极类别概率: 0.950904
消极类别概率: 0.049096
稍微重了点,可能是硬盘大的原故,还要再轻半斤就好了。
情感分类结果: 负向
分类的置信度: 0.0922925
积极类别概率: 0.408468
消极类别概率: 0.591532
服务很不错,下次还会来。
情感分类结果: 正向
分类的置信度: 0.990288
积极类别概率: 0.99563
消极类别概率: 0.00437049
前台接待太差,下次不会再选择入住此店啦
情感分类结果: 负向
分类的置信度: 0.980575
积极类别概率: 0.00874128
消极类别概率: 0.991259
菜做的很好,味道很不错。
情感分类结果: 正向
分类的置信度: 0.959412
积极类别概率: 0.981735
消极类别概率: 0.0182646
19天硬盘就罢工了,算上运来的一周都没用上15天,你说这算什么事呀
情感分类结果: 负向
分类的置信度: 0.366781
积极类别概率: 0.284949
消极类别概率: 0.715051
现在是高峰期,人太多了,我们晚点来吧
情感分类结果: 正向
分类的置信度: 0.400084
积极类别概率: 0.730038
消极类别概率: 0.269962


5.2 ERINE的结果:
这个宾馆比较陈旧了,特价的房间也很一般。总体来说一般 负向
交通方便;环境很好;服务态度很好 房间较小 正向
稍微重了点,可能是硬盘大的原故,还要再轻半斤就好了。 负向
服务很不错,下次还会来。 正向
前台接待太差,下次不会再选择入住此店啦 负向
菜做的很好,味道很不错。 正向
19天硬盘就罢工了,算上运来的一周都没用上15天,你说这算什么事呀 负向
现在是高峰期,人太多了,我们晚点来吧 负向

5.3、PaddleHub情感分析模型(以senta_bilstm为例)

这个宾馆比较陈旧了,特价的房间也很一般。总体来说一般
0
negative
0.0103
0.9897
交通方便;环境很好;服务态度很好 房间较小
1
positive
0.9374
0.0626
稍微重了点,可能是硬盘大的原故,还要再轻半斤就好了。
0
negative
0.2237
0.7763
服务很不错,下次还会来。
1
positive
0.9891
0.0109
前台接待太差,下次不会再选择入住此店啦
0
negative
0.0057
0.9943
菜做的很好,味道很不错。
1
positive
0.9714
0.0286
19天硬盘就罢工了,算上运来的一周都没用上15天,你说这算什么事呀
0
negative
0.0266
0.9734
现在是高峰期,人太多了,我们晚点来吧
1
positive
0.7662
0.2338

6、结论及建议

通过测试发现不论直接调用百度情感分析服务还是使用百度ERINE模型,对情感分析都有很好、很准确的结果。百度情感分析服务调用起来更加的方便,不需要使用者掌握太多的深度学习方面的技术,适用于绝大多数的应用场景。

PaddleHub情感分析模型库,是一个针对情感分析的模型库,并且针对情感分析场景进行了预训练,支持FineTune,不过即使没有FineTune也可以直接用于情感分析,调用起来比较方便。不过需要使用者掌握一定的深度学习方面的技术。

ERINE模型是一个通用模型给与用户更大的灵活性,可以根据自己的需要定制化的开发适合自己的引用,不过需要对深度学习及Paddle Paddle有比较深入的了解。大家可以根据自己的实际情况选择适合的技术。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/473436
推荐阅读
相关标签
  

闽ICP备14008679号