当前位置:   article > 正文

基于Bert的中文情感分析代码及分析_bert中文情感分析代码

bert中文情感分析代码

基于Bert的中文情感分析代码及分析

众所周知,Google 前段时间开源了他们的 BERT – BidirectionalEncoderRepresentations fromTransformers 模型,使用多头注意力和位置嵌入,一举打破自然语言处理领域11个不同问题的最好记录。NLP界开启一个全新的时代,利用Bert做NLP的任务也是取得很好的效果,本文利用微调Bert模型做中文情感分析,实验效果也算不错。本文参考[博文链接]。(https://blog.csdn.net/renxingkai/article/details/87605693)

数据准备

中文语料库获取:Github别人分享的各种语料库,这里有很多不同的中文语料库。
在这里插入图片描述
当然也可以从别的地方获取语料库。本文主要是通过SMP2019评测比赛获取的数据集。情感类标签是0,1,2,数据如下:
在这里插入图片描述

Bert预训练

拥有了数据集之后,需要下载Bert模型,Bert模型下载
下载完之后在data文件夹里放入训练集,验证集和测试集数据。
在这里插入图片描述
在开源的代码中,预训练的入口是在run_pretraining.py而fine-tune的入口针对不同的任务分别在run_classifier.py和run_squad.py。其中run_classifier.py适用的任务为分类任务。如CoLA、MRPC、MultiNLI这些数据集。而run_squad.py适用的是阅读理解(MRC)任务,如squad2.0和squad1.1。本文是做情感分类任务,因此主要修改run_classifier.py里的一些代码。下载的代码要是想运行,需要安装Tensorflow和pandas,直接pip install 就行。
在这里插入图片描述

本实验中增加的Processor代码为:

如果读取文件格式为csv格式

class SentenceProcessor(DataProcessor):
    """Processor for the Sentiment Analysis task"""
    #读取训练集
    def get_train_examples(self, data_dir):
      file_path = os.path.join(data_dir, 'train.csv')
      train_df = pd.read_csv(file_path, encoding='utf-8')
      train_data = []
      for index, train in enumerate(train_df.values):
          guid = 'train-%d' % index
          text_a = tokenization.convert_to_unicode(str(train[0]))
          # text_b = tokenization.convert_to_unicode(str(train[1]))
          label = str(train[1])
          train_data.append(InputExample(guid=guid, text_a=text_a, text_b=None, label=label))
      return train_data
    #读取验证集
    def get_dev_examples(self, data_dir):
      file_path = os.path.join(data_dir, 'dev.csv')
      dev_df = pd.read_csv(file_path, encoding='utf-8')
      dev_data = []
      for index, dev in enumerate(dev_df.values):
          guid = 'dev-%d' % index
          text_a = tokenization.convert_to_unicode(str(dev[0]))
          # text_b = tokenization.convert_to_unicode(str(dev[1]))
          label = str(dev[1])
          dev_data.append(InputExample(guid=guid, text_a=text_a, text_b=None, label=label))
      return dev_data
      #读取测试集
          def get_test_examples(self, data_dir):
        file_path = os.path.join(data_dir, 'test.csv')
        test_df = pd.read_csv(file_path, encoding='utf-8')
        test_data = []
        for index, test in enumerate(test_df.values):
            guid = 'test-%d' % index
            text_a = tokenization.convert_to_unicode(str(test[0]))
            # text_b = tokenization.convert_to_unicode(str(test[1]))
            label = str(test[1])
            test_data.append(InputExample(guid=guid, text_a=text_a, text_b=None, label=label))
        return test_data
	#生成类标签
    def get_labels(self):
        return ['0', '1', '2']
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

如果读取的文件是Txt格式

    def get_train_examples(self, data_dir):
        file_path = os.path.join(data_dir, 'train_sentiment.txt')
        f = open(file_path, 'r', encoding='utf-8')
        train_data = []
        index = 0
        for line in f.readlines():
            guid = 'train-%d' % index#参数guid是用来区分每个example的
            line = line.replace("\n", "").split("\t")
            text_a = tokenization.convert_to_unicode(str(line[1]))#要分类的文本
            label = str(line[2])#文本对应的情感类别
            train_data.append(InputExample(guid=guid, text_a=text_a, text_b=None, label=label))#加入到InputExample列表中
            index += 1
        return train_data      
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
    def get_dev_examples(self, data_dir):
        file_path = os.path.join(data_dir, 'test_sentiment.txt')
        f = open(file_path, 'r', encoding='utf-8')
        dev_data = []
        index = 0
        for line in f.readlines():
            guid = 'dev-%d' % index
            line = line.replace("\n", "").split("\t")
            text_a = tokenization.convert_to_unicode(str(line[1]))
            label = str(line[2])
            dev_data.append(InputExample(guid=guid, text_a=text_a, text_b=None, label=label))
            index += 1
        return dev_data
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

修改 processor 字典

def main(_):
    tf.logging.set_verbosity(tf.logging.INFO)

    processors = {
        "cola": ColaProcessor,
        "mnli": MnliProcessor,
        "mrpc": MrpcProcessor,
        "xnli": XnliProcessor,
        "sa": SentenceProcessor,
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

至此,run_classifier.py需要修改的就完成了。

训练 BERT 微调任务

之后就可以直接运行run_classsifier.py进行模型的训练。编写运行脚本,新建一个运行脚本文件名为“run.sh”,在运行时需要制定一些参数,一个较为完整的运行参数如下所示。当然也可以打开powershell 直接输入一下命令运行。

python3 run_classifier.py \
  --data_dir=data \
  --task_name=sa \
  --vocab_file=chinese_L-12_H-768_A-12/vocab.txt \
  --bert_config_file=chinese_L-12_H-768_A-12/bert_config.json \
  --output_dir=sa_model \
  --do_train=true \
  --do_eval=true \
  --init_checkpoint=chinese_L-12_H-768_A-12/bert_model.ckpt \
  --max_seq_length=70 \
  --train_batch_size=32 \
  --learning_rate=5e-5 \
  --num_train_epochs=3.0

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

这是cpu进行训练的,如果觉得时间长,可以更改–num_train_epochs=1.0。

验证结果为:

在这里插入图片描述
Bert分类任务中只有准确率和损失,本文在运行时增加了进行分类任务精确率、召回率的计算。

训练完之后需要预测

python3.6 run_classifier.py \
  --task_name=sa \
  --do_predict=true \
  --data_dir=data \
  --vocab_file=chinese_L-12_H-768_A-12/vocab.txt \
  --bert_config_file=chinese_L-12_H-768_A-12/bert_config.json \
  --init_checkpoint=tmp/sim_model \
  --max_seq_length=70 \
  --output_dir=output

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

运行结果

运行完之后会生成一个test_results,类似于如下结果:
在这里插入图片描述

得到的结果是以概率的形式表示极性,因此写一个转化脚本。

import os
import pandas as pd

if __name__ == '__main__':
    pd_all = pd.read_csv(os.path.join("test_results.tsv"), sep='\t', header=None)
    data = pd.DataFrame(columns=['polarity'])
    print(pd_all.shape)

    for index in pd_all.index:
        neutral_score = pd_all.loc[index].values[0]
        positive_score = pd_all.loc[index].values[1]
        negative_score = pd_all.loc[index].values[2]

        if max(neutral_score, positive_score, negative_score) == neutral_score:
            
            data.loc[index+1] = ["0"]
        elif max(neutral_score, positive_score, negative_score) == positive_score:
            
            data.loc[index+1] = ["1"]
        else:
          
            data.loc[index+1] = ["2"]
            
data.to_csv(os.path.join("pre_sample.tsv"), sep='\t')

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

结果变成

在这里插入图片描述

总结

用Bert做中文情感分析取得结果比较不错,本文主要是用了隐=式情感分析的语料库,所以效果一般。用Bert预测显示情感效果会很好。

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

闽ICP备14008679号