NLP学习笔记03:文本分类——从 TF-IDF 到 BERT

NLP学习笔记03:文本分类------从 TF-IDF 到 BERT

作者:Ye Shun

日期:2026-04-15

一、前言

文本分类(Text Classification)是自然语言处理(NLP)中最基础、也最常见的任务之一。它的目标,是将一段给定文本自动归类到一个或多个预定义类别中。

如果把它类比成现实中的场景,就像图书管理员需要根据书的内容把书放到不同书架上;在计算机中,我们则希望模型能够"读懂"文本,并自动判断它属于哪个类别。

虽然文本分类听起来简单,但它几乎覆盖了 NLP 中最核心的一条主线:从文本预处理、特征提取,到模型训练、效果评估,再到模型优化,很多经典方法都可以在这个任务里找到落点。

这篇笔记会围绕下面几个问题展开:

  1. 文本分类到底在解决什么问题
  2. 一个完整的文本分类系统通常包含哪些步骤
  3. 如何用 Python 实现一个简单可运行的文本分类示例
  4. 文本分类实践中常见的挑战有哪些

二、什么是文本分类

文本分类的本质,是一个监督学习任务。我们需要准备一批已经标注好类别的文本作为训练数据,让模型学习"文本特征"和"类别标签"之间的对应关系。训练完成后,模型就可以对新的未标注文本进行预测。

比如:

  • "这家餐厅太好吃了,下次还来" → 正面情感
  • "恭喜您中奖,请点击链接领取奖金" → 垃圾信息
  • "苹果发布了最新款芯片" → 科技新闻

从这个角度看,文本分类做的事情其实就是:给文本贴标签。

常见应用场景

文本分类在实际业务中非常常见,例如:

  • 情感分析:判断评论是正面、负面还是中性
  • 垃圾邮件过滤:区分正常邮件和垃圾邮件
  • 新闻分类:将新闻归类到体育、财经、科技等栏目
  • 意图识别:识别用户输入是"咨询""投诉"还是"购买"
  • 医疗辅助分析:根据症状描述预测疾病类型
  • 法律文书分类:自动识别案件类别或文书类型

可以说,只要"文本最终要被归类",背后大概率就是文本分类问题。

三、文本分类的基本流程

一个完整的文本分类系统,通常包含以下几个环节:

  1. 文本预处理
  2. 特征提取或文本表示
  3. 模型选择与训练
  4. 测试集预测与效果评估
  5. 误差分析与优化

这几个步骤看起来简单,但每一步都会直接影响最终效果。

1. 文本预处理

原始文本通常不能直接拿来训练模型,需要先做基础清洗,例如:

  • 小写化
  • 去除特殊字符和数字
  • 分词
  • 去除停用词
  • 词干提取或词形还原

下面是一个典型的英文预处理示例:

python 复制代码
import re
from nltk.corpus import stopwords
from nltk.stem import PorterStemmer


def preprocess_text(text):
    text = text.lower()
    text = re.sub(r"[^a-zA-Z\s]", "", text)
    words = text.split()

    stop_words = set(stopwords.words("english"))
    words = [word for word in words if word not in stop_words]

    stemmer = PorterStemmer()
    words = [stemmer.stem(word) for word in words]

    return " ".join(words)

不过在真正写实验代码时,要注意 nltk 的停用词资源往往需要额外下载。如果只是做一个纯本地、可快速运行的版本,也可以先用 scikit-learn 内置停用词,减少环境依赖。

2. 特征提取

文本不能直接送入传统机器学习模型,需要先转成数值特征。常见做法包括:

方法 描述 优点 缺点
词袋模型(BoW) 统计词频 简单直观 忽略词序和语义
TF-IDF 加入词重要性权重 比 BoW 更实用 仍缺少上下文
Word2Vec 稠密词向量 能表示语义相似性 无法区分多义词
BERT 上下文嵌入 表示能力强 计算成本高

在入门阶段,最常见也最稳妥的路线,通常是:

TF-IDF + 传统分类器

这套组合简单、高效、容易解释,也很适合作为基线模型。

3. 分类模型选择

在特征表示确定以后,就要选择分类器。常见方法大致分为两类:

传统机器学习方法
  • 朴素贝叶斯
  • 支持向量机(SVM)
  • 逻辑回归
  • 随机森林
深度学习方法
  • CNN
  • RNN / LSTM
  • Transformer / BERT

对于刚入门文本分类的人来说,建议先把 TF-IDF + 逻辑回归TF-IDF + SVM 跑通。因为它们不仅实现简单,而且在很多中小规模任务上效果并不差。

四、实践示例:新闻分类

下面用一个经典思路来演示文本分类任务。原始材料中提到的是 20 Newsgroups 数据集,它确实是很经典的新闻分类数据集。不过由于在线下载数据集有时会受环境影响,本文会分两种思路理解:

  1. 标准做法:使用 20 Newsgroups
  2. 稳定演示版:使用本地构造的小样本数据

1. 标准做法:20 Newsgroups

如果环境允许联网和下载数据,可以这样加载数据集:

python 复制代码
from sklearn.datasets import fetch_20newsgroups

categories = [
    "alt.atheism",
    "soc.religion.christian",
    "comp.graphics",
    "sci.med"
]

newsgroups_train = fetch_20newsgroups(subset="train", categories=categories)
newsgroups_test = fetch_20newsgroups(subset="test", categories=categories)

print(f"训练集样本数: {len(newsgroups_train.data)}")
print(f"测试集样本数: {len(newsgroups_test.data)}")

之后使用 TF-IDF 进行特征提取:

python 复制代码
from sklearn.feature_extraction.text import TfidfVectorizer

vectorizer = TfidfVectorizer(max_features=5000)
X_train = vectorizer.fit_transform(newsgroups_train.data)
X_test = vectorizer.transform(newsgroups_test.data)

y_train = newsgroups_train.target
y_test = newsgroups_test.target

再用逻辑回归进行训练和评估:

python 复制代码
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, classification_report

model = LogisticRegression(max_iter=1000)
model.fit(X_train, y_train)

y_pred = model.predict(X_test)

print(f"准确率: {accuracy_score(y_test, y_pred):.2f}")
print(classification_report(y_test, y_pred, target_names=newsgroups_test.target_names))

这是一个非常经典的文本分类入门流程。

2. 稳定演示版:本地小样本分类

如果只是想先验证流程,而不依赖外部数据集,可以自己构造一个小型语料做实验。比如把文本分成四类:

  • 计算机图形
  • 医学
  • 宗教
  • 无神论

先准备文本和标签,再使用 TfidfVectorizer 进行向量化,最后训练逻辑回归模型。这样做虽然数据量小,但足以帮助我们理解完整分类流程。

相比直接跑大型数据集,这种方式有两个明显优点:

  • 不依赖网络下载
  • 更容易观察每一步在做什么

五、模型评估:如何判断分类器好不好

文本分类并不是只看预测结果对不对,更重要的是通过评估指标全面理解模型表现。

1. 准确率(Accuracy)

准确率是最直观的指标:

text 复制代码
准确率 = 预测正确的样本数 / 总样本数

它适合类别分布相对均衡的情况。

2. Precision、Recall 和 F1-score

在很多真实任务中,仅看准确率是不够的。比如垃圾邮件检测中,误把正常邮件当垃圾邮件,代价可能很大;医疗场景中,漏判阳性样本代价也很高。

因此,通常还要关注:

  • Precision(精确率):预测为某类的样本中,有多少是真的
  • Recall(召回率):真实属于某类的样本中,有多少被找出来了
  • F1-score:精确率和召回率的综合平衡

classification_report 就会输出这些指标。

3. 混淆矩阵

混淆矩阵可以帮助我们分析:

  • 哪些类别最容易混淆
  • 错误主要集中在哪些方向
  • 模型是否偏向某些大类

很多时候,提升模型效果的关键不是盲目换模型,而是先看清楚模型"错在哪里"。

六、进阶技巧与常见挑战

文本分类在真实项目中并不总是像教学示例那样顺利,常见挑战很多。

1. 类别不平衡

如果某些类别样本远多于其他类别,模型可能会偏向大类。常见解决方法包括:

  • 过采样少数类
  • 欠采样多数类
  • 使用类别权重
  • 用 F1-score 代替单纯准确率

2. 特征工程优化

可以尝试从特征侧提升效果,例如:

  • 调整 n-gram 范围
  • 增减最大特征数
  • 使用词性特征
  • 引入词向量或上下文表示

3. 模型优化

常见思路包括:

  • 网格搜索或随机搜索超参数
  • 模型集成
  • 从逻辑回归切换到 SVM、朴素贝叶斯或深度学习模型

4. 数据增强

当标注数据不足时,可以尝试:

  • 同义词替换
  • 回译(Back Translation)
  • 规则改写

5. 真实业务中的更复杂任务

文本分类还会遇到一些更复杂的变体:

  • 多标签分类:一条文本可能属于多个类别
  • 领域迁移:训练集和测试集来自不同领域
  • 小样本学习:标注数据很少
  • 可解释性要求高:需要说明模型为什么这样判

所以,文本分类看似基础,实际上能一路延伸到非常深入的研究与工程问题。

七、从传统方法到深度学习

如果把文本分类方法做一个大致分层,可以理解为:

1. 传统方法

典型组合:

  • TF-IDF + 朴素贝叶斯
  • TF-IDF + SVM
  • TF-IDF + 逻辑回归

优点是:

  • 简单
  • 稳定
  • 易于解释
  • 适合小中型数据

2. 词向量方法

例如:

  • Word2Vec + 平均池化 + 分类器
  • FastText

优点是:

  • 比稀疏特征更有语义信息
  • 向量维度更低

但也存在静态表示的局限。

3. 深度学习方法

例如:

  • CNN 文本分类
  • LSTM 文本分类
  • BERT 微调分类

优点是:

  • 表示能力更强
  • 能利用上下文
  • 在复杂任务上通常效果更好

缺点是:

  • 计算成本更高
  • 训练和调参更复杂

因此,实际项目中并不是"越新越好",而是要结合数据规模、资源条件和效果要求来选。

八、学习建议

如果想系统学习文本分类,我比较推荐按下面的顺序来:

  1. 先跑通 TF-IDF + 逻辑回归TF-IDF + SVM
  2. 理解词袋模型、TF-IDF、N-gram 等基础表示
  3. 学习词向量和句向量
  4. 进一步接触 CNN、LSTM 等神经网络分类模型
  5. 最后再深入 BERT、RoBERTa 等预训练语言模型

这样学的好处是,能先把"文本分类的本质"看清楚,而不是一开始就只会调用高级模型接口。

九、总结

文本分类是 NLP 中最经典的任务之一,也是很多更复杂任务的基础。通过文本分类,我们可以把一整套 NLP 流程串起来:预处理、特征提取、建模、评估和优化。

从方法上看:

  • 传统方法简单高效,是很好的入门路线
  • 词向量方法让模型开始具备语义表达能力
  • 深度学习和预训练模型进一步提升了上下文理解能力

在实践中,建议先从稳定、简单、可解释的方案开始,再逐步过渡到更复杂的模型。真正重要的,不只是把代码跑出来,而是理解每一步为什么这样做。

相关推荐
Fanfanaas2 小时前
Linux 系统编程 进程篇 (二)
linux·运维·服务器·c语言·开发语言·学习
克里斯蒂亚诺·罗纳尔达2 小时前
智能体学习22——智能体间通信(A2A)
人工智能·学习·ai
码匠许师傅2 小时前
【STM32开发笔记】基于STM32CubeMX2 和STM32CubeIDE for VSCode的全新STM32C5开发体验
笔记·vscode·stm32
Hammer_Hans2 小时前
DFT笔记41
笔记
炽烈小老头2 小时前
【每天学习一点算法 2026/04/15】两整数之和(附带位运算总结)
学习·算法
风兮雨露2 小时前
2026年全国硕士研究生招生考试(附资源)
学习
05Nuyoah2 小时前
第一阶段:HTML的笔记
前端·笔记·html
Xpower 172 小时前
PHM算法学习 Day 3:深度卷积神经网络(CNN)故障诊断变体
学习·算法·cnn
im_AMBER2 小时前
学习 Redux Toolkit :从 Context 误区到 createSlice 实践
前端·javascript·学习·react.js·前端框架