当前,在BERT等预训练模型的基础上进行微调已经成了NLP任务的一个定式了。为了了解BERT怎么用,在这次实践中,我实现了一个最简单的NLP任务,即文本情感分类。
1.基于BERT进行情感分类的基本思路
所谓情感分类就是指判断句子是积极情感还是消极情感,例如说“今天这顿饭太美味了”是积极的情感,“今天这顿饭简直吃不下去”是消极的情感。
基于BERT完成情感分类的基本思路如图所示。我们知道BERT是一个预训练模型,我们把句子扔给它的时候,它对应每个字都会输出一个向量。但是在把句子扔给BERT之前,我们会在句子最前面增加一个特殊符号[CLS]。对应这个[CLS],BERT也会输出一个向量,我们就是利用这个向量来进行情感分类。为什么可以直接利用这个向量呢?这是因为BERT内部采用的是自注意力机制,自注意力机制的特点是考虑全局又聚焦重点,实际上[CLS]对应的向量已经嵌入了整个句子的信息,而且重点词字嵌入的信息权重要大。所以,我们将这个向量扔给一个全连接层,就可以完成分类任务了。由于BERT已经是一个预训练模型了,我们在做情感分类时可以将BERT的参数固定住,不再调整,而只是调整全连接层的参数,我在这次实践中就是这么做的。当然也可以同时调整BERT和全连接层的参数,但是BERT模型较大,消耗的时间会长一些。

2.数据集准备
我在网上下了一个数据集(点击可下载,提取码为zfh3),csv格式的,包含两列,一列是句子,一列是标签,如下图所示。我才这个数据集应该是来自大众点评。。。,数据里面标签为0的时候表示是消极的情感,标签为1时表示的是积极的情感。这个数据集总共有11987行,由于我用的是CPU电脑,速度实在太慢,所以我只用了200条数据,其中150条数据用于训练,50条数据用于测试。

3.数据预处理
利用BERT实现情感分类的关键就是要把数据处理成BERT需要的输入形式。BERT的输入包括三个部分:第一个部分 是句子中每个字对应的id,我们用input_ids表示,这个id需要用到BERT的字库,字库里面每个字所排的次序就是id。第二个部分 是mask,我们用input_mask表示,假设我们设置BERT输入的句子最大长度是128,如果我们的句子长度是100,那么mask前100个填1,后面28个填0。第三部分 是句子标识符id,我们用segment_ids表示,如果第一句全为0,如果是第二句全为1,以此类推,由于情感分类只涉及到一个句子,所以该标识符都是0。
将一个句子处理成上面这样的输入,要经过两步,第一步 是对句子进行分词,在英文里面叫做“tokenize”,分词后的结果称为“tokens”。对于中文来说,分词后的结果很简单,就是一个一个的字。完成该项工作可以使用tokenizer.tokenize(text)。下图分词的一个示例。

完成分词后,第二步 要将tokens转换成id,对于中文来说,就是把一个一个的字转换成字对应的id。此外呢,还要获取input_mask和segment_ids。实现该步骤可以使用tokenizer.encode_plus()。下图是一个示例,第二个参数max_seq_length是指BERT输入句子的最大长度。

下面是数据预处理的代码,保存在dataProcessor.py文件中。
import pandas as pd
import os
import logging
logging.basicConfig(format='%(asctime)s - %(levelname)s - %(name)s - %(message)s',
datefmt='%m/%d/%Y %H:%M:%S',
level=logging.INFO)
logger = logging.getLogger(__name__)
class InputExample(object):
"""A single training/test example for simple sequence classification."""
def __init__(self, text, label=None):
self.text = text
self.label = label
class InputFeatures(object):
"""A single set of features of data."""
def __init__(self, input_ids, input_mask, segment_ids, label_id):
self.input_ids = input_ids
self.input_mask = input_mask
self.segment_ids = segment_ids
self.label_id = label_id
class DataProcessor(object):
"""Base class for data converters for sequence classification data sets."""
def get_train_examples(self, data_dir):
"""Gets a collection of `InputExample`s for the train set."""
raise NotImplementedError()
def

本文详细介绍了如何使用BERT进行文本情感分类,包括数据集准备、预处理、模型搭建与训练过程。通过150条数据实现90%以上训练准确率,85%以上测试准确率。
最低0.47元/天 解锁文章
2841





