NLP学习笔记03:文本分类——从 TF-IDF 到 BERT
NLP学习笔记03:文本分类——从 TF-IDF 到 BERT
作者:Ye Shun
日期:2026-04-15
一、前言
文本分类(Text Classification)是自然语言处理(NLP)中最基础、也最常见的任务之一。它的目标,是将一段给定文本自动归类到一个或多个预定义类别中。
如果把它类比成现实中的场景,就像图书管理员需要根据书的内容把书放到不同书架上;在计算机中,我们则希望模型能够“读懂”文本,并自动判断它属于哪个类别。
虽然文本分类听起来简单,但它几乎覆盖了 NLP 中最核心的一条主线:从文本预处理、特征提取,到模型训练、效果评估,再到模型优化,很多经典方法都可以在这个任务里找到落点。
这篇笔记会围绕下面几个问题展开:
- 文本分类到底在解决什么问题
- 一个完整的文本分类系统通常包含哪些步骤
- 如何用 Python 实现一个简单可运行的文本分类示例
- 文本分类实践中常见的挑战有哪些
二、什么是文本分类
文本分类的本质,是一个监督学习任务。我们需要准备一批已经标注好类别的文本作为训练数据,让模型学习“文本特征”和“类别标签”之间的对应关系。训练完成后,模型就可以对新的未标注文本进行预测。
比如:
- “这家餐厅太好吃了,下次还来” → 正面情感
- “恭喜您中奖,请点击链接领取奖金” → 垃圾信息
- “苹果发布了最新款芯片” → 科技新闻
从这个角度看,文本分类做的事情其实就是:给文本贴标签。
常见应用场景
文本分类在实际业务中非常常见,例如:
- 情感分析:判断评论是正面、负面还是中性
- 垃圾邮件过滤:区分正常邮件和垃圾邮件
- 新闻分类:将新闻归类到体育、财经、科技等栏目
- 意图识别:识别用户输入是“咨询”“投诉”还是“购买”
- 医疗辅助分析:根据症状描述预测疾病类型
- 法律文书分类:自动识别案件类别或文书类型
可以说,只要“文本最终要被归类”,背后大概率就是文本分类问题。
三、文本分类的基本流程
一个完整的文本分类系统,通常包含以下几个环节:
- 文本预处理
- 特征提取或文本表示
- 模型选择与训练
- 测试集预测与效果评估
- 误差分析与优化
这几个步骤看起来简单,但每一步都会直接影响最终效果。
1. 文本预处理
原始文本通常不能直接拿来训练模型,需要先做基础清洗,例如:
- 小写化
- 去除特殊字符和数字
- 分词
- 去除停用词
- 词干提取或词形还原
下面是一个典型的英文预处理示例:
importrefromnltk.corpusimportstopwordsfromnltk.stemimportPorterStemmerdefpreprocess_text(text):text=text.lower()text=re.sub(r"[^a-zA-Z\s]","",text)words=text.split()stop_words=set(stopwords.words("english"))words=[wordforwordinwordsifwordnotinstop_words]stemmer=PorterStemmer()words=[stemmer.stem(word)forwordinwords]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数据集,它确实是很经典的新闻分类数据集。不过由于在线下载数据集有时会受环境影响,本文会分两种思路理解:
- 标准做法:使用
20 Newsgroups - 稳定演示版:使用本地构造的小样本数据
1. 标准做法:20 Newsgroups
如果环境允许联网和下载数据,可以这样加载数据集:
fromsklearn.datasetsimportfetch_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 进行特征提取:
fromsklearn.feature_extraction.textimportTfidfVectorizer 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再用逻辑回归进行训练和评估:
fromsklearn.linear_modelimportLogisticRegressionfromsklearn.metricsimportaccuracy_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)
准确率是最直观的指标:
准确率 = 预测正确的样本数 / 总样本数它适合类别分布相对均衡的情况。
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 微调分类
优点是:
- 表示能力更强
- 能利用上下文
- 在复杂任务上通常效果更好
缺点是:
- 计算成本更高
- 训练和调参更复杂
因此,实际项目中并不是“越新越好”,而是要结合数据规模、资源条件和效果要求来选。
八、学习建议
如果想系统学习文本分类,我比较推荐按下面的顺序来:
- 先跑通
TF-IDF + 逻辑回归或TF-IDF + SVM - 理解词袋模型、TF-IDF、N-gram 等基础表示
- 学习词向量和句向量
- 进一步接触 CNN、LSTM 等神经网络分类模型
- 最后再深入 BERT、RoBERTa 等预训练语言模型
这样学的好处是,能先把“文本分类的本质”看清楚,而不是一开始就只会调用高级模型接口。
九、总结
文本分类是 NLP 中最经典的任务之一,也是很多更复杂任务的基础。通过文本分类,我们可以把一整套 NLP 流程串起来:预处理、特征提取、建模、评估和优化。
从方法上看:
- 传统方法简单高效,是很好的入门路线
- 词向量方法让模型开始具备语义表达能力
- 深度学习和预训练模型进一步提升了上下文理解能力
在实践中,建议先从稳定、简单、可解释的方案开始,再逐步过渡到更复杂的模型。真正重要的,不只是把代码跑出来,而是理解每一步为什么这样做。
