bert文本情感分类、有数据代码、直接运行

 目录

导入库:

读取数据:

 数据清洗 :

数据分析:词频统计 饼图

 数据分析:词频统计 柱状图

  数据分析:词频统计 词云

数据划分 训练集 和测试集 

 定义读取数据的函数

加载bert 定义模型

定义训练参数 epoch 优化器 学习率等

训练

模型加载预测

f1分数可以达到93

 所有的数据代码 请点击:

导入库:

import torch
from torch import nn
from torch import optim
import transformers as tfs
import math
import numpy as np
import pandas as pd
from sklearn.metrics import f1_score
import warnings
import re
import jieba
warnings.filterwarnings('ignore')
from tqdm import tqdm
from sklearn.model_selection import train_test_split
from collections import Counter
import matplotlib.pyplot as plt
plt.rcParams["font.sans-serif"] = ['Simhei']
plt.rcParams["axes.unicode_minus"] = False
from pylab import *

读取数据:

data = pd.read_excel('淮安评论合集.xlsx')
train_data=data["comment"]
train_label=data["sentiment"]
print(train_data.values)
print(train_label.values)

数据是带有标签的二分类的 01 标签  

bert文本情感分类、有数据代码、直接运行_第1张图片

 数据清洗 :

使用 正则表达式数据清洗 只要文本文字去除标清 一些不能识别的字符

juzi=[]
for i in train_data:
    zifuchuan=""
#     print(re.findall('[\u4E00-\u9FA5\\s]',i))
    for ii in re.findall('[\u4E00-\u9FA5\\s]',i):
        zifuchuan=zifuchuan+str(ii)
    zifuchuan=zifuchuan.replace(" ","")
#     print(zifuchuan)
    seg = jieba.lcut(zifuchuan)
#     print(seg)
    seg=" ".join(i for i in seg)
#     print(seg)
    juzi.append(seg)
# print(juzi)

数据分析:词频统计 饼图

# print(juzi[0].split())
quanbu_juzi=[]
for i in range(len(juzi)):
    for word in juzi[i].split():
        quanbu_juzi.append(word)

word=[]
summ=[]

for key in Counter(quanbu_juzi).items():
        word.append(key[0])
        summ.append(key[1])

sorted_id = sorted(range(len(summ)), key=lambda k: summ[k], reverse=True)

sorted_word=[]
for i in sorted_id[0:20]:
    sorted_word.append(word[i])
sorted_sum=[]
for i in sorted_id[0:20]:
    sorted_sum.append(summ[i])

mpl.rcParams['font.sans-serif'] = ['SimHei']    # 显示中文字体
lt = []     # 建立空列表,用于存放计算结果
for i in range(len(sorted_sum)):      # 遍历data,每遍历一个数据进行一次运算
    result = sorted_sum[i] / sum(sorted_sum)
    lt.append(result)       # 将计算结果一次添加到lt中
plt.figure(figsize=(10,50))
plt.axes(aspect=1)
plt.pie(x=lt, autopct='%1.2f%%')       # x表示饼状图的数据,autopct后面的值1.2表示保留2位小数,1.1表示保留一位小数
plt.legend(sorted_word, loc="best")        # 绘制图的图例为name,位置为最佳
plt.title("词频饼图")     # 饼图的名称
plt.show()

bert文本情感分类、有数据代码、直接运行_第2张图片

 数据分析:词频统计 柱状图


plt.rcParams["font.sans-serif"] = ['Simhei']
plt.rcParams["axes.unicode_minus"] = False
import pandas as pd
import matplotlib.pyplot as plt
plt.figure(figsize=(10,50))#设置画布的尺寸
plt.title('词频统计图',fontsize=20)#标题,并设定字号大小
plt.xlabel(u'词',fontsize=14)#设置x轴,并设定字号大小
plt.ylabel(u'数目',fontsize=14)#设置y轴,并设定字号大小
 
#alpha:透明度;width:柱子的宽度;facecolor:柱子填充色;edgecolor:柱子轮廓色;lw:柱子轮廓的宽度;label:图例;
plt.bar(sorted_word,sorted_sum, alpha=0.2,width = 0.8,  facecolor = 'deeppink', edgecolor = 'darkblue', lw=1,)
plt.legend(loc=2)#图例展示位置,数字代表第几象限
plt.show()#显示图像

bert文本情感分类、有数据代码、直接运行_第3张图片

  数据分析:词频统计 词云

# 词云
from wordcloud import WordCloud

plt.rcParams["font.sans-serif"] = ['Simhei']
plt.rcParams["axes.unicode_minus"] = False
wc = WordCloud(
        # 设置字体,不指定就会出现乱码
        font_path=r'C:\Windows\Fonts\方正粗黑宋简体',
        # 设置背景色
        background_color='white',
        # 设置背景宽
        width=500,
        # 设置背景高
        height=350,
        # 最大字体
        max_font_size=50,
        # 最小字体
        min_font_size=10,
        mode='RGBA'
        #colormap='pink'
        )
n=""
for i in word:
    n=n+" "+str(i)
# print(n)
# 产生词云
wc.generate(n)
# 保存图片
wc.to_file(r"wordcloud.png") # 按照设置的像素宽高度保存绘制好的词云图,比下面程序显示更清晰
# 4.显示图片
# 指定所绘图名称
plt.figure("jay")
# 以图片的形式显示词云
plt.imshow(wc)
# 关闭图像坐标系
plt.axis("off")
plt.show()

bert文本情感分类、有数据代码、直接运行_第4张图片

数据划分 训练集 和测试集 

# 数据分割 
x_train,x_test,y_train,y_test = train_test_split(juzi,train_label.values,test_size=0.1,random_state=23)
#                                                    0.2 表示  八份训练 2份验证 
print(len(x_train))
print(len(x_test))
print(x_train[0:19])

bert文本情感分类、有数据代码、直接运行_第5张图片

 定义读取数据的函数

def read_batch_data (act,end):
    batch_train_inputs=x_train[act:end]
    batch_train_targets=y_train[int(act):int(end)]
    return batch_train_inputs,batch_train_targets

def test_read_batch_data (act,end):
    batch_test_inputs=x_test[act:end]
    batch_test_targets=y_test[int(act):int(end)]
    return batch_test_inputs,batch_test_targets

加载bert 定义模型

model_class, tokenizer_class, pretrained_weights = (tfs.BertModel, tfs.BertTokenizer, 'bert-base-chinese')
#                                                    模型             分词器            词汇表  
tokenizer = tokenizer_class.from_pretrained(pretrained_weights)#定义分词器
 
model = model_class.from_pretrained(pretrained_weights)#定义模型
class BertClassificationModel(nn.Module):
    def __init__(self):
        super(BertClassificationModel, self).__init__()   
        model_class, tokenizer_class, pretrained_weights = (tfs.BertModel, tfs.BertTokenizer, 'bert-base-chinese')         
        self.tokenizer = tokenizer_class.from_pretrained(pretrained_weights)
        self.bert = model_class.from_pretrained(pretrained_weights)
        self.dense = nn.Linear(768,2)  #bert默认的隐藏单元数是768, 输出单元是2,表示二分类
    def forward(self, input_ids,attention_mask):
        bert_output = self.bert(input_ids, attention_mask=attention_mask)
        bert_cls_hidden_state = bert_output[0][:,0,:]       #提取[CLS]对应的隐藏状态
        linear_output = self.dense(bert_cls_hidden_state)
        return linear_output

定义训练参数 epoch 优化器 学习率等

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
epochs =1
bert_classifier_model = BertClassificationModel().to(device)
optimizer = torch.optim.SGD(bert_classifier_model.parameters(), lr=0.01)
criterion = torch.nn.CrossEntropyLoss()
criterion.to(device)

训练

for epoch in range(epochs):
    print("第",epoch,"个epoch")
    for i in tqdm(range(1,8900,64)):
        inputs,targets=read_batch_data(i,i+64) # 数据起点和数据终点
#         print(inputs)
        labels = torch.tensor(targets).to(device)  
        batch_tokenized = tokenizer_class.from_pretrained(pretrained_weights).batch_encode_plus(inputs, padding=True, truncation=True, max_length=50)      
        input_ids = torch.tensor(batch_tokenized['input_ids']).to(device)  
        attention_mask = torch.tensor(batch_tokenized['attention_mask']).to(device)
        optimizer.zero_grad()
        outputs = bert_classifier_model(input_ids,attention_mask)
        loss = criterion(outputs,labels) # 交叉熵损失函数 必须是两个tensor进行计算啊
#         print(loss)
        loss.backward()
        optimizer.step()
    torch.save(bert_classifier_model.state_dict(), 'TNEWStrainModel'+str(epoch)+'.pth') 

模型加载预测

#模型加载:
model = BertClassificationModel()
model.load_state_dict(torch.load('TNEWStrainModel0.pth'))
model.eval()
 # 在对模型进行评估时,应该配合使用with torch.no_grad() 与 model.eval():
with torch.no_grad():
        y_pred=[]
        y_true=[]
        for i in range(0,950,64):# 
                test_inputs,test_targets=test_read_batch_data(i,i+64)
                labels = torch.tensor(test_targets).to(device)
                batch_tokenized = tokenizer_class.from_pretrained(pretrained_weights).batch_encode_plus(test_inputs, padding=True, truncation=True, max_length=50)      
                input_ids = torch.tensor(batch_tokenized['input_ids']).to(device)  
                attention_mask = torch.tensor(batch_tokenized['attention_mask']).to(device)

                outputs = bert_classifier_model(input_ids,attention_mask)
                outputs = outputs.cpu().numpy()
                for t in np.array(outputs):
#                     print(t)
                    t=np.argmax(t)
#                     print(t)
                    y_pred.append(t)
    
                for ii in test_targets:
                    y_true.append(ii)
print(y_pred)
print(y_true)
Fa=f1_score(y_true, y_pred, average='macro') 
print("Fa",Fa)

f1分数可以达到93

bert文本情感分类、有数据代码、直接运行_第6张图片

 所有的数据代码 请点击:

bert、word2vec、textcnn、面向旅游文本的情感分析分类代码-自然语言处理文档类资源-CSDN下载

你可能感兴趣的:(人工智能,手把手带你学python,自然语言语言处理,python,人工智能,计算机视觉,自然语言处理,word2vec)