Python 语言 用 PyTorch 实现情感分析 BERT 模型微调中文语料 + 混淆矩阵评估

Python阿木 发布于 2 天前 5 次阅读


使用 PyTorch 和 BERT 模型实现情感分析:代码与实践

情感分析是自然语言处理(NLP)领域的一个重要任务,旨在识别和分类文本中的情感倾向。随着深度学习技术的快速发展,基于预训练语言模型的情感分析方法取得了显著的成果。本文将使用 PyTorch 和 BERT 模型,结合中文语料进行情感分析,并通过混淆矩阵评估模型性能。

环境准备

在开始之前,请确保您的环境中已安装以下库:

- PyTorch
- Transformers
- torchtext
- sklearn

您可以使用以下命令安装所需的库:

bash
pip install torch transformers torchtext sklearn

数据准备

为了进行情感分析,我们需要一个包含文本和对应情感标签的数据集。以下是一个简单的数据集示例:

python
data = [
("这是一个非常好的产品", "正面"),
("这个产品真的很差劲", "负面"),
("这个产品一般般", "中性"),
... 更多数据
]

将数据集转换为 PyTorch 数据加载器:

python
from torchtext.data import Field, BucketIterator

TEXT = Field(tokenize="spacy", tokenizer_language="zh_core_web_sm", lower=True)
LABEL = Field(sequential=False)

train_data, test_data = data[::2], data[1::2]

train_dataset, test_dataset = TEXT.build_dataset(train_data, label=LABEL), TEXT.build_dataset(test_data, label=LABEL)

train_iterator, test_iterator = BucketIterator.splits(
(train_dataset, test_dataset),
batch_size=32,
sort_key=lambda x: len(x.text),
sort_within_batch=True,
device=device
)

模型构建

接下来,我们将使用 BERT 模型进行情感分析。我们需要从 Hugging Face 的 Transformers 库中加载预训练的 BERT 模型。

python
from transformers import BertModel, BertTokenizer

tokenizer = BertTokenizer.from_pretrained('bert-base-chinese')
model = BertModel.from_pretrained('bert-base-chinese')

然后,我们将定义一个简单的情感分析模型,它将使用 BERT 模型的输出进行分类。

python
import torch.nn as nn

class SentimentClassifier(nn.Module):
def __init__(self):
super(SentimentClassifier, self).__init__()
self.bert = BertModel.from_pretrained('bert-base-chinese')
self.dropout = nn.Dropout(0.5)
self.classifier = nn.Linear(768, 2) BERT 基础模型的隐藏层大小为 768

def forward(self, text):
text = tokenizer(text, padding=True, truncation=True, return_tensors="pt")
output = self.bert(text)
hidden_states = output.last_hidden_state
pooled_output = hidden_states[:, 0, :]
pooled_output = self.dropout(pooled_output)
logits = self.classifier(pooled_output)
return logits

model = SentimentClassifier()

训练模型

现在,我们可以开始训练模型了。我们将使用交叉熵损失函数和 Adam 优化器。

python
from torch.optim import Adam
from torch.utils.data import DataLoader

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model.to(device)

criterion = nn.CrossEntropyLoss()
optimizer = Adam(model.parameters(), lr=1e-5)

def train(model, iterator, optimizer, criterion):
model.train()
epoch_loss = 0
for batch in iterator:
optimizer.zero_grad()
text = batch.text
labels = batch.label
text = text.to(device)
labels = labels.to(device)
logits = model(text)
loss = criterion(logits, labels)
loss.backward()
optimizer.step()
epoch_loss += loss.item()
return epoch_loss / len(iterator)

def evaluate(model, iterator, criterion):
model.eval()
epoch_loss = 0
with torch.no_grad():
for batch in iterator:
text = batch.text
labels = batch.label
text = text.to(device)
labels = labels.to(device)
logits = model(text)
loss = criterion(logits, labels)
epoch_loss += loss.item()
return epoch_loss / len(iterator)

epochs = 3
for epoch in range(epochs):
train_loss = train(model, train_iterator, optimizer, criterion)
test_loss = evaluate(model, test_iterator, criterion)
print(f"Epoch: {epoch+1}, Train Loss: {train_loss:.4f}, Test Loss: {test_loss:.4f}")

评估模型

为了评估模型性能,我们将使用混淆矩阵。

python
from sklearn.metrics import confusion_matrix
import seaborn as sns
import matplotlib.pyplot as plt

def plot_confusion_matrix(cm, class_names):
fig, ax = plt.subplots(figsize=(8, 8))
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues', xticklabels=class_names, yticklabels=class_names)
ax.set_xlabel('Predicted labels')
ax.set_ylabel('True labels')
ax.set_title('Confusion Matrix')
ax.xaxis.set_ticklabels(class_names)
ax.yaxis.set_ticklabels(class_names)
plt.show()

def predict(model, iterator):
model.eval()
predictions = []
true_labels = []
with torch.no_grad():
for batch in iterator:
text = batch.text
labels = batch.label
text = text.to(device)
labels = labels.to(device)
logits = model(text)
_, predicted = torch.max(logits, 1)
predictions.extend(predicted.cpu().numpy())
true_labels.extend(labels.cpu().numpy())
return predictions, true_labels

predictions, true_labels = predict(model, test_iterator)
cm = confusion_matrix(true_labels, predictions)
plot_confusion_matrix(cm, ['正面', '负面', '中性'])

结论

本文使用 PyTorch 和 BERT 模型实现了情感分析任务。通过微调预训练的 BERT 模型,我们能够对中文语料进行情感分类。通过混淆矩阵评估,我们可以看到模型的性能。在实际应用中,您可以根据需要调整模型结构、超参数和训练数据,以提高模型的性能。