LSTM中文新闻分类源码详解

LSTM中文新闻分类

  • 一、导包
  • 二、读取数据
  • 三、数据预处理
    • 1.分词、去掉停用词和数字、字母转换成小写等
    • 2.新闻文本标签数值化
  • 三、创建词汇表/词典
    • 1.data.Field()
    • 2.空格切分等
    • 3.构建词汇表/词典
      • 使用训练集构建单词表,vectors=None:没有使用预训练好的词向量,而是使用的是随机初始化的词向量,默认是100维
    • 这里面的20002,多的那两个应该是
  • 四、构造数据集迭代器,方便批处理
    • batch.cutword[0]和batch.cutword[1]
      • batch.cutword[0]:表示的是一批数据也就是64条新闻,每条新闻都会被分词,分成一个一个的词语,每个词语在词典中的索引,最后面的1表示的是不足400,填充的<pad>对应在词典中的索引为1。
      • batch.cutword[1]:表示的是一批数据也就是64条新闻,每条新闻对应所有新闻中的索引号。
  • 五、搭建LSTM网络
    • r_out, (h_n, h_c)分别是:
      • r_out是最终输出结果y(根据今天,昨天和日记)
      • h_n是隐藏层的输出结果s(根据昨天)
      • h_c是长期信息的输出结果c(根据日记)
  • 六、LSTM网络的训练
  • 七、LSTM网络的测试

一、导包

%config InlineBackend.figure_format = 'retina'
%matplotlib inline
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from matplotlib.font_manager import FontProperties 
fonts = FontProperties(fname = "/Library/Fonts/华文细黑.ttf")
import re   
import string  
import copy   
import time   
from sklearn.metrics import accuracy_score,confusion_matrix   
import torch
from torch import nn
import torch.nn.functional as F
import torch.optim as optim
import torch.utils.data as Data
import jieba
jieba.setLogLevel(jieba.logging.INFO)
from torchtext.legacy import data
from torchtext.vocab import Vectors
#从 PyTorch 的拓展库 torchtext 中导入了 Vectors 类,该类用于处理词向量(word embeddings)

二、读取数据

train_df = pd.read_csv("data/lstm/cnews/cnews.train.txt",sep="\t",header=None,names = ["label","text"])
val_df = pd.read_csv("data/lstm/cnews/cnews.val.txt",sep="\t",header=None,names = ["label","text"])
test_df = pd.read_csv("data/lstm/cnews/cnews.test.txt",sep="\t",header=None,names = ["label","text"])
train_df.head(5)

在这里插入图片描述

三、数据预处理

stop_words = pd.read_csv("data/lstm/cnews/中文停用词库.txt",header=None,names = ["text"])

1.分词、去掉停用词和数字、字母转换成小写等

## 对中文文本数据进行预处理,去除一些不需要的字符,分词,去停用词,等操作
def chinese_pre(text_data):## 字母转化为小写,去除数字,text_data = text_data.lower()text_data = re.sub("\d+", "", text_data)## 分词,使用精确模式text_data = list(jieba.cut(text_data,cut_all=False)) ## 去停用词和多余空格text_data = [word.strip() for word in text_data if word not in stop_words.text.values]## 处理后的词语使用空格连接为字符串text_data = " ".join(text_data)return text_data
train_df["cutword"] = train_df.text.apply(chinese_pre)
val_df["cutword"] = val_df.text.apply(chinese_pre)
test_df["cutword"] = test_df.text.apply(chinese_pre)
## 预处理后的结果保存为新的文件
train_df[["label","cutword"]].to_csv("data/lstm/cnews_train.csv",index=False)
val_df[["label","cutword"]].to_csv("data/lstm/cnews_val.csv",index=False)
test_df[["label","cutword"]].to_csv("data/lstm/cnews_test.csv",index=False)
train_df.cutword.head()

在这里插入图片描述

train_df = pd.read_csv("data/lstm/cnews_train.csv")
val_df = pd.read_csv("data/lstm/cnews_val.csv")
test_df = pd.read_csv("data/lstm/cnews_test.csv")

2.新闻文本标签数值化

labelMap = {"体育": 0,"娱乐": 1,"家居": 2,"房产": 3,"教育": 4,"时尚": 5,"时政": 6,"游戏": 7,"科技": 8,"财经": 9}
train_df["labelcode"] =train_df["label"].map(labelMap)
val_df["labelcode"] =val_df["label"].map(labelMap)
test_df["labelcode"] =test_df["label"].map(labelMap)
train_df.head()

在这里插入图片描述

train_df[["labelcode","cutword"]].to_csv("data/lstm/cnews_train2.csv",index=False)
val_df[["labelcode","cutword"]].to_csv("data/lstm/cnews_val2.csv",index=False)
test_df[["labelcode","cutword"]].to_csv("data/lstm/cnews_test2.csv",index=False)

三、创建词汇表/词典

1.data.Field()

data.Field参数与方法详解

2.空格切分等

按照空格进行分词,cutword是序列数据,labelcode不是序列数据

## 使用torchtext库进行数据准备
# 定义文件中对文本和标签所要做的操作
"""
sequential=True:表明输入的是序列数据
tokenize="spacy":使用spacy切分词语
use_vocab=True: 创建词汇表
batch_first=True: batch优先的数据方式
fix_length=400 :每个句子固定长度为400,不足会默认使用 <pad> 符号填充
"""
## 定义文本切分方法,因为前面已经做过处理,所以直接使用空格切分即可
mytokenize = lambda x: x.split()
TEXT = data.Field(sequential=True, tokenize=mytokenize, include_lengths=True, use_vocab=True,batch_first=True, fix_length=400)
LABEL = data.Field(sequential=False, use_vocab=False, pad_token=None, unk_token=None)
## 对所要读取的数据集的列进行处理
text_data_fields = [("labelcode", LABEL), # 对标签的操作("cutword", TEXT) # 对文本的操作
]
## 读取数据
traindata,valdata,testdata = data.TabularDataset.splits(path="data/lstm", format="csv", train="cnews_train2.csv", fields=text_data_fields, validation="cnews_val2.csv",test = "cnews_test2.csv", skip_header=True
)
len(traindata),len(valdata),len(testdata)

在这里插入图片描述

## 检查一个样本的标签和文本
em = traindata.examples[0]
print(em.labelcode)
print(em.cutword)

在这里插入图片描述

3.构建词汇表/词典

使用训练集构建单词表,vectors=None:没有使用预训练好的词向量,而是使用的是随机初始化的词向量,默认是100维

TEXT.build_vocab(traindata,max_size=20000,vectors = None)
LABEL.build_vocab(traindata)
## 可视化训练集中的前50个高频词
word_fre = TEXT.vocab.freqs.most_common(n=50)
word_fre = pd.DataFrame(data=word_fre,columns=["word","fre"])
word_fre.plot(x="word", y="fre", kind="bar",legend=False,figsize=(12,7))
plt.xticks(rotation = 90,fontproperties = fonts,size = 10)
plt.show()print("词典的词数:",len(TEXT.vocab.itos))
print("前10个单词:\n",TEXT.vocab.itos[0:10])
## 类别标签的数量和类别
print("类别标签情况:",LABEL.vocab.freqs)

在这里插入图片描述在这里插入图片描述

这里面的20002,多的那两个应该是

在这里插入图片描述

四、构造数据集迭代器,方便批处理

## 定义一个迭代器,将类似长度的示例一起批处理。
BATCH_SIZE = 64
train_iter = data.BucketIterator(traindata,batch_size = BATCH_SIZE)
val_iter = data.BucketIterator(valdata,batch_size = BATCH_SIZE)
test_iter = data.BucketIterator(testdata,batch_size = BATCH_SIZE)
##  获得一个batch的数据,对数据进行内容进行介绍
for step, batch in enumerate(train_iter):  if step > 0:break
## 针对一个batch 的数据,可以使用batch.labelcode获得数据的类别标签
print("数据的类别标签:\n",batch.labelcode)
## batch.cutword[0]是文本对应的标签向量
print("数据的尺寸:",batch.cutword[0].shape)
## batch.cutword[1] 对应每个batch使用的原始数据中的索引
print("数据样本数:",len(batch.cutword[1]))

在这里插入图片描述

batch.cutword[0]和batch.cutword[1]

batch.cutword[0]:表示的是一批数据也就是64条新闻,每条新闻都会被分词,分成一个一个的词语,每个词语在词典中的索引,最后面的1表示的是不足400,填充的对应在词典中的索引为1。

batch.cutword[1]:表示的是一批数据也就是64条新闻,每条新闻对应所有新闻中的索引号。

在这里插入图片描述

##  获得一个batch的数据,对数据进行内容进行介绍
for step, batch in enumerate(train_iter):  textdata,target = batch.cutword[0],batch.labelcode.view(-1)if step > 0:break
# ## 针对一个batch 的数据,可以使用batch.labelcode获得数据的类别标签
# print("数据的类别标签:\n",batch.labelcode)
# ## batch.cutword[0]是文本对应的标签向量
# print("数据的尺寸:",batch.cutword[0].shape)
# ## batch.cutword[1] 对应每个batch使用的原始数据中的索引
# print("数据样本数:",len(batch.cutword[1]))

五、搭建LSTM网络

class LSTMNet(nn.Module):def __init__(self, vocab_size,embedding_dim, hidden_dim, layer_dim, output_dim):"""vocab_size:词典长度embedding_dim:词向量的维度hidden_dim: RNN神经元个数layer_dim: RNN的层数output_dim:隐藏层输出的维度(分类的数量)"""super(LSTMNet, self).__init__()self.hidden_dim = hidden_dim ## RNN神经元个数self.layer_dim = layer_dim ## RNN的层数## 对文本进行词向量处理self.embedding = nn.Embedding(vocab_size, embedding_dim)# LSTM + 全连接层self.lstm = nn.LSTM(embedding_dim, hidden_dim, layer_dim,batch_first=True)self.fc1 = nn.Linear(hidden_dim, output_dim)def forward(self, x):embeds = self.embedding(x)# r_out shape (batch, time_step, output_size)# h_n shape (n_layers, batch, hidden_size)   LSTM 有两个 hidden states, h_n 是分线, h_c 是主线# h_c shape (n_layers, batch, hidden_size)r_out, (h_n, h_c) = self.lstm(embeds, None)   # None 表示 hidden state 会用全0的 state# 选取最后一个时间点的out输出out = self.fc1(r_out[:, -1, :]) return out

r_out, (h_n, h_c)分别是:

r_out是最终输出结果y(根据今天,昨天和日记)

h_n是隐藏层的输出结果s(根据昨天)

h_c是长期信息的输出结果c(根据日记)

vocab_size = len(TEXT.vocab)
embedding_dim = 100
hidden_dim = 128
layer_dim = 1
output_dim = 10
lstmmodel = LSTMNet(vocab_size, embedding_dim, hidden_dim, layer_dim, output_dim)
lstmmodel

在这里插入图片描述

六、LSTM网络的训练

## 定义网络的训练过程函数
def train_model2(model,traindataloader, valdataloader,criterion, optimizer,num_epochs=25,):"""model:网络模型;traindataloader:训练数据集;valdataloader:验证数据集,;criterion:损失函数;optimizer:优化方法;num_epochs:训练的轮数"""train_loss_all = []train_acc_all = []val_loss_all = []val_acc_all = []since = time.time()for epoch in range(num_epochs):print('-' * 10)print('Epoch {}/{}'.format(epoch, num_epochs - 1))# 每个epoch有两个阶段,训练阶段和验证阶段train_loss = 0.0train_corrects = 0train_num = 0val_loss = 0.0val_corrects = 0val_num = 0model.train() ## 设置模型为训练模式for step,batch in enumerate(traindataloader):textdata,target = batch.cutword[0],batch.labelcode.view(-1)out = model(textdata)pre_lab = torch.argmax(out,1) # 预测的标签loss = criterion(out, target) # 计算损失函数值optimizer.zero_grad()   #梯度清零     loss.backward()       #损失函数反向传播optimizer.step()        #更新梯度train_loss += loss.item() * len(target)train_corrects += torch.sum(pre_lab == target.data)train_num += len(target)## 计算一个epoch在训练集上的损失和精度train_loss_all.append(train_loss / train_num)train_acc_all.append(train_corrects.double().item()/train_num)print('{} Train Loss: {:.4f}  Train Acc: {:.4f}'.format(epoch, train_loss_all[-1], train_acc_all[-1]))## 计算一个epoch的训练后在验证集上的损失和精度model.eval() ## 设置模型为训练模式评估模式 for step,batch in enumerate(valdataloader):textdata,target = batch.cutword[0],batch.labelcode.view(-1)out = model(textdata)pre_lab = torch.argmax(out,1)loss = criterion(out, target)   val_loss += loss.item() * len(target)val_corrects += torch.sum(pre_lab == target.data)val_num += len(target)## 计算一个epoch在训练集上的损失和精度val_loss_all.append(val_loss / val_num)val_acc_all.append(val_corrects.double().item()/val_num)print('{} Val Loss: {:.4f}  Val Acc: {:.4f}'.format(epoch, val_loss_all[-1], val_acc_all[-1]))train_process = pd.DataFrame(data={"epoch":range(num_epochs),"train_loss_all":train_loss_all,"train_acc_all":train_acc_all,"val_loss_all":val_loss_all,"val_acc_all":val_acc_all})  return model,train_process
# 定义优化器
optimizer = torch.optim.Adam(lstmmodel.parameters(), lr=0.0003)  
loss_func = nn.CrossEntropyLoss()   # 损失函数
## 对模型进行迭代训练,对所有的数据训练EPOCH轮
lstmmodel,train_process = train_model2(lstmmodel,train_iter,val_iter,loss_func,optimizer,num_epochs=20)

在这里插入图片描述
在这里插入图片描述

## 输出结果保存和数据保存
torch.save(lstmmodel,"data/lstm/lstmmodel.pkl")
## 导入保存的模型
lstmmodel = torch.load("data/lstm/lstmmodel.pkl")
lstmmodel
## 保存训练过程
train_process.to_csv("data/lstm/lstmmodel_process.csv",index=False)
train_process

在这里插入图片描述

## 可视化模型训练过程中
plt.figure(figsize=(18,6))
plt.subplot(1,2,1)
plt.plot(train_process.epoch,train_process.train_loss_all,"r.-",label = "Train loss")
plt.plot(train_process.epoch,train_process.val_loss_all,"bs-",label = "Val loss")
plt.legend()
plt.xlabel("Epoch number",size = 13)
plt.ylabel("Loss value",size = 13)
plt.subplot(1,2,2)
plt.plot(train_process.epoch,train_process.train_acc_all,"r.-",label = "Train acc")
plt.plot(train_process.epoch,train_process.val_acc_all,"bs-",label = "Val acc")
plt.xlabel("Epoch number",size = 13)
plt.ylabel("Acc",size = 13)
plt.legend()
plt.show()

在这里插入图片描述

七、LSTM网络的测试

## 对测试集进行预测并计算精度
lstmmodel.eval() ## 设置模型为训练模式评估模式 
test_y_all = torch.LongTensor()
pre_lab_all = torch.LongTensor()
for step,batch in enumerate(test_iter):textdata,target = batch.cutword[0],batch.labelcode.view(-1)out = lstmmodel(textdata)pre_lab = torch.argmax(out,1)test_y_all = torch.cat((test_y_all,target)) ##测试集的标签pre_lab_all = torch.cat((pre_lab_all,pre_lab))##测试集的预测标签acc = accuracy_score(test_y_all,pre_lab_all)
print("在测试集上的预测精度为:",acc)
## 计算混淆矩阵并可视化
class_label = ["体育","娱乐","家居","房产","教育","时尚","时政","游戏","科技","财经"]
conf_mat = confusion_matrix(test_y_all,pre_lab_all)
df_cm = pd.DataFrame(conf_mat, index=class_label, columns=class_label)
heatmap = sns.heatmap(df_cm, annot=True, fmt="d",cmap="YlGnBu")
heatmap.yaxis.set_ticklabels(heatmap.yaxis.get_ticklabels(), rotation=0,ha='right',fontproperties = fonts)
heatmap.xaxis.set_ticklabels(heatmap.xaxis.get_ticklabels(), rotation=45,ha='right',fontproperties = fonts)
plt.ylabel('True label')
plt.xlabel('Predicted label')
plt.show()

在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/579821.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

阿里云自建官方Docker仓库镜像提交拉取方法

文章目录 发布镜像到DockerHub发布镜像到自建Docker仓库(Harbor)修改配置文件在Linux服务器中登录Docker打TAGPUSH提交镜像PULL拉取镜像 发布镜像到阿里云容器服务在Linux服务器中登录DockerPUSH提交镜像PULL拉取镜像 发布镜像到DockerHub 本地我们镜像命名可能会不规范&#…

详解Keras3.0 Layer API: LSTM layer

LSTM layer 用于实现长短时记忆网络&#xff0c;它的主要作用是对序列数据进行建模和预测。 遗忘门&#xff08;Forget Gate&#xff09;&#xff1a;根据当前输入和上一个时间步的隐藏状态&#xff0c;计算遗忘门的值。遗忘门的作用是控制哪些信息应该被遗忘&#xff0c;哪些…

C++面试宝典第10题:绘制各种图形

题目 我们需要编写一个图形相关的应用程序,并处理大量图形(Shape)信息,图形有矩形(Rectangle)、正方形(Square)、圆形(Circle)等种类。应用程序需要计算这些图形的面积,并且可能需要在某个设备上进行显示(使用在标准输出上打印信息的方式作为示意)。 (1)请使用面…

华为——使用ACL限制内网主机访问外网网站示例

组网图形 图1 使用ACL限制内网主机访问外网网站示例 ACL简介配置注意事项组网需求配置思路操作步骤配置文件 ACL简介 访问控制列表ACL&#xff08;Access Control List&#xff09;是由一条或多条规则组成的集合。所谓规则&#xff0c;是指描述报文匹配条件的判断语句&#…

大数据开发之Sqoop详细介绍

测试环境 CDH 6.3.1 Sqoop 1.4.7 一.Sqoop概述 Apache Sqoop&#xff08;SQL-to-Hadoop&#xff09;项目旨在协助RDBMS与Hadoop之间进行高效的大数据交流。用户可以在 Sqoop 的帮助下&#xff0c;轻松地把关系型数据库的数据导入到 Hadoop 与其相关的系统 (如HBase和Hive)中&…

IRIS、Cache系统类汉化

文章目录 系统类汉化简介标签说明汉化系统包说明效果展示类分类%Library包下的类重点类非重点类弃用类数据类型类工具类 使用说明 系统类汉化 简介 帮助小伙伴更加容易理解后台系统程序方法使用&#xff0c;降低代码的难度。符合本土化中文环境的开发和维护&#xff0c;有助于…

年底大厂今年发多少年终奖,怎么发(上)?

马上就2023年年底了&#xff0c;互联网大厂腾讯员工首先&#xff0c;发年终奖了&#xff0c;111354 元&#xff01; 腾讯的同学可以查一查了&#xff0c;应该发多少已经定下来了&#xff01;&#x1f44b; 除此之外&#xff0c;千寻找了很多的大厂的年终奖发放时间&#xff0c;…

Android Studio 如何隐藏默认标题栏

目录 前言 一、修改清单文件 二、修改代码 三、更多资源 前言 在 Android 应用中&#xff0c;通常会有一个默认的标题栏&#xff0c;用于显示应用的名称和一些操作按钮。但是&#xff0c;在某些情况下&#xff0c;我们可能需要隐藏默认的标题栏&#xff0c;例如自定义标题栏…

时序预测 | Matlab实现SSA-CNN-LSTM麻雀算法优化卷积长短期记忆神经网络时间序列预测

时序预测 | Matlab实现SSA-CNN-LSTM麻雀算法优化卷积长短期记忆神经网络时间序列预测 目录 时序预测 | Matlab实现SSA-CNN-LSTM麻雀算法优化卷积长短期记忆神经网络时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 MATLAB实现SSA-CNN-LSTM麻雀算法优化卷积长短…

【HarmonyOS开发】探究Hap与App包的结构与区别

1、Hap与App包的区别 OpenHarmony 可以进行两种形式&#xff08;Hap和App&#xff09;的打包&#xff0c;HAP是用于本地调试的&#xff0c;APP包是用于上架发布的。 根据不同的设备类型&#xff0c;一个APP包可以包含多个HAP包。 下面从两个角度进行分析 1.1 编译构建角度 编…

uniapp中uview的text组件

基本使用&#xff1a; 通过text参数设置文本内容。推荐您使用:textvalue的形式 <u--text text"我用十年青春,赴你最后之约"></u--text>设置主题&#xff1a; 通过type参数设置文本主题&#xff0c;我们提供了五类属性。primary error success warning…

【leetcode100-021】【矩阵】搜索二维矩阵 II

【题干】 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性&#xff1a; 每行的元素从左到右升序排列。每列的元素从上到下升序排列。 【思路】 以右上角为起点斜着看这个矩阵&#xff0c;会发现&#xff0c;这是一颗二叉搜索树。 …

中间件系列 - Redis入门到实战(高级篇-分布式缓存)

前言 学习视频&#xff1a; 黑马程序员Redis入门到实战教程&#xff0c;深度透析redis底层原理redis分布式锁企业解决方案黑马点评实战项目 本内容仅用于个人学习笔记&#xff0c;如有侵扰&#xff0c;联系删除 学习目标 Redis持久化Redis主从Redis哨兵Redis分片集群 一 分…

每日一题——LeetCode876.链表的中间结点

个人主页&#xff1a;白日依山璟 专栏&#xff1a;Java|数据结构与算法|每日一题 1.题目描述 给你单链表的头结点 head &#xff0c;请你找出并返回链表的中间结点。 如果有两个中间结点&#xff0c;则返回第二个中间结点。 示例1 输入&#xff1a;head [1,2,3,4,5] 输出&…

nginx-proxy-manager初次登录502 bad gateway

nginx-proxy-manager初次登录502 bad gateway 按照官方docker-compose安装后,页面如下: 默认账户密码: adminexample.com/changeme点击sign in,提示Bad Gateway 打开调试 重装后依然如此,最后查阅githup issue 找到答案 https://github.com/NginxProxyManager/nginx-proxy-…

【教学类-43-01】20231226 九宫格数独1.0

作品展示——九宫格数独&#xff08;正方形手工纸&#xff09; 背景需求&#xff1a; 最近陆续出了“X-Y比大小”“X-Y加法判断题”&#xff0c;发现1/3大4班孩子都能完成&#xff0c;3-4位孩子表示“太简单”。 大4班20号同学&#xff0c;做完0-10的判断题后说&#xff1a;“…

mongodb聚合_删除_可视化工具

3.5 MongoDB中limit和skip MongoDB Limit() 方法 如果你需要在MongoDB中读取指定数量的数据记录&#xff0c;可以使用MongoDB的Limit方法&#xff0c;limit()方法接受一个数字参数&#xff0c;该参数指定从MongoDB中读取的记录条数。limit()方法基本语法如下所示&#xff1a;…

跟着LearnOpenGL学习12--光照贴图

文章目录 一、前言二、漫反射贴图三、镜面光贴图3.1、采样镜面光贴图 一、前言 在跟着LearnOpenGL学习11–材质中&#xff0c;我们讨论了让每个物体都拥有自己独特的材质从而对光照做出不同的反应的方法。这样子能够很容易在一个光照的场景中给每个物体一个独特的外观&#xf…

机器学习——决策树(三)

【说明】文章内容来自《机器学习——基于sklearn》&#xff0c;用于学习记录。若有争议联系删除。 1、案例一 决策树用于是否赖床问题。 采用决策树进行分类&#xff0c;要经过数据采集、特征向量化、模型训练和决策树可视化4个步骤。 赖床数据链接&#xff1a;https://pan…

解决Pycharm pip安装模块太慢问题,pycharm2022没有manage repositories配置镜像源

解决方案 方法清华阿里云中国科技大学华中理工大学 或者直接-i 加镜像 方法 URL写下面任意一个 清华 https://pypi.tuna.tsinghua.edu.cn/simple阿里云 http://mirrors.aliyun.com/pypi/simple/中国科技大学 https://pypi.mirrors.ustc.edu.cn/simple/华中理工大学 http:/…