PyTorch情感分析教程:基于NBoW模型的IMDb影评分类
pytorch-sentiment-analysis 项目地址: https://gitcode.com/gh_mirrors/py/pytorch-sentiment-analysis
引言
情感分析是自然语言处理(NLP)中的一个重要任务,旨在判断文本表达的情感倾向。本教程将使用PyTorch框架,从零开始构建一个基于神经网络词袋模型(NBoW)的情感分析系统,对IMDb电影评论进行正面/负面分类。
技术背景
什么是NBoW模型?
NBoW(Neural Bag-of-Words)模型,也称为连续词袋模型(CBoW),是NLP中最基础的神经网络模型之一。它的核心思想是:
- 将输入文本视为一个无序的词集合(词袋)
- 通过嵌入层将每个词转换为向量表示
- 对所有词向量进行聚合(如平均或求和)
- 通过全连接层输出分类结果
这种模型虽然简单,但在许多文本分类任务中都能提供不错的基线性能。
为什么选择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模型的核心组件包括:
- 嵌入层(Embedding Layer): 将离散的词索引映射为连续的词向量
- 聚合层(Pooling Layer): 对所有词向量进行平均或求和
- 全连接层(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模型简单有效,但仍有改进空间:
- 处理未知词:添加
<unk>
标记处理未见过的词汇 - 预训练词向量:使用GloVe等预训练词向量初始化嵌入层
- 调整模型结构:增加隐藏层或使用更复杂的聚合方式
- 超参数调优:调整嵌入维度、学习率等参数
总结
本教程详细介绍了如何使用PyTorch构建一个基础的NBoW情感分析模型。通过这个项目,我们学习了:
- 文本数据预处理流程
- 词嵌入的基本概念
- 简单的神经网络分类模型构建
- PyTorch训练循环的实现
NBoW模型虽然简单,但为理解更复杂的NLP模型奠定了良好基础。读者可以在此基础上尝试更先进的模型架构,如RNN、CNN或Transformer等。
pytorch-sentiment-analysis 项目地址: https://gitcode.com/gh_mirrors/py/pytorch-sentiment-analysis
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考