SMOTE不能直接处理原始文本,必须先用TfidfVectorizer等向量化为数值矩阵;其默认欧氏距离在高维稀疏文本上不稳定,宜调小n_neighbors;语义增强应优先用nlpaug而非生成模型,避免标签失真。

用 imblearn.over_sampling.SMOTE 处理文本分类前的向量化陷阱
SMOTE 不能直接对原始文本(如 ["好评", "差评", "差评"])做上采样——它只接受数值型特征矩阵。常见错误是直接把 SMOTE().fit_resample(X_text, y) 传入列表或字符串,结果报错 ValueError: Expected 2D array, got 1D array instead。
必须先完成文本向量化(如用 TfidfVectorizer 或 CountVectorizer),再对得到的稀疏矩阵 X_tfidf 和标签 y 调用 SMOTE:
from sklearn.feature_extraction.text import TfidfVectorizer from imblearn.over_sampling import SMOTE <p>vectorizer = TfidfVectorizer(max_features=5000, stop_words='english') X_vec = vectorizer.fit_transform(texts) # shape: (n_samples, 5000) smote = SMOTE(random_state=42) X_res, y_res = smote.fit_resample(X_vec, y) # ✅ 正确:输入是稀疏矩阵 + 标签</p>
- 注意
SMOTE默认使用欧氏距离,在高维稀疏文本向量上可能不稳定;可改用SMOTE(k_neighbors=3)减小邻域半径 - 若
X_vec是scipy.sparse矩阵,SMOTE会自动保持稀疏性;但某些旧版本 imblearn 可能强制转为稠密,导致内存爆炸 - 切勿在向量化前做 SMOTE——没有“合成新句子”的语义逻辑,那只是伪造 ID
用 nlpaug 对少数类文本做语义级增强
当类别极不均衡(如 99% 正样本、1% 负样本),单纯过采样向量容易过拟合;此时应在原始文本层面做同义词替换、随机插入等操作,保留语言结构。
nlpaug 是最轻量且可控的选择,不依赖大模型,适合快速实验:
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
import nlpaug.augmenter.word as naw <h1>针对少数类文本(例如 y==1 的所有样本)</h1><p>minority_texts = [texts[i] for i in range(len(y)) if y[i] == 1] aug = naw.SynonymAug(aug_src='wordnet', aug_min=1, aug_max=3) augmented_texts = [aug.augment(t) for t in minority_texts]</p>
-
aug_src='wordnet'稳定、无需联网;'bert'效果好但慢且需 GPU,容易引入噪声 -
aug_min/aug_max控制每句替换词数,避免过度失真(比如把“质量差”变成“品质卓越”就翻车了) - 增强后务必人工抽检 3–5 条,检查是否改变原始情感极性或事实——
nlpaug不懂业务语义
为什么不用 transformers + pipeline 做文本增强?
有人尝试用 AutoModelForSeq2SeqLM 生成新样本,比如用 T5 把“这个手机很卡”重写为“这款设备运行缓慢”。这看似高级,实际问题很多:
- 生成文本与原标签不一致:模型可能把负面样本重写成中性甚至正面,破坏监督信号
- 推理慢、显存占用高,1000 条文本增强耗时分钟级,无法嵌入训练 pipeline
- 缺乏控制粒度:你无法指定“只替换形容词”或“保持否定词不变”,而
nlpaug支持action='substitute'+target_words=['差','烂','卡'] - 如果真要用生成式方法,建议仅用于离线构造增强集,并用规则过滤(如情感分析模型打分验证)
RandomOverSampler 和 SMOTE 在文本任务中的关键区别
两者都用于上采样,但在文本场景下行为完全不同:
-
RandomOverSampler:简单复制少数类样本的向量行,相当于重复已有文档——不会提升泛化能力,还可能放大标注噪声 -
SMOTE:在 TF-IDF 特征空间中对相邻样本做线性插值,生成新向量(比如取两篇“差评”的 TF-IDF 向量平均),隐含假设是“相似词分布 → 相似语义” - 实测中,
SMOTE在短文本(RandomOverSampler;但长评论中因稀疏性高,插值得到的向量可能对应无意义词组合 - 更稳妥的做法是:先用
nlpaug增强原始文本,再用RandomOverSampler补足数量缺口——语义真实性和数量保障兼顾
真正难的不是选哪个工具,而是判断哪类样本值得增强:用户反馈中的“功能缺陷”类差评和“物流延迟”类差评,语义分布差异很大,混在一起用 SMOTE 插值,大概率造出“功能延迟”这种假概念。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










