目录
导入库:
读取数据:
数据清洗 :
数据分析:词频统计 饼图
数据分析:词频统计 柱状图
数据分析:词频统计 词云
数据划分 训练集 和测试集
定义读取数据的函数
加载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 标签
数据清洗 :使用 正则表达式数据清洗 只要文本文字去除标清 一些不能识别的字符
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()
数据分析:词频统计 柱状图
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()#显示图像
数据分析:词频统计 词云
# 词云
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()
数据划分 训练集 和测试集
# 数据分割
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])
定义读取数据的函数
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、word2vec、textcnn、面向旅游文本的情感分析分类代码-自然语言处理文档类资源-CSDN下载
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)