You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

sklearn ComplementNB在完全可分数据中仅预测类别0的原因探究

问题:为何ComplementNB对可完全区分的数据全预测为类别0?

一组平衡的一维数据可被sklearn的GaussianNB完全区分,但用同一数据训练ComplementNB后,它对所有样本的预测结果均为类别0。

测试代码如下:

from sklearn.naive_bayes import GaussianNB
from sklearn.naive_bayes import ComplementNB
import numpy as np

N = 20
np.random.seed(9)
pos = np.random.uniform(size = N, low = 0.7, high = 0.8).reshape(-1, 1)
neg = np.random.uniform(size = N, low = 0.4, high = 0.5).reshape(-1, 1)
X = np.r_[pos, neg]
Y = np.array([1] * N + [0] * N)

gnb = GaussianNB()
cnb = ComplementNB()
gnb.fit(X,Y)
cnb.fit(X,Y)
# 预测训练数据
print(gnb.predict(X))   
print(cnb.predict(X))

GaussianNB分类准确率100%,输出:

[1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]

ComplementNB的输出全为0:

[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] 

原因分析

核心差异来自两个模型的设计目标和概率计算逻辑:

  1. 适用场景完全不同

    • GaussianNB是专门为连续数值特征设计的,它会为每个类别拟合对应的高斯分布(均值+方差),然后通过计算样本属于每个类的高斯概率来做预测。在这个案例里,两个类的特征分布完全不重叠,GaussianNB自然能100%区分。
    • ComplementNB则是为稀疏非负计数特征(比如文本分类里的词频、TF-IDF值)设计的,针对不平衡分类任务优化,它的核心逻辑是计算样本“不属于某类”的概率,再转换为属于该类的概率,本质是多项式朴素贝叶斯的补集变种。
  2. 概率计算逻辑导致的偏向
    ComplementNB的概率公式大致为:$P(y|x) \propto P(y) \prod_{i} P(x_i | \overline{y})$,其中$\overline{y}$是类别$y$的补集(也就是所有非$y$的样本)。
    在这个案例中:

    • 类别1的补集是类别0,特征均值约0.45;类别0的补集是类别1,特征均值约0.75。
    • 对于类别1的样本(特征值0.7~0.8),计算它属于类别1的概率时,会用补集(类别0)的特征均值来估计$P(x_i | \overline{y=1})$。由于样本特征值远大于补集均值,在多项式分布的假设下,这个概率会非常小,最终导致$P(y=1|x)$远低于$P(y=0|x)$。
    • 对于类别0的样本(特征值0.4~0.5),计算它属于类别0的概率时,用补集(类别1)的特征均值0.75来估计,样本特征值远小于补集均值,对应的概率反而更高,因此也会被预测为0。
  3. 平滑参数的影响
    ComplementNB默认的平滑参数alpha=1.0会进一步拉平概率估计,加剧这种偏向,让所有样本的预测结果都倒向类别0。

简单来说,你用了一个专为文本计数特征设计的模型去处理连续数值特征,自然会出现不符合预期的结果。

内容的提问来源于stack exchange,提问作者HOSS_JFL

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 06:22:39