本文目录导读:
文本分类是自然语言处理(NLP)中一项基础且核心的任务,目标是为给定的文本(如句子、段落、文档)分配一个或多个预定义的类别标签(判断邮件是“垃圾邮件”还是“正常邮件”;判断新闻属于“体育”、“科技”还是“娱乐”)。
实现文本分类主要有传统机器学习方法和深度学习方法两条路径,以下是完整的实现流程和关键步骤。
核心流程(通用步骤)
无论采用哪种方法,文本分类的基本流程通常包括:
- 问题定义 & 数据收集:明确分类目标(二分类、多分类、多标签分类),收集带有标签的文本数据集。
- 数据预处理:清洗数据,将原始文本转换为模型可理解的格式。
- 特征工程/文本表示:将文本“向量化”,即转换为数字向量。
- 模型训练:选择算法并用预处理后的数据训练模型。
- 模型评估:使用准确率、精确率、召回率、F1分数等指标衡量模型性能。
- 模型部署与预测:将训练好的模型用于新文本的分类。
主流实现方法一:传统机器学习方法
适用于数据量较小、对资源要求低或需要高解释性的场景。
数据预处理
- 分词:将句子切分成词语,中文常用
jieba,英文直接用空格/标点分割。 - 去停用词:移除“的”、“是”、“了”等无意义的词。
- 词干提取/词形还原(英文):将 “running” -> “run”,减少词形变化。
文本表示(特征提取)
- 词袋模型:统计每个词在文档中出现的次数,缺点:忽略词序。
- TF-IDF:不仅看词频,还看词的稀缺性(重要程度),的”出现很多但不重要,“核聚变”出现少但区分度高。这是传统方法里最常用的特征。
TF-IDF = 词频(TF) × 逆文档频率(IDF)
- N-gram:将连续的N个词作为特征,非常/好” vs “非/常好”,能捕获部分上下文。
模型选择
- 朴素贝叶斯:简单、快速,非常适合文本分类(尤其是垃圾邮件过滤),假设特征之间相互独立。
- 支持向量机:在小样本、高维特征空间(如TF-IDF矩阵)上表现优异。
- 逻辑回归:可解释性强,能输出概率。
- 随机森林/XGBoost:集成学习方法,效果通常优于单模型。
传统方法优缺点:
- 优点:训练快,可解释性好,小数据集效果好。
- 缺点:无法处理词序和复杂语义(“我喜欢你” vs “你我喜欢” 被当成一样),特征工程繁琐。
主流实现方法二:深度学习方法
适用于大数据量、需要捕获上下文语义的场景(如情感分析、复杂主题分类)。目前工业界和学术界的主流。
数据预处理
- 分词(同上)。
- 构建词汇表:给每个词分配一个独一无二的数字ID。
- 序列化与填充:将文本转换为固定长度的数字序列。
文本表示——词嵌入
- 静态词嵌入:预训练好的词向量(如Word2Vec、GloVe、FastText),每个词被映射为一个固定维度的稠密向量(如300维),优点:向量能捕捉词的相似性(“国王” - “男人” + “女人” ≈ “女王”)。
- 动态词嵌入:BERT、GPT等预训练语言模型,根据上下文动态生成词向量(即“苹果”在“吃苹果”和“苹果公司”中向量不同)。这是目前表现最好的方法。
模型架构
- TextCNN:使用一维卷积核捕捉局部N-gram特征,速度快,效果好,适合短文本。
- RNN/LSTM/GRU:按顺序处理文本,能有效捕捉长距离依赖,但训练速度慢,可能有梯度消失问题,LSTM是改进版。
- 注意力机制:让模型关注句子中更重要的词,Transformer 架构完全基于自注意力。
- Transformer / BERT 微调:使用预训练的BERT模型,在其基础上加一个简单的分类层,用你的标注数据进行微调。这是当前最流行、效果最好的方法。
深度学习方法优缺点:
- 优点:自动特征提取,语义理解强(“差”不一定代表负面,如“味道差不了”),泛化能力强,效果上限高。
- 缺点:需要大量训练数据(通常需数万条以上),计算资源要求高(GPU),模型可解释性差(黑盒)。
关键细节对比表
| 维度 | 传统机器学习 | 深度学习 |
|---|---|---|
| 数据处理 | 需要精细的停用词、分词、特征抽取 | 通常只需分词和编码,依赖模型自动学习 |
| 特征质量 | 依赖人工特征(TF-IDF),稀疏 | 词嵌入向量,稠密且富含语义 |
| 所需数据量 | 几百到几千条即可 | 通常需要万级以上(否则容易过拟合) |
| 计算资源 | CPU即可,速度快 | 需要GPU,训练耗时 |
| 效果上限 | 中等,受限于特征 | 很高,目前SOTA(State-of-the-art) |
| 可解释性 | 较好(能看到哪些词权重高) | 较差(“黑盒”) |
快速实践入门(以Python为例)
传统方法(TF-IDF + 逻辑回归)
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
import jieba
# 假设你有数据和标签
texts = ["这部电影太棒了", "这服务差劲的要命"]
labels = [1, 0]
# 1. 对中文进行分词预处理
def chinese_word_cut(text):
return " ".join(jieba.cut(text))
texts_cut = [chinese_word_cut(t) for t in texts]
# 2. 向量化
vectorizer = TfidfVectorizer()
X = vectorizer.fit_transform(texts_cut)
# 3. 划分训练测试集
X_train, X_test, y_train, y_test = train_test_split(X, labels, test_size=0.2)
# 4. 训练逻辑回归模型
model = LogisticRegression()
model.fit(X_train, y_train)
# 5. 评估 & 预测
print(model.score(X_test, y_test))
new_text = ["这剧情太无聊了"]
new_vec = vectorizer.transform([chinese_word_cut(new_text)])
print(model.predict(new_vec))
深度学习方法(使用预训练BERT)
# 使用 Hugging Face 的 transformers 库(需安装:pip install transformers torch) from transformers import AutoTokenizer, AutoModelForSequenceClassification, Trainer, TrainingArguments import torch # 1. 加载预训练模型和分词器(这里用中文BERT) model_name = "bert-base-chinese" tokenizer = AutoTokenizer.from_pretrained(model_name) model = AutoModelForSequenceClassification.from_pretrained(model_name, num_labels=2) # 二分类 # 2. 文本处理 texts = ["这部电影太棒了", "这服务差劲的要命"] labels = [1, 0] # 编码:将文本转换为input_ids, attention_mask等 encodings = tokenizer(texts, truncation=True, padding=True, return_tensors="pt") labels = torch.tensor(labels) # 3. 定义数据集类(省略细节,标准PyTorch Dataset) # 4. 定义训练参数并训练(可用Trainer API简化) training_args = TrainingArguments(output_dir="./results", num_train_epochs=3) trainer = Trainer(model=model, args=training_args, train_dataset=dataset) trainer.train() # 5. 新文本预测 new_text = ["这剧情刷新了我的三观"] inputs = tokenizer(new_text, return_tensors="pt") outputs = model(**inputs) probs = torch.softmax(outputs.logits, dim=-1) predicted_class = torch.argmax(probs, dim=-1) print(predicted_class)
总结建议
- 新手入门/小项目:从TF-IDF + 逻辑回归或朴素贝叶斯开始,代码简单,效果可达80%+。
- 追求最佳效果/大项目:直接使用BERT或RoBERTa等预训练模型微调,虽然有门槛,但在大部分文本任务中效果远超传统方法。
- 资源有限/实时性高:考虑TextCNN + Word2Vec,在速度和效果之间取得平衡。
- 中文处理注意:分词工具用
jieba,预训练模型用bert-base-chinese、chinese-roberta-wwm-ext等。