PyTorch情感分析教程:基于NBoW模型的IMDb影评分类

PyTorch情感分析教程:基于NBoW模型的IMDb影评分类

pytorch-sentiment-analysis pytorch-sentiment-analysis 项目地址: https://gitcode.com/gh_mirrors/py/pytorch-sentiment-analysis

引言

情感分析是自然语言处理(NLP)中的一个重要任务,旨在判断文本表达的情感倾向。本教程将使用PyTorch框架,从零开始构建一个基于神经网络词袋模型(NBoW)的情感分析系统,对IMDb电影评论进行正面/负面分类。

技术背景

什么是NBoW模型?

NBoW(Neural Bag-of-Words)模型,也称为连续词袋模型(CBoW),是NLP中最基础的神经网络模型之一。它的核心思想是:

  1. 将输入文本视为一个无序的词集合(词袋)
  2. 通过嵌入层将每个词转换为向量表示
  3. 对所有词向量进行聚合(如平均或求和)
  4. 通过全连接层输出分类结果

这种模型虽然简单,但在许多文本分类任务中都能提供不错的基线性能。

为什么选择IMDb数据集?

IMDb数据集包含5万条电影评论,每条评论标注为正面或负面。这个数据集具有以下特点:

  • 规模适中,适合教学演示
  • 文本长度和复杂度适中
  • 是情感分析领域的标准基准数据集

数据准备

1. 环境配置

首先导入必要的Python库:

import datasets
import torch
import torch.nn as nn
import torchtext
from torchtext.data.utils import get_tokenizer

设置随机种子保证实验可复现:

seed = 1234
torch.manual_seed(seed)
torch.cuda.manual_seed(seed)

2. 数据加载与探索

加载IMDb数据集并查看其结构:

train_data, test_data = datasets.load_dataset("imdb", split=["train", "test"])
print(train_data.features)

输出显示数据集包含两个特征:

  • text: 电影评论文本(string类型)
  • label: 情感标签(0表示负面,1表示正面)

3. 文本分词处理

使用基础英文分词器处理文本:

tokenizer = get_tokenizer("basic_english")

def tokenize_example(example, max_length=256):
    tokens = tokenizer(example["text"])[:max_length]
    return {"tokens": tokens}

train_data = train_data.map(tokenize_example)
test_data = test_data.map(tokenize_example)

分词后的结果存储在新增的tokens特征中,每个评论被转换为一个词序列。

构建NBoW模型

1. 模型架构

NBoW模型的核心组件包括:

  1. 嵌入层(Embedding Layer): 将离散的词索引映射为连续的词向量
  2. 聚合层(Pooling Layer): 对所有词向量进行平均或求和
  3. 全连接层(Linear Layer): 输出最终的分类结果
class NBoWModel(nn.Module):
    def __init__(self, vocab_size, embedding_dim, output_dim):
        super().__init__()
        self.embedding = nn.Embedding(vocab_size, embedding_dim)
        self.fc = nn.Linear(embedding_dim, output_dim)
        
    def forward(self, text):
        # text shape: [batch_size, seq_len]
        embedded = self.embedding(text)  # [batch_size, seq_len, emb_dim]
        pooled = embedded.mean(dim=1)   # [batch_size, emb_dim]
        return self.fc(pooled)

2. 构建词汇表

将分词后的文本转换为数字索引:

from collections import Counter

def build_vocab(tokenized_texts, min_freq=5):
    counter = Counter()
    for tokens in tokenized_texts:
        counter.update(tokens)
    vocab = torchtext.vocab.vocab(counter, min_freq=min_freq)
    vocab.insert_token("<unk>", 0)
    vocab.set_default_index(0)
    return vocab

vocab = build_vocab(train_data["tokens"])

3. 数据批处理

创建数据加载器,将数据组织为批次:

def numericalize_example(example, vocab):
    ids = [vocab[token] for token in example["tokens"]]
    return {"ids": ids}

train_data = train_data.map(numericalize_example)
test_data = test_data.map(numericalize_example)

from torch.utils.data import DataLoader

def collate_fn(batch):
    ids = [torch.tensor(item["ids"]) for item in batch]
    labels = torch.tensor([item["label"] for item in batch])
    ids = nn.utils.rnn.pad_sequence(ids, batch_first=True)
    return ids, labels

train_loader = DataLoader(train_data, batch_size=32, collate_fn=collate_fn)
test_loader = DataLoader(test_data, batch_size=32, collate_fn=collate_fn)

模型训练与评估

1. 初始化模型

vocab_size = len(vocab)
embedding_dim = 100
output_dim = 1  # 二分类问题

model = NBoWModel(vocab_size, embedding_dim, output_dim)

2. 定义损失函数和优化器

criterion = nn.BCEWithLogitsLoss()
optimizer = optim.Adam(model.parameters())

3. 训练循环

def train(model, iterator, optimizer, criterion):
    model.train()
    epoch_loss = 0
    
    for batch in iterator:
        optimizer.zero_grad()
        predictions = model(batch[0]).squeeze(1)
        loss = criterion(predictions, batch[1].float())
        loss.backward()
        optimizer.step()
        epoch_loss += loss.item()
        
    return epoch_loss / len(iterator)

4. 评估函数

def evaluate(model, iterator, criterion):
    model.eval()
    epoch_loss = 0
    
    with torch.no_grad():
        for batch in iterator:
            predictions = model(batch[0]).squeeze(1)
            loss = criterion(predictions, batch[1].float())
            epoch_loss += loss.item()
            
    return epoch_loss / len(iterator)

5. 完整训练过程

N_EPOCHS = 5

for epoch in range(N_EPOCHS):
    train_loss = train(model, train_loader, optimizer, criterion)
    test_loss = evaluate(model, test_loader, criterion)
    print(f"Epoch: {epoch+1:02}")
    print(f"\tTrain Loss: {train_loss:.3f}")
    print(f"\tTest Loss: {test_loss:.3f}")

模型优化与改进

虽然NBoW模型简单有效,但仍有改进空间:

  1. 处理未知词:添加<unk>标记处理未见过的词汇
  2. 预训练词向量:使用GloVe等预训练词向量初始化嵌入层
  3. 调整模型结构:增加隐藏层或使用更复杂的聚合方式
  4. 超参数调优:调整嵌入维度、学习率等参数

总结

本教程详细介绍了如何使用PyTorch构建一个基础的NBoW情感分析模型。通过这个项目,我们学习了:

  1. 文本数据预处理流程
  2. 词嵌入的基本概念
  3. 简单的神经网络分类模型构建
  4. PyTorch训练循环的实现

NBoW模型虽然简单,但为理解更复杂的NLP模型奠定了良好基础。读者可以在此基础上尝试更先进的模型架构,如RNN、CNN或Transformer等。

pytorch-sentiment-analysis pytorch-sentiment-analysis 项目地址: https://gitcode.com/gh_mirrors/py/pytorch-sentiment-analysis

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

包怡妹Alina

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值