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]
原因分析
核心差异来自两个模型的设计目标和概率计算逻辑:
适用场景完全不同
- GaussianNB是专门为连续数值特征设计的,它会为每个类别拟合对应的高斯分布(均值+方差),然后通过计算样本属于每个类的高斯概率来做预测。在这个案例里,两个类的特征分布完全不重叠,GaussianNB自然能100%区分。
- ComplementNB则是为稀疏非负计数特征(比如文本分类里的词频、TF-IDF值)设计的,针对不平衡分类任务优化,它的核心逻辑是计算样本“不属于某类”的概率,再转换为属于该类的概率,本质是多项式朴素贝叶斯的补集变种。
概率计算逻辑导致的偏向
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。
平滑参数的影响
ComplementNB默认的平滑参数alpha=1.0会进一步拉平概率估计,加剧这种偏向,让所有样本的预测结果都倒向类别0。
简单来说,你用了一个专为文本计数特征设计的模型去处理连续数值特征,自然会出现不符合预期的结果。
内容的提问来源于stack exchange,提问作者HOSS_JFL
相关产品推荐
相关产品推荐

