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

使用torchtext实现中文文本分类任务

发布时间:2024-01-01 05:17:16

Torchtext是一个基于PyTorch的自然语言处理库,它提供了一套方便的工具来处理文本数据集,使得数据的加载、预处理和迭代变得更加简单。Torchtext可以帮助我们轻松地构建文本分类任务,并且提供了一些常用的预处理工具来处理文本数据。

在下面的例子中,我们将使用Torchtext来实现一个中文文本分类任务,具体来说,我们将使用一个中文新闻分类数据集来构建一个分类器,以将新闻分类为政治、经济、文化或体育等类别。我们将按照以下步骤来实现这个任务:

1. 数据加载和预处理

2. 构建词汇表

3. 数据划分

4. 构建迭代器

5. 定义模型

6. 训练模型

7. 测试模型

首先,我们需要安装Torchtext库,并导入所需的模块:

!pip install torchtext
import torch
import torchtext.data as data
import torchtext.datasets as datasets

1. 数据加载和预处理:

我们将使用一个中文新闻分类数据集,该数据集已经提前下载并存储在当前目录下的一个文件夹中。为了加载数据,我们需要定义数据字段,用于指定每个字段的预处理操作和数据类型。在这个例子中,我们将使用data.Field来定义一个中文文本字段。

TEXT = data.Field(sequential=True, tokenize=lambda x: x.split(), include_lengths=True)
LABEL = data.LabelField()

在上面的代码中,sequential=True表示该字段是一个序列,tokenize=lambda x: x.split()指定将中文文本按照空格进行分词,include_lengths=True指定在生成mini-batch时包括序列的长度。LABEL = data.LabelField()定义了一个用于标签的字段。

然后,我们可以使用TabularDataset类来加载数据集。TabularDataset接受一个数据文件路径和字段列表作为参数,它将数据文件加载为一个迭代器,并将所有字段预处理和存储在torchtext生成的词汇表中。

train_data, test_data = datasets.TabularDataset.splits(
    path='./data',
    train='train.csv',
    test='test.csv',
    format='csv',
    fields=[('text', TEXT), ('label', LABEL)],
    skip_header=True
)

在上面的代码中,path指定数据集所在的文件夹路径,traintest指定训练集和测试集数据文件名,format='csv'指定数据文件的格式为csv,fields=[('text', TEXT), ('label', LABEL)]指定数据的字段格式,skip_header=True表示跳过数据文件的 行。

2. 构建词汇表:

TEXT.build_vocab(train_data, min_freq=2)
LABEL.build_vocab(train_data)

上面的代码使用训练集构建了词汇表,并指定了一个min_freq=2的参数,表示只有在词频大于等于2时才会加入到词汇表中。

3. 数据划分:

train_data, valid_data = train_data.split(split_ratio=0.8)

上面的代码将训练集划分为80%的训练数据和20%的验证数据。

4. 构建迭代器:

train_iter, valid_iter, test_iter = data.Iterator.splits(
    (train_data, valid_data, test_data),
    batch_sizes=(32, 32, 32),
    sort_key=lambda x: len(x.text),
    sort_within_batch=True,
    device=torch.device('cuda') if torch.cuda.is_available() else torch.device('cpu')
)

5. 定义模型:

import torch.nn as nn
import torch.optim as optim

class TextClassifier(nn.Module):
    def __init__(self, vocab_size, embedding_dim, hidden_dim, output_dim):
        super(TextClassifier, self).__init__()
        self.embedding = nn.Embedding(vocab_size, embedding_dim)
        self.rnn = nn.GRU(embedding_dim, hidden_dim, bidirectional=True)
        self.fc = nn.Linear(hidden_dim * 2, output_dim)
        
    def forward(self, text, text_lengths):
        embedded = self.embedding(text)
        packed_embedded = nn.utils.rnn.pack_padded_sequence(embedded, text_lengths.cpu(), enforce_sorted=False)
        packed_output, hidden = self.rnn(packed_embedded)
        output, _ = nn.utils.rnn.pad_packed_sequence(packed_output)
        hidden = torch.cat((hidden[-2,:,:], hidden[-1,:,:]), dim=1)
        return self.fc(hidden.squeeze(0))

上面的代码定义了一个简单的文本分类模型,包含一个嵌入层、一个双向GRU层和一个全连接层。在这个例子中,我们使用了一个双向GRU来编码输入文本的上下文信息,并使用最后一个时间步的隐藏状态来进行分类。

6. 训练模型:

model = TextClassifier(len(TEXT.vocab), 100, 100, len(LABEL.vocab))
optimizer = optim.Adam(model.parameters())
criterion = nn.CrossEntropyLoss()

model = model.to(device)
criterion = criterion.to(device)

def train(model):
    model.train()
    for batch in train_iter:
        optimizer.zero_grad()
        text, text_lengths = batch.text
        label = batch.label
        output = model(text, text_lengths)
        loss = criterion(output, label)
        loss.backward()
        optimizer.step()

def evaluate(model):
    model.eval()
    correct = 0
    total = 0
    for batch in valid_iter:
        text, text_lengths = batch.text
        label = batch.label
        output = model(text, text_lengths)
        _, predicted = torch.max(output.data, 1)
        total += label.size(0)
        correct += (predicted == label).sum().item()
    return correct / total

num_epochs = 10
for epoch in range(num_epochs):
    train(model)
    acc = evaluate(model)
    print('Epoch [{}/{}], Accuracy: {:.2f}%'.format(epoch+1, num_epochs, acc * 100))

在上面的代码中,我们使用Adam优化器和交叉熵损失函数来训练模型。在每个epoch中,我们遍历训练集并更新模型参数,然后在验证集上评估模型的准确率。

7. 测试模型:

def test(model):
    model.eval()
    correct = 0
    total = 0
    for batch in test_iter:
        text, text_lengths = batch.text
        label = batch.label
        output = model(text, text_lengths)
        _, predicted = torch.max(output.data, 1)
        total += label.size(0)
        correct += (predicted == label).sum().item()
    return correct / total
  
acc = test(model)
print('Test Accuracy: {:.2f}%'.format(acc * 100))

上面的代码使用测试集评估模型的准确率。

以上就是使用Torchtext实现中文文本分类任务的例子。通过Torchtext的简单准备数据和构建迭代器的方式,我们可以方便地加载文本数据、预处理和训练模型。