// learning_article

自然语言处理:文本分类实战指南

从特征工程到深度学习,掌握文本分类的完整流程

开发指南自然语言处理 21分钟2025-03-2013,800 阅读
文本分类NLPBERT实战指南

引言

文本分类是NLP最基础也是应用最广泛的任务之一。从情感分析到新闻分类,从垃圾邮件检测到意图识别,文本分类无处不在。本指南将带您从零开始构建一个完整的文本分类系统。

一、任务定义与数据准备

1.1 明确任务类型

二分类:

  • 情感分析: 正面/负面
  • 垃圾邮件检测: 垃圾/正常
  • 输出: 单个标签

多分类:

  • 新闻分类: 体育/财经/科技等
  • 意图识别: 查询天气/订餐/打车等
  • 输出: 互斥的单个标签

多标签分类:

  • 文章标签: 可以同时属于多个类别
  • 输出: 多个标签

1.2 数据收集

数据来源:

  • 公开数据集: IMDB, AG News, 20 Newsgroups等
  • 业务数据: 用户评论、客服对话等
  • 数据标注: 众包平台(如Amazon MTurk)或内部标注

数据量建议:

  • 传统方法: 每类至少1000条
  • 深度学习: 每类至少5000条
  • 预训练模型微调: 每类可低至100-500条

1.3 数据清洗

  • 去除HTML标签和特殊字符
  • 统一大小写(根据任务决定)
  • 去除或替换URL、邮箱、电话号码
  • 处理缺失值和重复数据
  • 过滤过短或过长的文本

1.4 数据划分

  • 训练集: 70-80%
  • 验证集: 10-15%
  • 测试集: 10-15%
  • 确保各类别分布平衡

二、传统方法

2.1 特征工程

Bag of Words (BoW):

  • 将文本表示为词的集合
  • 统计每个词的出现次数
  • 简单但丢失词序信息

TF-IDF:

  • TF: 词频,词在文档中的频率
  • IDF: 逆文档频率,降低常见词权重
  • TF-IDF = TF × IDF
  • 效果优于BoW

N-gram:

  • 考虑连续N个词的组合
  • Bigram(2-gram): "很好" vs "不好"
  • 保留部分词序信息

2.2 分类算法

朴素贝叶斯:

  • 基于贝叶斯定理
  • 假设特征独立
  • 速度快,效果不错
  • 适合基线模型

支持向量机(SVM):

  • 寻找最优分类超平面
  • 配合TF-IDF效果好
  • 适合中小规模数据

逻辑回归:

  • 线性分类器
  • 可解释性强
  • 训练快速

三、深度学习方法

3.1 词嵌入

Word2Vec:

  • 将词映射到低维稠密向量
  • 语义相似的词向量接近
  • 两种模型: CBOW和Skip-gram

GloVe:

  • 基于词共现矩阵
  • 结合全局统计信息

FastText:

  • 考虑子词(subword)信息
  • 对生僻词和拼写错误更鲁棒

3.2 RNN/LSTM/GRU

架构:

  • 输入: 词嵌入序列
  • RNN/LSTM/GRU处理序列
  • 最后一个时间步的输出用于分类

双向LSTM:

  • 正向和反向LSTM
  • 捕捉双向上下文信息
  • 效果优于单向

3.3 CNN文本分类

TextCNN:

  • 多个不同尺寸的卷积核
  • 提取不同N-gram特征
  • MaxPooling提取关键特征
  • 速度快,效果好

3.4 注意力机制

  • 让模型关注重要的词
  • 提升可解释性
  • 与LSTM结合效果显著

四、预训练模型方法

4.1 BERT微调

步骤:

  • 1. 选择预训练BERT模型
  • 2. 添加分类层(通常是[CLS]的输出)
  • 3. 在任务数据上微调
  • 4. 使用较小学习率(2e-5到5e-5)

优势:

  • 少量数据即可达到好效果
  • 捕捉深层语义信息
  • 当前最佳方案

4.2 模型选择

  • BERT-base: 通用选择,12层
  • BERT-large: 更高精度,24层
  • RoBERTa: BERT改进版
  • ALBERT: 参数更少,速度更快
  • DistilBERT: 蒸馏版,速度快
  • 中文模型: BERT-wwm, RoBERTa-wwm, MacBERT等

4.3 实现示例(PyTorch)

from transformers import BertForSequenceClassification, BertTokenizer
import torch

# 加载模型和tokenizer
model = BertForSequenceClassification.from_pretrained(
    'bert-base-uncased',
    num_labels=2  # 二分类
)
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')

# 处理输入
text = "This movie is fantastic!"
inputs = tokenizer(
    text,
    padding='max_length',
    truncation=True,
    max_length=128,
    return_tensors='pt'
)

# 推理
outputs = model(**inputs)
logits = outputs.logits
prediction = torch.argmax(logits, dim=-1)

五、模型训练与调优

5.1 超参数调优

关键超参数:

  • 学习率:
    • 传统方法: 0.01-0.1
    • 深度学习: 0.001-0.01
    • BERT微调: 2e-5到5e-5
  • Batch Size:
    • 传统方法: 32-128
    • BERT: 16-32(受显存限制)
  • Epochs:
    • 传统方法: 10-100
    • BERT微调: 3-5(容易过拟合)

5.2 处理类别不平衡

  • 过采样: 复制少数类样本
  • 欠采样: 减少多数类样本
  • 类别权重: 给少数类更大的损失权重
  • Focal Loss: 降低易分类样本权重
  • 数据增强: 同义词替换、回译等

5.3 正则化

  • Dropout: 防止过拟合
  • L2正则化: 限制权重大小
  • Early Stopping: 验证集不再提升时停止

六、评估与优化

6.1 评估指标

  • 准确率(Accuracy): 适合类别平衡数据
  • 精确率(Precision): 预测为正的样本中真正的比例
  • 召回率(Recall): 实际为正的样本中被找出的比例
  • F1-Score: 精确率和召回率的调和平均
  • AUC-ROC: 适合二分类,评估整体性能
  • 混淆矩阵: 分析各类别的分类情况

6.2 错误分析

  • 查看分类错误的样本
  • 识别常见错误模式
  • 分析是否需要更多某类数据
  • 考虑引入新特征或规则

6.3 模型融合

  • 投票: 多个模型投票决定
  • 加权平均: 按性能加权
  • Stacking: 训练元模型融合

七、部署上线

7.1 模型优化

  • 模型量化: 减少模型大小
  • 模型蒸馏: BERT蒸馏到小模型
  • 模型剪枝: 移除不重要的参数
  • ONNX导出: 跨平台部署

7.2 服务化

  • 使用Flask/FastAPI构建API
  • 添加缓存机制
  • 批量推理提升吞吐量
  • 监控推理延迟和准确率

7.3 持续优化

  • 收集线上badcase
  • 定期标注补充数据
  • 模型定期重训练
  • A/B测试验证新模型效果

总结

文本分类从传统机器学习到深度学习再到预训练模型,技术不断进步。实践中建议:

  • 从简单方法开始,建立基线
  • 数据量充足时,使用BERT微调
  • 重视数据质量和错误分析
  • 根据业务需求平衡精度和速度