README.md 14.0 KB
Newer Older
1
# 情感倾向分析
Y
Yibing Liu 已提交
2

3 4 5 6 7 8 9 10 11 12
* [模型简介](#模型简介)
* [快速开始](#快速开始)
* [进阶使用](#进阶使用)
* [版本更新](#版本更新)
* [作者](#作者)
* [如何贡献代码](#如何贡献代码)

## 模型简介

情感倾向分析(Sentiment Classification,简称Senta)针对带有主观描述的中文文本,可自动判断该文本的情感极性类别并给出相应的置信度。情感类型分为积极、消极。情感倾向分析能够帮助企业理解用户消费习惯、分析热点话题和危机舆情监控,为企业提供有利的决策支持。可通过 [AI开放平台-情感倾向分析](http://ai.baidu.com/tech/nlp_apply/sentiment_classify) 线上体验。
Y
Yibing Liu 已提交
13 14

情感是人类的一种高级智能行为,为了识别文本的情感倾向,需要深入的语义建模。另外,不同领域(如餐饮、体育)在情感的表达各不相同,因而需要有大规模覆盖各个领域的数据进行模型训练。为此,我们通过基于深度学习的语义模型和大规模数据挖掘解决上述两个问题。效果上,我们基于开源情感倾向分类数据集ChnSentiCorp进行评测;此外,我们还开源了百度基于海量数据训练好的模型,该模型在ChnSentiCorp数据集上fine-tune之后(基于开源模型进行Finetune的方法请见下面章节),可以得到更好的效果。具体数据如下所示:
15 16

| 模型 | dev | test | 模型(finetune) |dev | test |
Y
Yibing Liu 已提交
17 18 19 20 21 22 23 24 25
| :------| :------ | :------ | :------ |:------ | :------
| BOW | 89.8% | 90.0% | BOW |91.3% | 90.6% |
| CNN | 90.6% | 89.9% | CNN |92.4% | 91.8% |
| LSTM | 90.0% | 91.0% | LSTM |93.3% | 92.2% |
| GRU | 90.0% | 89.8% | GRU |93.3% | 93.2% |
| BI-LSTM | 88.5% | 88.3% | BI-LSTM |92.8% | 91.4% |
| ERNIE | 95.1% | 95.4% | ERNIE |95.4% | 95.5% |
| ERNIE+BI-LSTM | 95.3% | 95.2% | ERNIE+BI-LSTM |95.7% | 95.6% |

26
## 快速开始
Y
Yibing Liu 已提交
27

28
### 安装说明
Y
Yibing Liu 已提交
29

30 31 32 33 34 35 36 37 38 39 40 41 42 43
1. PaddlePaddle 安装

   本项目依赖于 PaddlePaddle Fluid 1.3.2 及以上版本,请参考 [安装指南](http://www.paddlepaddle.org/#quick-start) 进行安装

2. 代码安装

   克隆代码库到本地

   ```shell
   git clone https://github.com/PaddlePaddle/models.git
   cd models/PaddleNLP/sentiment_classification
   ```

3. 环境依赖
Y
Yibing Liu 已提交
44

45
   请参考 PaddlePaddle [安装说明](https://www.paddlepaddle.org.cn/documentation/docs/zh/1.5/beginners_guide/install/index_cn.html) 部分的内容
Y
Yibing Liu 已提交
46

47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
### 代码结构说明

以下是本项目主要代码结构及说明:

```text
.
├── senta_config.json           # 配置文件
├── config.py                   # 配置文件读取接口
├── inference_model.py		     # 保存 inference_model 的脚本
├── inference_ernie_model.py	# 保存 inference_ernie__model 的脚本
├── reader.py                   # 数据读取接口
├── run_classifier.py           # 项目的主程序入口,包括训练、预测、评估
├── run.sh                      # 训练、预测、评估运行脚本
├── run_ernie_classifier.py     # 基于ERNIE表示的项目的主程序入口
├── run_ernie.sh                # 基于ERNIE的训练、预测、评估运行脚本
├── utils.py                    # 其它功能函数脚本
```

### 数据准备

#### **自定义数据**

训练、预测、评估使用的数据可以由用户根据实际的应用场景,自己组织数据。数据由两列组成,以制表符分隔,第一列是以空格分词的中文文本(分词预处理方法将在下文具体说明),文件为utf8编码;第二列是情感倾向分类的类别(0表示消极;1表示积极),注意数据文件第一行固定表示为"text_a\tlabel"
Y
Yibing Liu 已提交
70

71 72 73 74 75
```text
特 喜欢 这种 好看的 狗狗                 1
这 真是 惊艳 世界 的 中国 黑科技          1
环境 特别 差 ,脏兮兮 的,再也 不去 了     0
```
L
LiuHao 已提交
76

77
注:PaddleNLP 项目提供了分词预处理脚本(在preprocess目录下),可供用户使用,具体使用方法如下:
Y
Yibing Liu 已提交
78 79

```shell
80 81
python tokenizer.py --test_data_dir ./test.txt.utf8 --batch_size 1 > test.txt.utf8.seg
#其中test.txt.utf8为待分词的文件,一条文本数据一行,utf8编码,分词结果存放在test.txt.utf8.seg文件中。
Y
Yibing Liu 已提交
82 83
```

84
#### 公开数据集
Y
Yibing Liu 已提交
85

Y
Yibing Liu 已提交
86
下载经过预处理的数据,文件解压之后,senta_data目录下会存在训练数据(train.tsv)、开发集数据(dev.tsv)、测试集数据(test.tsv)以及对应的词典(word_dict.txt)
87

Y
Yibing Liu 已提交
88 89 90 91 92
```shell
wget https://baidu-nlp.bj.bcebos.com/sentiment_classification-dataset-1.0.0.tar.gz
tar -zxvf sentiment_classification-dataset-1.0.0.tar.gz
```

93 94 95 96 97 98 99
```text
.
├── train.tsv				# 训练集
├── train.tsv           # 验证集
├── test.tsv				# 测试集
├── word_dict.txt			# 词典
```
Y
Yibing Liu 已提交
100

101
### 单机训练
Y
Yibing Liu 已提交
102

103
基于示例的数据集,可以运行下面的命令,在训练集(train.tsv)上进行模型训练,并在开发集(dev.tsv)验证
Y
Yibing Liu 已提交
104
```shell
105 106 107 108
# BOW、CNN、LSTM、BI-LSTM、GRU模型
sh run.sh train
# ERNIE、ERNIE+BI-LSTM模型
sh run_ernie.sh train
Y
Yibing Liu 已提交
109
```
110
训练完成后,可修改```run.sh```中init_checkpoint参数,进行模型评估和预测
Y
Yibing Liu 已提交
111 112

```
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
"""
# 输出结果示例
Running type options:
  --do_train DO_TRAIN   Whether to perform training. Default: False.
  ...

Model config options:
  --model_type {bow_net,cnn_net,lstm_net,bilstm_net,gru_net,textcnn_net}
                        Model type to run the task. Default: textcnn_net.
  --init_checkpoint INIT_CHECKPOINT
                        Init checkpoint to resume training from. Default: .
  --save_checkpoint_dir SAVE_CHECKPOINT_DIR
                        Directory path to save checkpoints Default: .
...
"""
 ```

本项目参数控制优先级:命令行参数 > ```config.json ``` > 默认值。训练完成后,会在```./save_models``` 目录下生成以 ```step_xxx ``` 命名的模型目录。

### 模型评估
Y
Yibing Liu 已提交
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158

基于上面的预训练模型和数据,可以运行下面的命令进行测试,查看预训练模型在开发集(dev.tsv)上的评测效果
```shell
# BOW、CNN、LSTM、BI-LSTM、GRU模型
sh run.sh eval
# ERNIE、ERNIE+BI-LSTM模型
sh run_ernie.sh eval
```
注:如果用户需要使用预训练的BI-LSTM模型,需要修改run.sh和senta_config.json中的配置。run.sh脚本修改如下:
```shell
MODEL_PATH=senta_model/bilstm_model/
# 在eval()函数中,修改如下参数:
--vocab_path $MODEL_PATH/word_dict.txt
--init_checkpoint $MODEL_PATH/params
```
senta_config.json中需要修改如下:
```shell
# vob_size大小对应为上面senta_model/bilstm_model//word_dict.txt,词典大小
"vocab_size": 1256606
```
如果用户需要使用预训练的ERNIE+BI-LSTM模型,需要修改run_ernie.sh中的配置如下:
```shell
# 在eval()函数中,修改如下参数:
--init_checkpoint senta_model/ernie_bilstm_model/
--model_type "ernie_bilstm"
```
159 160 161 162 163 164 165 166
```
"""
# 输出结果示例
Load model from ./save_models/step_100
Final test result:
[test evaluation] avg loss: 0.339021, avg acc: 0.869691, elapsed time: 0.123983 s
"""
```
Y
Yibing Liu 已提交
167

168
### 模型推断
169

170
利用已有模型,可以运行下面命令,对未知label的数据(test.tsv)进行预测
171
```shell
172 173 174 175
# BOW、CNN、LSTM、BI-LSTM、GRU模型
sh run.sh infer
#ERNIE+BI-LSTM模型
sh run_ernie.sh infer
176
```
177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194

```
"""
# 输出结果示例
Load model from ./save_models/step_100
1       0.001659        0.998341
0       0.987223        0.012777
1       0.001365        0.998635
1       0.001875        0.998125
"""
```

### 预训练模型

我们开源了基于海量数据训练好的情感倾向分类模型(基于CNN、BI-LSTM、ERNIE等模型训练),可供用户直接使用,我们提供两种下载方式。

**方式一**:基于PaddleHub命令行工具(PaddleHub[安装方式](https://github.com/PaddlePaddle/PaddleHub)

195
```shell
196 197
hub download sentiment_classification --output_path ./
tar -zxvf sentiment_classification-1.0.0.tar.gz
198 199
```

200
**方式二**:直接下载脚本
Y
Yibing Liu 已提交
201 202

```shell
203 204
wget https://baidu-nlp.bj.bcebos.com/sentiment_classification-1.0.0.tar.gz
tar -zxvf sentiment_classification-1.0.0.tar.gz
Y
Yibing Liu 已提交
205 206
```

207 208 209 210 211
以上两种方式会将预训练的 CNN、BI-LSTM等模型和 ERNIE模型,保存在当前目录下,可直接修改```run.sh```脚本中的```init_checkpoint```参数进行评估、预测。

### 服务部署

为了将模型应用于线上部署,可以利用```inference_model.py``````inference_ernie_model.py``` 脚本对模型进行裁剪,只保存网络参数及裁剪后的模型。运行命令如下:
Y
Yibing Liu 已提交
212 213

```shell
214 215
sh run.sh save_inference_model
sh run_ernie.sh save_inference_model
Y
Yibing Liu 已提交
216 217
```

218 219 220 221
#### 服务器部署

请参考PaddlePaddle官方提供的 [服务器端部署](https://www.paddlepaddle.org.cn/documentation/docs/zh/1.5/advanced_usage/deploy/inference/index_cn.html) 文档进行部署上线。

Y
Yibing Liu 已提交
222 223
## 进阶使用

224
### 背景介绍
Y
Yibing Liu 已提交
225 226

传统的情感分类主要基于词典或者特征工程的方式进行分类,这种方法需要繁琐的人工特征设计和先验知识,理解停留于浅层并且扩展泛化能力差。为了避免传统方法的局限,我们采用近年来飞速发展的深度学习技术。基于深度学习的情感分类不依赖于人工特征,它能够端到端的对输入文本进行语义理解,并基于语义表示进行情感倾向的判断。
227 228

### 模型概览
Y
Yibing Liu 已提交
229 230 231 232 233 234 235 236 237 238 239

本项目针对情感倾向性分类问题,开源了一系列模型,供用户可配置地使用:

+ BOW(Bag Of Words)模型,是一个非序列模型,使用基本的全连接结构;
+ CNN(Convolutional Neural Networks),是一个基础的序列模型,能处理变长序列输入,提取局部区域之内的特征;
+ GRU(Gated Recurrent Unit),序列模型,能够较好地解决序列文本中长距离依赖的问题;
+ LSTM(Long Short Term Memory),序列模型,能够较好地解决序列文本中长距离依赖的问题;
+ BI-LSTM(Bidirectional Long Short Term Memory),序列模型,采用双向LSTM结构,更好地捕获句子中的语义特征;
+ ERNIE(Enhanced Representation through kNowledge IntEgration),百度自研基于海量数据和先验知识训练的通用文本语义表示模型,并基于此在情感倾向分类数据集上进行fine-tune获得。
+ ERNIE+BI-LSTM,基于ERNIE语义表示对接上层BI-LSTM模型,并基于此在情感倾向分类数据集上进行Fine-tune获得;

240
### 自定义模型
Y
Yibing Liu 已提交
241

242
可以根据自己的需求,组建自定义的模型,具体方法如下所示:
Y
Yibing Liu 已提交
243

244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268
1. 定义自己的网络结构

   用户可以在 ```models/classification/nets.py``` 中,定义自己的模型,只需要增加新的函数即可。假设用户自定义的函数名为```user_net```

2. 更改模型配置

```senta_config.json``` 中需要将 ```model_type``` 改为用户自定义的 ```user_net```

3. 模型训练

   通过```run.sh``` 脚本运行训练、评估、预测。

### 基于 ERNIE 进行 Finetune

ERNIE 是百度自研的基于海量数据和先验知识训练的通用文本语义表示模型,基于 ERNIE 进行 Finetune,能够提升对话情绪识别的效果。

#### 模型训练

需要先下载 ERNIE 模型,使用如下命令:

```shell
mkdir -p pretrain_models/ernie
cd pretrain_models/ernie
wget --no-check-certificate https://baidu-nlp.bj.bcebos.com/ERNIE_stable-1.0.1.tar.gz -O ERNIE_stable-1.0.1.tar.gz
tar -zxvf ERNIE_stable-1.0.1.tar.gz
Y
Yibing Liu 已提交
269
```
270 271 272

然后修改```run_ernie.sh``` 脚本中train 函数的 ```init_checkpoint``` 参数,再执行命令:

Y
Yibing Liu 已提交
273
```shell
274 275 276
#--init_checkpoint ./pretrain_models/ernie
sh run_ernie.sh train
```
Y
Yibing Liu 已提交
277

278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295
默认使用GPU进行训练,模型保存在 ```./save_models/ernie/```目录下,以 ```step_xxx ``` 命名。

#### 模型评估

根据训练结果,可选择最优的step进行评估,修改```run_ernie.sh``` 脚本中 eval 函数 ```init_checkpoint``` 参数,然后执行

```shell
#--init_checkpoint./save/step_907
sh run_ernie.sh eval

'''
# 输出结果示例
W0820 14:59:47.811139   334 device_context.cc:259] Please NOTE: device: 0, CUDA Capability: 70, Driver API Version: 9.2, Runtime API Version: 9.0
W0820 14:59:47.815557   334 device_context.cc:267] device: 0, cuDNN Version: 7.3.
Load model from ./save_models/ernie/step_907
Final validation result:
[test evaluation] avg loss: 0.260597, ave acc: 0.907336, elapsed time: 2.383077 s
'''
Y
Yibing Liu 已提交
296 297
```

298
#### 模型推断
Y
Yibing Liu 已提交
299

300 301 302 303 304 305 306 307 308 309 310 311 312 313 314
修改```run_ernie.sh``` 脚本中 infer 函数 ```init_checkpoint``` 参数,然后执行

```shell
#--init_checkpoint./save/step_907
sh run_ernie.sh infer

'''
# 输出结果示例
Load model from ./save_models/ernie/step_907
Final test result:
1      0.001130      0.998870
0      0.978465      0.021535
1      0.000847      0.999153
1      0.001498      0.998502
'''
Y
Yibing Liu 已提交
315 316
```

317
### 基于 PaddleHub 加载 ERNIE 进行 Finetune
Y
Yibing Liu 已提交
318

319
我们也提供了使用 PaddleHub 加载 ERNIE 模型的选项,PaddleHub 是 PaddlePaddle 的预训练模型管理工具,可以一行代码完成预训练模型的加载,简化预训练模型的使用和迁移学习。更多相关的介绍,可以查看 [PaddleHub](https://github.com/PaddlePaddle/PaddleHub)
Y
Yibing Liu 已提交
320

321 322 323 324 325 326
注意:使用该选项需要先安装PaddleHub,安装命令如下
```shell
pip install paddlehub
```

需要修改```run_ernie.sh```中的配置如下:
Y
Yibing Liu 已提交
327 328

```shell
329 330
# 在train()函数中,修改--use_paddle_hub选项
--use_paddle_hub true
Y
Yibing Liu 已提交
331
```
332 333

执行以下命令进行 Finetune
Y
Yibing Liu 已提交
334
```shell
335
sh run_ernie.sh train
Y
Yibing Liu 已提交
336
```
337 338

Finetune 结束后,进行 eval 或者 infer 时,需要修改 ```run_ernie.sh``` 中的配置如下:
Y
Yibing Liu 已提交
339
```shell
340 341
# 在eval()和infer()函数中,修改--use_paddle_hub选项
--use_paddle_hub true
Y
Yibing Liu 已提交
342 343
```

344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359
执行以下命令进行 eval 和 infer
```shell
sh run_ernie.sh eval
sh run_ernie.sh infer
```

## 版本更新

2019/08/26 规范化配置的使用,对模块内数据处理代码进行了重构,更新README结构,提高易用性。

2019/06/13 添加PaddleHub调用ERNIE方式。

## 作者

- [liuhao](https://github.com/ChinaLiuHao)

Y
Yibing Liu 已提交
360 361 362
## 如何贡献代码

如果你可以修复某个issue或者增加一个新功能,欢迎给我们提交PR。如果对应的PR被接受了,我们将根据贡献的质量和难度进行打分(0-5分,越高越好)。如果你累计获得了10分,可以联系我们获得面试机会或者为你写推荐信。