欢迎访问宙启技术站
智能推送

使用Python实现GRU网络进行中文文本分类

发布时间:2023-12-12 07:50:00

GRU(Gated Recurrent Unit)是一种循环神经网络(RNN)的变种,广泛应用于文本分类、语言模型等自然语言处理(NLP)任务中。本篇文章将使用Python实现一个简单的中文文本分类的GRU网络,并提供一个使用例子。

1. 数据预处理

首先,我们需要对输入的中文文本数据进行预处理。常见的预处理步骤包括文本分词、构建词表、对文本进行编码等。

import jieba
from collections import Counter

def preprocess(data):
    # 分词
    seg_data = [jieba.lcut(text) for text in data]
    
    # 统计词频
    word_counter = Counter()
    for text in seg_data:
        word_counter.update(text)
    
    # 构建词表
    word_vocab = ['<pad>', '<unk>'] + [word for word, _ in word_counter.most_common()]
    word2idx = {word: idx for idx, word in enumerate(word_vocab)}
    
    # 对文本进行编码
    encoded_data = [[word2idx.get(word, 1) for word in text] for text in seg_data]
    
    return encoded_data, word_vocab, word2idx

2. 模型定义与训练

使用PyTorch库定义GRU网络模型,并进行训练。

import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import Dataset, DataLoader

# 模型定义
class GRUModel(nn.Module):
    def __init__(self, vocab_size, embedding_dim, hidden_dim, output_dim):
        super(GRUModel, self).__init__()
        self.embedding = nn.Embedding(vocab_size, embedding_dim)
        self.gru = nn.GRU(embedding_dim, hidden_dim, batch_first=True)
        self.fc = nn.Linear(hidden_dim, output_dim)
    
    def forward(self, x):
        embedded = self.embedding(x)
        output, hidden = self.gru(embedded)
        hidden_last = hidden[-1]
        return self.fc(hidden_last)

# 数据集定义
class TextDataset(Dataset):
    def __init__(self, data, labels):
        self.data = data
        self.labels = labels
    
    def __len__(self):
        return len(self.data)
    
    def __getitem__(self, index):
        return self.data[index], self.labels[index]

# 模型训练
def train(model, train_loader, optimizer, criterion):
    model.train()
    for inputs, labels in train_loader:
        optimizer.zero_grad()
        
        inputs = inputs.to(device)
        labels = labels.to(device)
        
        outputs = model(inputs)
        loss = criterion(outputs, labels)
        
        loss.backward()
        optimizer.step()

# 使用例子
if __name__ == "__main__":
    # 读取数据
    data = [...]  # 读取中文文本数据
    labels = [...]  # 标签数据
    
    # 预处理
    encoded_data, word_vocab, word2idx = preprocess(data)
    label2idx = {...}  # 定义标签到索引的映射关系
    encoded_labels = [label2idx[label] for label in labels]
    
    # 划分训练集和测试集
    train_data = encoded_data[:800]
    train_labels = encoded_labels[:800]
    test_data = encoded_data[800:]
    test_labels = encoded_labels[800:]
    
    # 初始化模型
    device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    model = GRUModel(len(word_vocab), embedding_dim=100, hidden_dim=128, output_dim=len(label2idx))
    model.to(device)
    
    # 定义优化器和损失函数
    optimizer = optim.Adam(model.parameters())
    criterion = nn.CrossEntropyLoss()
    
    # 构造数据加载器
    train_dataset = TextDataset(train_data, train_labels)
    train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)
    
    # 训练模型
    for epoch in range(10):
        train(model, train_loader, optimizer, criterion)
    
    # 测试模型
    test_data_tensor = torch.LongTensor(test_data).to(device)
    test_labels_tensor = torch.LongTensor(test_labels).to(device)
    
    model.eval()
    with torch.no_grad():
        outputs = model(test_data_tensor)
        _, predicted_labels = torch.max(outputs, 1)
        accuracy = torch.sum(predicted_labels == test_labels_tensor) / len(test_labels_tensor)
        print("Accuracy: {:.2f}%".format(accuracy * 100))

本例中的GRU网络模型采用了单层GRU结构,并在最后一个时间步处取出隐藏状态作为文本的表示。模型的输入是一个文本序列,经过embedding层嵌入后输入GRU层,并将最后一个时间步处的隐藏状态通过全连接层映射到输出类别上。

以上是使用Python实现GRU网络进行中文文本分类的简单示例。你可以根据实际需求对模型结构进行调整,并根据数据的不同特点进行数据预处理和训练过程的修改。