文本分类应优先选ComplementNB或MultinomialNB;GaussianNB仅适用于连续正态特征,TF-IDF上使用会导致准确率异常偏低。

sklearn.naive_bayes 用哪个类?别直接选 GaussianNB
多数场景下你真不需要 GaussianNB —— 它只适合特征是连续值且近似正态分布的数据。文本分类、离散标签预测这类更常见的任务,应该优先考虑 ComplementNB 或 MultiNB。
常见错误现象:GaussianNB 在 TF-IDF 向量上训练后准确率反常地低(比如低于 50%),其实是它把稀疏的高维整数计数当成了“服从高斯分布的实数”,数学前提崩了。
-
CountVectorizer+ 文本 → 用ComplementNB(对不平衡类别更鲁棒) -
TfidfVectorizer+ 短文本 →MultiNB更稳,但得先用np.log1p对 tfidf 值做平滑(避免 log(0)) - 纯离散枚举特征(如:颜色=红/蓝/绿)→
CategoricalNB,但注意它不接受字符串,必须提前LabelEncoder编码
fit() 前必须检查 X 的 shape 和 dtype
朴素贝叶斯系列对输入数据类型极其敏感:它不自动转类型,也不会报错提示你“该转了”,而是默默算出错误概率。
典型翻车点:用 pandas.DataFrame 直接传给 fit(),结果内部调用 .values 后 dtype 是 object,某些 NB 实现会当成字符串处理,导致 ValueError: Unknown label type: 'unknown'。
- 确保
X是二维numpy.ndarray或scipy.sparse矩阵,dtype 推荐float32或int32 - 如果从
pd.get_dummies()得到稀疏矩阵,记得用.astype(np.float32)显式转换 - 检查
y是否为一维数组,且不含 NaN ——ComplementNB遇到np.nan会静默跳过样本,不报错但训练集缩水
predict_proba() 返回的不是“置信度”,是条件概率连乘结果
很多人拿 predict_proba() 输出的最大值当模型“把握有多大”,这是误解。朴素贝叶斯的 proba 是基于独立性假设硬算出来的联合概率,数值本身没标度意义,不同类别之间不能比大小,跨模型更不能比。
安全 Python 代码沙箱:在隔离的沙箱中执行任意 Python 代码,预装 requests、NumPy、pandas 库。返回 stdout、stderr。
使用场景:如果你要做阈值截断(比如只返回 proba > 0.8 的预测),那这个阈值必须在验证集上重新校准,不能凭经验设 0.5 或 0.7。
-
predict_proba()结果可能全小于 0.01 —— 正常,因为分母是所有类别的概率和,而朴素假设太强,导致每个类的分子都极小 - 想获得更靠谱的概率估计?加
class_prior参数手动设先验,或用CalibratedClassifierCV包一层(但会拖慢预测速度) - 线上服务中慎用
predict_proba做排序:它对特征缩放极度敏感,StandardScaler一加,结果就全乱
中文文本分类时,停用词和 min_df 不是可选项
不做这两步,ComplementNB 在中文上基本就是扔硬币水平。中文没有空格分词,高频虚词(的、了、在)会严重污染词频统计,而 min_df=1(默认)会让大量仅出现一次的噪声词进入特征空间。
错误现象:训练时 fit() 很快,但 predict() 准确率波动极大,交叉验证方差超过 20%,说明模型学到了随机噪声。
- 停用词必须自定义:jieba 分词后过滤掉《哈工大停用词表》+ 业务无关词(如“用户”“系统”这种泛称)
-
min_df至少设为3,小语料(5;同时配max_features=10000控制维度 - 别用
ngram_range=(1,2)盲加二元词——中文二元词大部分是无意义组合(如“进行操作”“可以使用”),反而稀释关键特征
真正难的不是调参,是让分词器输出的 token 能被 CountVectorizer 正确识别为原子单位。一旦中间环节混入空格、全角字符或未归一化的繁体字,整个概率计算就偏了,而且很难 debug。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










