手把手实战:用BERT中文模型微调微博情感分析(附完整代码+数据集+中文模型)
1. 引言
在自然语言处理(NLP)任务中,情感分析是最经典的应用之一。近年来,预训练语言模型(如BERT)的出现大幅提升了文本分类的效果。然而,很多开发者对“如何微调BERT”仍然感到无从下手——数据怎么处理?训练代码怎么写?训练好的模型怎么用?
我前段时间想弄一个对微博评论进行情感分析的系统,查了很多资料,也看了很多博客,结果找到的文章,大部分都是解释,什么是bert,它的机制是什么,它可以用来做什么,但是,我就是找不到,应该怎么使用它。
如果你是一个大学生,或者对这方面了解不多的开发者,你会发现,你花了很长的时间来学习和了解它,最后好像知道它是什么了,可以用来干什么了,却还是一头雾水,不知道该从哪里开始。
在我看来,这是一种本末倒置的现象,bert本质上其实只是一个工具,我们最应该学习的,就是应该怎么使用它,就像你使用ai,你不需要知道它是怎么训练的,也不需要知道它的底层逻辑和机制是什么,你只需要知道,我怎么向他发提示词,让他能够完成我想完成的工作,就够了。
基于这种想法,我写下了这篇文章,本文不会告诉你bert是什么,机制是什么,谁发明的,我会从以下几点告诉你,你该怎么使用他,并且完全可以复现。
本文将带你从零开始,使用 Hugging Face 的 transformers 库和 bert-base-chinese 预训练模型,完成一个微博评论情感二分类任务。你将获得:
-
一份可直接运行的训练脚本(含SwanLab可视化)
-
一份批量预测 CSV 的推理脚本
-
数据清洗、模型保存与加载的最佳实践
最终效果:输入一段中文评论,模型能判断它是积极(positive)还是消极(negative)。
2. 环境准备与依赖安装
我使用的是python版本是3.12,PyCharm版本是2024的版本,别的版本应该也可以,别太老导致运行库不兼容即可。
如果你没有python环境或pycharm,可以到官网进行下载,也可以下载我的安装包进行安装,下面的是安装包链接:
通过网盘分享的文件:pycharm-professional-2024.1.exe等2个文件
链接: https://pan.baidu.com/s/1CTD_ozq9cibUkiN7Wmeekw 提取码: myj8
下载后双击安装即可
安装后,安装必要的运行库,主要是下面的库,语法如下:
pip install torch transformers datasets pandas scikit-learn swanlab
-
torch:深度学习框架,GPU加速推理 -
transformers:Hugging Face 模型库,提供BERT及分词器 -
datasets:高效处理数据集 -
pandas:读写 CSV、数据清洗 -
swanlab:国内可用的实验跟踪可视化工具(可选,若不使用可移除相关代码)
3. 数据集准备
安装完环境后,你需要找到一个数据集进行训练,在这里进行一个简单的解释,我使用的模型名称是bert-base-chinese,它是一个预训练的模型,什么意思呢,你可以把它看成是一个中文词典,有了它,电脑就可以认出我们的中文,也就是说它现在只能认识中文,并不能进行情感分析,所以我们此时要告诉他,什么话是积极的,什么话是消极的,这就是对模型进行训练,也可以称为微调,而要训练它,我们会需要一个数据集,数据集的格式如下图:

它分为了两列,左边的一列是label,里面是数字0和1,分别代表消极和积极,右边则是文本,这个数据集内的文本都是微博中的评论,1和0是人工提前进行标注的,通过把这样的数据集喂给模型,让他知道,什么样的评论应该标上1,什么样的评论应该标上0,就实现了对文本进行情感分析。
我使用的数据是一个拥有10万条微博评论的数据集,这是我在网上找到的,并非我自行标注,但是准确率也挺高了,以下是数据集的链接可以直接进行下载:
链接: https://pan.baidu.com/s/1xkCTCi0-Aj_pl-4ab3GIdA 提取码: i5zm
使用10万条微博情感数据,包含两列:
-
review:评论文本 -
label:0(消极)或 1(积极)
你需要确保数据格式与本例一致,路径默认为脚本同级目录。若无此数据集,也可以用其他带情感标签的中文文本 CSV 替代,只需确保列名为 review 和 label。
4. 模型训练脚本详解
数据集和模型可以说是一一对应的,之前有说,我们使用的模型是bert-base-chinese,数据集也是中文的,如果你下载了别的版本,就可能会报错,因为可能别的模型不认识中文,而是一本“英文词典”,你告诉它“好!”这样的句子应该打上标签1,但是它只认识“good”,所以,选择正确的模型和数据集,可以让你事半功倍。
下面是我使用的模型的下载链接:
链接: https://pan.baidu.com/s/1HNWd4dK5eb1cp57dBTWCtg 提取码: 491y
准备好了数据集和模型,就要使用脚本开始训练模型。
训练模型的脚本文件是“训练.py”,你不需要知道它的原理,知道它是用来干嘛的,以及怎么使用即可,我会发出完整的脚本代码,你只需要修改如模型存放位置,训练步数等参数即可。
链接如下:
链接: https://pan.baidu.com/s/1zkUrQDkhQFO1HSJdJQYPog 提取码: shnk
训练.py 负责加载数据、微调BERT、保存最佳模型。核心步骤如下。
4.1 导入库与预测函数
import torch
from datasets import load_dataset, Dataset
from transformers import AutoTokenizer, AutoModelForSequenceClassification, Trainer, TrainingArguments
from swanlab.integration.huggingface import SwanLabCallback
import swanlab
import pandas as pd
def predict(text, model, tokenizer, CLASS_NAME):
inputs = tokenizer(text, return_tensors="pt", padding=True, truncation=True)
device = next(model.parameters()).device
inputs = {k: v.to(device) for k, v in inputs.items()}
with torch.no_grad():
outputs = model(**inputs)
logits = outputs.logits
predicted_class = torch.argmax(logits).item()
print(f"Input Text: {text}")
print(f"Predicted class: {int(predicted_class)} {CLASS_NAME[int(predicted_class)]}")
return int(predicted_class)
这段函数用于快速验证模型效果,它会自动跟随模型所在的设备(CPU/GPU),无需手动指定,需要注意的是,训练模型最好使用GPU,如果没有GPU的话,训练速度会很慢,我训练的时候出现了有GPU但是模型仍然在CPU上跑的情况,出现这种情况的原因是:默认安装的 torch 只是 CPU 版,或者 CUDA 版本与你的显卡驱动不匹配。
出现这种情况,我们需要卸载掉默认安装的torch库,代码如下
pip uninstall torch torchvision torchaudio
然后再用下面的代码,安装适配的torch版本:
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121
如果你发现模型训练的速度特别慢,很大概率是这个原因。
4.2 主函数:数据加载与预处理
df = pd.read_csv('weibo_senti_100k_cleaned.csv')
df = df.dropna()
dataset = Dataset.from_pandas(df)
dataset = dataset.train_test_split(test_size=0.1) # 9:1 划分训练集和验证集
tokenizer = AutoTokenizer.from_pretrained('bert-base-chinese')
def tokenize(batch):
return tokenizer(batch['review'], padding='max_length', truncation=True, max_length=128)
tokenized_datasets = dataset.map(tokenize, batched=True)
tokenized_datasets = tokenized_datasets.rename_column("label", "labels")
tokenized_datasets.set_format('torch', columns=['input_ids', 'attention_mask', 'labels'])
这里的代码,首先通过pd.read_csv读取了数据集,如果你细心的话,可以看到,我发出来的数据集是“weibo_senti_100k.csv”,但是我读取的数据集是“weibo_senti_100k_cleaned.csv”,这里就要提到数据集的清洗工作,有的数据集是不能直接使用的,比如前一个数据集,它的文本中还有一些url链接,表情符号,@某人等信息,这些无意义的内容统称为“噪声”,在使用之前,我们要将其进行清理,而且这个数据集还有一个很大的问题,就是它的前5万条数据,标签都是1,后5万条数据,标签都是0,这会让模型在学习的时候,前期一直都标1,正确率就很高,后期一直标0,正确率也很高,这两点都会导致训练出来的模型分析效果变差,所以还需要对数据集进行清洗,清洗的工作就是,第一,清除噪声,第二,将他们的次序打乱,随机排序,可以把这个要求发给ai,让它生成一段清洗数据的代码,随后在python中清洗数据。
我进行清洗的代码被覆盖了,在这里附上清洗后的数据集的链接:
通过网盘分享的文件:weibo_senti_100k_cleaned.csv
链接: https://pan.baidu.com/s/1W7HiqwJL-uBs9tLkHALMRg 提取码: a36f
读取了数据集后,下方有一个注释是“9:1划分训练集和验证集”,这里要提到训练模型的逻辑,是需要给他一个训练集和一个验证集,他可以看到训练集的标签,看不到验证集的标签,他会通过学习训练集的标签,然后去给验证集打上标签,再验证是否正确,通过这样的过程,学会进行情感分析,而我们只给了一个数据集,所以就通过这样的方式,将数据集中的90%作为训练集,剩下10%作为验证集。
随后,再通过tokenizer = AutoTokenizer.from_pretrained('bert-base-chinese')导入你的模型,后方的双引号中,是模型的地址,自行修改为自己存放的位置。
4.3 模型定义与训练参数
model = AutoModelForSequenceClassification.from_pretrained('bert-base-chinese', num_labels=2)
CLASS_NAME = {0: "negative", 1: "positive"}
training_args = TrainingArguments(
output_dir='./results',
eval_strategy='epoch',
save_strategy='epoch',
logging_steps=100,
learning_rate=2e-5,
per_device_train_batch_size=32,
per_device_eval_batch_size=32,
num_train_epochs=5,
weight_decay=0.01,
report_to="none",
dataloader_num_workers=0,
dataloader_pin_memory=True,
load_best_model_at_end=True,
metric_for_best_model='eval_loss',
greater_is_better=False,
)
导入数据集和模型后,设置相关参数,随后就可以进行训练了,有兴趣的可以复制上面的参数发给ai,询问每个参数的意义是什么,就我个人而言,只需要知道,读取模型进行了二分类训练“0和1”,然后epoch=5,代表的是将同一个数据集喂给模型5次,可以让模型的学习效果更好,当然不是越多越好,学习次数过多也会出现过拟合的情况,一般3-5次就好。
关键配置解释:
-
eval_strategy='epoch':每个epoch结束时在验证集上评估。 -
load_best_model_at_end=True:训练结束后自动加载验证损失最低的模型,避免过拟合。 -
metric_for_best_model='eval_loss'且greater_is_better=False:以更小的验证损失为最佳模型指标。 -
batch_size 设为32,普通GPU(如RTX 3060 12G)可流畅运行。
在我的代码中,每一个epoch都会对模型进行一次保存,记录下当前的loss率,最终会保存效果最好的版本,保存到“sentiment_model_fixed_best”文件夹内。
4.4 集成SwanLab与启动训练
swanlab_callback = SwanLabCallback(
project='BERT-Chinese-Weibo',
experiment_name='Weibo-Sentiment-v1',
config={'dataset': 'Weibo-100k', "CLASS_NAME": CLASS_NAME}
)
trainer = Trainer(
model=model,
args=training_args,
train_dataset=tokenized_datasets['train'],
eval_dataset=tokenized_datasets['test'],
callbacks=[swanlab_callback],
)
trainer.train()
SwanLab 是一个开源的机器学习实验跟踪和可视化工具,类似于 TensorBoard 或 Weights & Biases。它可以帮助你记录训练过程中的超参数、指标(如 loss, accuracy)以及硬件状态,并生成可视化的仪表盘。
简单的来说,可以截图看效果,用于自己把握训练效果和展示给其他人看,都很不错。
效果如下图所示:

使用的方法:
第一步:SwanLab - AGI时代先进模型训练研发工具进入这个网址,注册账号
第二步:在设置中找到如图所示的api进行复制

第三步:在bash中输入如下代码
swanlab login
随后粘贴上刚才复制的api,提示登录成功即可。
4.5 保存模型与快速测试
python
trainer.save_model('./sentiment_model_fixed_best')
tokenizer.save_pretrained('./sentiment_model_fixed_best')
test_reviews = [
"这部电影太好看了,剧情非常精彩,强烈推荐!",
"简直是浪费时间,剧情老套,演员演技也很尴尬。",
# ... 更多测试评论
]
for review in test_reviews:
predict(review, model, tokenizer, CLASS_NAME)
swanlab.finish()
保存模型后,直接用训练脚本末尾的测试语句验证效果。输出如下:
Input Text: 这部电影太好看了,剧情非常精彩,强烈推荐!
Predicted class: 1 positive
Input Text: 简直是浪费时间,剧情老套,演员演技也很尴尬。
Predicted class: 0 negative
5. 模型推理(批量预测CSV)
训练完成后,我们有了一个 sentiment_model_fixed_best 文件夹,里面包含 config.json、pytorch_model.bin、分词器等文件。下面的 测试.py 脚本可以批量读取CSV文件中的评论,输出情感标签和置信度。
完整代码:
通过网盘分享的文件:训练.py
链接: https://pan.baidu.com/s/1UpqcZW-oeZFpBX9M-QQfSA 提取码: ra2f
5.1 数据清洗
首先,要对微博评论进行情感分析的话,就要先爬取微博的评论,相关内容请看这篇文章
Python爬虫实战:基于Selenium替代方案的微博热搜与评论全量采集-CSDN博客
从微博爬取的原始评论可能包含大量噪声,我们设计 clean_weibo_text 函数:
-
移除URL、话题标签
#...#、@用户 -
仅保留中英文、数字和常用标点
-
合并多余空格
同时,对整表进行过滤:
-
删除内容为“未获取到评论数据”的无效行
-
删除清洗后为空的评论
5.2 加载模型与推理函数
model_path = "./情感分析模型/sentiment_model_fixed_best" # 修改为你的路径
tokenizer = AutoTokenizer.from_pretrained(model_path)
device = "cuda" if torch.cuda.is_available() else "cpu"
model = AutoModelForSequenceClassification.from_pretrained(model_path).to(device)
CLASS_MAPPING = {0: "LABEL_0", 1: "LABEL_1"} # 对应消极和积极
def predict_sentiment(text):
if not text.strip():
return "LABEL_1", 0.0
inputs = tokenizer(text, return_tensors="pt", padding=True, truncation=True, max_length=512).to(device)
with torch.no_grad():
outputs = model(**inputs)
predictions = torch.nn.functional.softmax(outputs.logits, dim=-1)
predicted_class_id = torch.argmax(predictions, dim=-1).item()
score = predictions[0][predicted_class_id].item()
label = CLASS_MAPPING.get(predicted_class_id, "LABEL_1")
return label, score
这里标签名称保留为 LABEL_0 / LABEL_1,你可以在实际使用时修改为“消极/积极”。
5.3 批量处理文件夹内所有CSV
def batch_analyze_csv(folder_path):
for filename in os.listdir(folder_path):
if filename.endswith('.csv'):
df = pd.read_csv(file_path)
df = clean_dataframe(df) # 返回带“纯净评论”列的数据
# 判断是否已有情感标签列,支持增量分析
if '情感标签' in df.columns:
mask = df['情感标签'].isna() | df['置信度'].isna()
for idx in df[mask].index:
label, conf = predict_sentiment(df.loc[idx, '纯净评论'])
df.loc[idx, '情感标签'] = label
df.loc[idx, '置信度'] = conf
else:
results = df['纯净评论'].apply(lambda x: pd.Series(predict_sentiment(x), index=['情感标签', '置信度']))
df['情感标签'] = results['情感标签']
df['置信度'] = results['置信度']
df.to_csv(file_path, index=False, encoding='utf-8-sig')
该段代码的亮点是增量分析:如果 CSV 中已有“情感标签”列,但部分行为空,脚本只会对空缺部分进行推理,避免重复计算浪费资源。
5.4 运行示例
将待分析的 CSV 放在 ./comments_csv 文件夹下,执行脚本:
最终CSV会多出三列:
-
纯净评论:清洗后的文本 -
情感标签:LABEL_0 或 LABEL_1 -
置信度:模型预测的softmax概率
效果如图所示:

6. 结果验证与调优建议
训练5个epoch后,验证集准确率通常能达到94%以上,足以应对一般场景。
进一步优化方向:
-
数据增强:回译、同义词替换等方法增加样本多样性。
-
超参数调整:尝试不同的学习率(1e-5 ~ 5e-5)、批次大小。
-
长文本处理:若评论较长,可将
max_length增加到256或512,并调整batch size。 -
早停机制:加入
EarlyStoppingCallback,当验证损失不再下降时提前停止训练。
如果想换用其他中文BERT变体(如 bert-wwm-ext、RoBERTa-wwm-ext),只需修改 AutoTokenizer 和 AutoModel 中的模型名称即可,代码全兼容。
7. 总结
本文提供了完整的代码框架,实现了:
-
用
bert-base-chinese微调微博情感分类模型 -
集成 SwanLab 进行训练监控
-
训练后模型的保存与加载
-
批量处理 CSV 文件并输出带有情感标签和置信度的结果
整套流程清晰、可复用,你只需准备好带“评论内容”列的CSV,即可一键产出分析结果。希望这篇文章能帮助你快速上手BERT微调与实战部署,只要你愿意花时间跟着步骤去做,都可以运行成功。希望这个教学可以帮到一些正在学习的小白同学,至少可以让你学会“怎么用”,而不是像一只无头苍蝇到处找。
以上的所有内容都是我个人学习得到的成果,可能已经不那么新,有很多地方加入了我的个人理解,不够专业的地方还请多多包涵,如有不对的地方敬请指正,如果有更好的方案,欢迎探讨,谢谢每一个看到这里的人,如果你是小白,恭喜你学到了新的技能,加油。
完整代码:你可以分别下载文中的 训练.py 和 测试.py,按需修改路径后直接运行。如果遇到任何问题,欢迎在评论区交流。
更多推荐
所有评论(0)