NLP_情感分类_序列模型方案

news2024/9/22 7:41:47

文章目录

  • 项目背景
  • 代码
    • 导包
    • 读取数据
    • 文本预处理
    • 举例查看分词器
    • 数据集调整
      • 进一步剖析:对应Step [{i+1}/{len(train_loader)}] 里的train_loader
      • 进一步剖析:Step [{i+1}/{len(train_loader)}] 里的train_loader,原始的train_df
    • 计算数据集中最长文本的长度
    • 定义模型
    • 超参数
      • 进一步剖析label_encoder.classes_
    • 训练 RNN 模型
    • 训练 GRU 模型
    • 训练 LSTM 模型
  • 同类型项目


项目背景

项目的目的,是为了对情感评论数据集进行预测打标。在训练之前,需要对数据进行数据清洗环节,前面已对数据进行清洗,详情可移步至NLP_情感分类_数据清洗
前面用机器学习方案解决,详情可移步至NLP_情感分类_机器学习方案

下面对已清洗的数据集,用序列模型方案进行处理

代码

导包

import warnings
warnings.filterwarnings('ignore')
import pandas as pd
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import Dataset, DataLoader
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder
from torchtext.data.utils import get_tokenizer
from torchtext.vocab import build_vocab_from_iterator
from torch.nn.utils.rnn import pad_sequence
import torch.nn.functional as F  

读取数据

df = pd.read_csv('data/sentiment_analysis_clean.csv')
df = df.dropna()

文本预处理

tokenizer = get_tokenizer('basic_english')
def yield_tokens(data_iter):
    for text in data_iter:
        yield tokenizer(text)

vocab = build_vocab_from_iterator(yield_tokens(df['text']), specials=["<unk>"])
vocab.set_default_index(vocab["<unk>"])

# 标签编码
label_encoder = LabelEncoder()
df['label'] = label_encoder.fit_transform(df['label'])

# 划分训练集和测试集
train_df, test_df = train_test_split(df, test_size=0.2, random_state=2024)

# 转换为 PyTorch 张量
def text_pipeline(x):
    return vocab(tokenizer(x))

def label_pipeline(x):
    return int(x)

举例查看分词器

tokenizer('I like apple'),vocab(tokenizer('I like apple'))

在这里插入图片描述

数据集调整

class TextDataset(Dataset):
    def __init__(self, df):
        self.texts = df['text'].values
        self.labels = df['label'].values

    def __len__(self):
        return len(self.texts)

    def __getitem__(self, idx):
        text = torch.tensor(text_pipeline(self.texts[idx]), dtype=torch.long)
        label = torch.tensor(label_pipeline(self.labels[idx]), dtype=torch.long)
        return text, label

train_dataset = TextDataset(train_df)
test_dataset = TextDataset(test_df)

def collate_batch(batch):
    text_list, label_list = [], []
    for (text, label) in batch:
        text_list.append(text)
        label_list.append(label)
    text_list = pad_sequence(text_list, batch_first=True, padding_value=vocab['<pad>'])
    label_list = torch.tensor(label_list, dtype=torch.long)
    return text_list, label_list

train_loader = DataLoader(train_dataset, batch_size=128, shuffle=True, collate_fn=collate_batch)
test_loader = DataLoader(test_dataset, batch_size=128, shuffle=False, collate_fn=collate_batch)

进一步剖析:对应Step [{i+1}/{len(train_loader)}] 里的train_loader

len(train_dataset)

在这里插入图片描述

进一步剖析:Step [{i+1}/{len(train_loader)}] 里的train_loader,原始的train_df

len(train_df)

在这里插入图片描述

计算数据集中最长文本的长度

max_seq_len = 0
for text in df['text']:
    tokens = text_pipeline(text)
    if len(tokens) > max_seq_len:
        max_seq_len = len(tokens)

print(f'Max sequence length in the dataset: {max_seq_len}')

在这里插入图片描述

定义模型

class TextClassifier(nn.Module):
    def __init__(self, model_type, vocab_size, embed_dim, hidden_dim, output_dim, num_layers=1):
        super(TextClassifier, self).__init__()
        self.model_type = model_type
        self.embedding = nn.Embedding(vocab_size, embed_dim, padding_idx=vocab['<pad>'])

        if model_type == 'RNN':
            self.rnn = nn.RNN(embed_dim, hidden_dim, num_layers, batch_first=True)
        elif model_type == 'GRU':
            self.rnn = nn.GRU(embed_dim, hidden_dim, num_layers, batch_first=True)
        elif model_type == 'LSTM':
            self.rnn = nn.LSTM(embed_dim, hidden_dim, num_layers, batch_first=True)
        else:
            raise ValueError("model_type should be one of ['RNN', 'GRU', 'LSTM']")

        if model_type in ['RNN', 'GRU', 'LSTM']:
            self.fc = nn.Linear(hidden_dim, output_dim)
    def forward(self, x):
        x = self.embedding(x) # [batch,seq_len,emb_dim]
        if self.model_type in ['RNN', 'GRU', 'LSTM']:
            h0 = torch.zeros(self.rnn.num_layers, x.size(0), self.rnn.hidden_size).to(x.device)
            if self.model_type == 'LSTM':
                c0 = torch.zeros(self.rnn.num_layers, x.size(0), self.rnn.hidden_size).to(x.device)
                out, _ = self.rnn(x, (h0, c0))
            else:
                out, _ = self.rnn(x, h0)
            # out :[batch,seq_len,emb_dim]
            out = self.fc(out[:, -1, :]) # 使用输出序列最后一个时间步的表征作为序列整体的表征
        else:
            raise ValueError("model_type should be one of ['RNN', 'GRU', 'LSTM']")           
        return out
def train_model(model, train_loader, criterion, optimizer, num_epochs=2, device='cpu'):
    model.to(device)
    model.train()
    for epoch in range(num_epochs):
        running_loss = 0.0
        correct = 0
        total = 0
        for i, (texts, labels) in enumerate(train_loader):
            texts, labels = texts.to(device), labels.to(device)
            outputs = model(texts)
            loss = criterion(outputs, labels)
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()

            running_loss += loss.item()
            
            _, predicted = torch.max(outputs.data, 1)
            total += labels.size(0)
            correct += (predicted == labels).sum().item()
            
            if i % 10 == 0:  # 每个批次输出一次日志
                accuracy = 100 * correct / total
                print(f'Epoch [{epoch+1}/{num_epochs}], Step [{i+1}/{len(train_loader)}], Loss: {loss.item():.4f}, Accuracy: {accuracy:.2f}%')
        
        epoch_loss = running_loss / len(train_loader)
        epoch_accuracy = 100 * correct / total
        print(f'Epoch [{epoch+1}/{num_epochs}], Average Loss: {epoch_loss:.4f}, Average Accuracy: {epoch_accuracy:.2f}%')

def evaluate_model(model, test_loader, device='cpu'):
    model.to(device)
    model.eval()
    correct = 0
    total = 0
    with torch.no_grad():
        for texts, labels in test_loader:
            texts, labels = texts.to(device), labels.to(device)
            outputs = model(texts)
            _, predicted = torch.max(outputs.data, 1)
            total += labels.size(0)
            correct += (predicted == labels).sum().item()
    print(f'Accuracy: {100 * correct / total:.2f}%')

超参数

vocab_size = len(vocab)
embed_dim = 128
hidden_dim = 128
output_dim = len(label_encoder.classes_)
num_layers = 1
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

进一步剖析label_encoder.classes_

len(label_encoder.classes_)

在这里插入图片描述

训练 RNN 模型

model_rnn = TextClassifier('RNN', vocab_size, embed_dim, hidden_dim, output_dim, num_layers)
criterion = nn.CrossEntropyLoss()
optimizer_rnn = optim.Adam(model_rnn.parameters(), lr=0.001)
train_model(model_rnn, train_loader, criterion, optimizer_rnn, num_epochs=2, device=device)
evaluate_model(model_rnn, test_loader, device=device)

在这里插入图片描述

训练 GRU 模型

model_gru = TextClassifier('GRU', vocab_size, embed_dim, hidden_dim, output_dim, num_layers)
optimizer_gru = optim.Adam(model_gru.parameters(), lr=0.001)
train_model(model_gru, train_loader, criterion, optimizer_gru, num_epochs=2, device=device)
evaluate_model(model_gru, test_loader, device=device)

在这里插入图片描述

训练 LSTM 模型

model_lstm = TextClassifier('LSTM', vocab_size, embed_dim, hidden_dim, output_dim, num_layers)
optimizer_lstm = optim.Adam(model_lstm.parameters(), lr=0.001)
train_model(model_lstm, train_loader, criterion, optimizer_lstm, num_epochs=2, device=device)
evaluate_model(model_lstm, test_loader, device=device)

在这里插入图片描述

同类型项目

阿里云-零基础入门NLP【基于机器学习的文本分类】

阿里云-零基础入门NLP【基于深度学习的文本分类3-BERT】
也可以参考进行学习


学习的参考资料:
深度之眼

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

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

相关文章

Java 并发(四)—— volatile 和 synchronized

一、volatile 关键字 1.概念 如果我们将一个变量使用 volatile 修饰&#xff0c;这就指示 编译器&#xff0c;这个变量是共享且不稳定的&#xff0c;每次使用它都到主存中进行读取。 2.作用 保证变量对所有线程的可见性。但不能保证数据的原子性。因此不能完全保证线程安全…

STP(生成树)的概述和工作原理

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:Linux运维老纪的首页…

PHPStorm 环境配置与应用详解

​ 大家好&#xff0c;我是程序员小羊&#xff01; 前言&#xff1a; PHPStorm 是 JetBrains 出品的一款专业 PHP 集成开发环境&#xff08;IDE&#xff09;&#xff0c;凭借其智能的代码补全、调试功能、深度框架支持和前端开发工具&#xff0c;为用户提供了丰富的功能和工具…

简单的敏感词提示功能

简单的敏感词提示功能 1. 需求 公司现在接到通知&#xff0c;部分接口的部分手动输入字段&#xff0c;需要新增敏感词报红提示&#xff0c;敏感词汇现在应该是7000多个左右&#xff0c;需要我们提供一个敏感词校验接口&#xff0c;如果前端输入敏感词&#xff0c;则前端提示出…

在Unreal Engine中使用C++创建基础角色并添加移动功能

目录 引言 步骤一&#xff1a;创建C类 步骤二&#xff1a;编写C代码 步骤三&#xff1a;设置输入绑定 步骤四&#xff1a;在UE编辑器中测试 结论 引言 Unreal Engine&#xff08;UE&#xff09;以其强大的功能和灵活性在游戏开发界广受好评。本文将指导你如何在UE中通过…

校园外卖平台小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;商家管理&#xff0c;菜品信息管理&#xff0c;菜品分类管理&#xff0c;购买菜品管理&#xff0c;订单信息管理&#xff0c;系统管理 微信端账号功能包括&#xff1a;系统首页&a…

揭开ChatGPT进化之谜:人工智能如何变得更聪明

近年来&#xff0c;人工智能&#xff08;AI&#xff09;领域取得了显著进展&#xff0c;尤其是在自然语言处理&#xff08;NLP&#xff09;方面。OpenAI的GPT系列模型&#xff0c;如GPT-3和ChatGPT&#xff0c;代表了这一领域的前沿技术。本文将围绕ChatGPT提升的原因、发展趋势…

基于JSP的个性化影片推荐系统

你好呀&#xff0c;我是计算机学姐码农小野&#xff01;如果有相关需求&#xff0c;可以私信联系我。 开发语言&#xff1a;JSP 数据库&#xff1a;MySQL 技术&#xff1a;JSP技术 工具&#xff1a;MyEclipse、Tomcat、MySQL 系统展示 首页 管理员功能模块 用户功能模块 …

国外评论家称《黑神话》PC版有性能问题 还有卡顿现象

《黑神话&#xff1a;悟空》即将正式发售&#xff0c;人们对这款游戏的期待值相当高。所以许多粉丝在耐心等待第一批评测报道&#xff0c;然后再购买这款游戏。在8月16日媒体评测解禁之前&#xff0c;有一位国外评论家认为《黑神话&#xff1a;悟空》是一款好游戏&#xff0c;但…

Vue的监视属性watch、computed和watch之间的区别

目录 1. 监视属性2. 监视属性的简写3. computed和watch之间的区别 1. 监视属性 监听对象: 监视属性可以监听普通属性和计算属性调用时间: 当监听的属性发生改变时。handler被调用immediate: true: 是否初始化时让handler调用一下。此时oldVlue为undefineddeep: false: watch默…

美国洛杉矶大带宽服务器的运维与监控

美国洛杉矶的大带宽服务器因其优越的地理位置、高速的网络连接以及充足的带宽资源&#xff0c;在全球范围内享有很高的声誉。为了确保这些服务器的稳定运行和高效服务&#xff0c;运维与监控工作显得尤为重要。以下是一些关于美国洛杉矶大带宽服务器运维与监控方面的科普内容。…

CentOS7 配置 nginx 和 php 方案

配置方案 一、安装软件二、编写配置文件&#xff0c;连接PHP三、引用文件四、测试 鉴于网上教程错综复杂&#xff0c;写下一这篇文章 本教程只需要三步即可 一、安装软件 yum install -y nginx php php-fpm二、编写配置文件&#xff0c;连接PHP 一般情况下在安装完 nginx 后…

css实现太极图

<template><div><!-- 太极图 --><div class"all"><div class"left box"></div><div class"right box"></div><div class"black"><div class"inner_white"><…

16.3 简单神经网络的实现

欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;欢迎订阅相关专栏&#xff1a; 工&#x1f497;重&#x1f497;hao&#x1f497;&#xff1a;野老杂谈 ⭐️ 全网最全IT互联网公司面试宝典&#xff1a;收集整理全网各大IT互联网公司技术、项目、HR面试真题.…

java或者sh脚本实现 实现 mysql 数据库定时导出并导入(适合linux和windows)

定时导出指定数据库的指定表导出到指定数据库 一、Java实现 1、contronller Slf4j Controller public class BackupController {AutowiredBackupService backupService;// 备份 // ResponseBody // PostMapping("/backup/backupByfile")Scheduled(cron&quo…

CANopen 控制多台设备的支持能力与定制方案评估

1. CANopen 支持的设备数量 CAN 总线的物理限制&#xff1a;CANopen 基于 CAN 总线协议&#xff0c;其设备数量受到 CAN 总线物理层的限制。标准 CAN 总线通常支持最多 127 个节点&#xff0c;但实际应用中&#xff0c;考虑到总线负载、波特率、线缆长度、网络拓扑等因素&#…

(Java)集合框架

1.集合的简介 集合Collection&#xff0c;也是一个数据容器&#xff0c;类似于数组&#xff0c;但是和数组是不一样的。集合是一个可变的容器&#xff0c;可以随时向集合中添加元素&#xff0c;也可以随时从集合中删除元素。另外&#xff0c;集合还提供了若干个用来操作集合中…

[upload]-[GXYCTF2019]BabyUpload1-笔记

尝试上传.htaccess和图片和一句话木马提示 php文件提示 响应头可以看到 构造一句话图片木马如下&#xff1a; <script languagephp>eval($_POST[cmd]);</script> 上传成功 必须增加文件夹下jpg后缀解析php .htaccess如下 <FilesMatch "jpg">Set…

windows关闭英语美式键盘

命令窗口 在Windows 中&#xff0c;如果你可通过批处理文件&#xff08;.bat&#xff09;关闭或移除美式键盘布局&#xff0c;可以使用以下步骤创建一个简单的批处理脚本&#xff1a; 打开windows命令窗口 执行命令 reg add "HKCU\Keyboard Layout\Toggle" /v &quo…

多模态感知:打造温室作物的全方位“健康档案“

&#xff08; 于景鑫 国家农业信息化工程技术研究中心&#xff09;现代农业的发展&#xff0c;离不开现代科技的支撑。在温室种植领域&#xff0c;由于环境复杂多变、管理要素繁多&#xff0c;传统人工经验难以应对日益精细化、智能化的生产需求。多模态感知技术的出现&#xf…