Python实现高斯朴素贝叶斯返回概率数组为[nan]问题求解
朴素贝叶斯连续特征标准差为0触发NaN的修复方案
根因
你遇到的NaN问题来自高斯概率密度计算的除零错误:
P(x|c) = 1/(√(2π) * σ_c) * e^(-(x-μ_c)²/(2σ_c²))
当某类别下的连续特征所有样本取值完全一致时,标准差σ_c=0,公式分母为0,输出结果直接为NaN,导致后续概率比较逻辑失效。
修复方法
方案1:添加标准差平滑项
这是最常用的处理方式,在计算标准差时增加极小的兜底值,避免出现0值,平滑值通常取1e-9,对最终概率结果的影响可以忽略。
示例代码修改:
from math import exp, sqrt, pi def prob_continous_value(x, mean, std): # 给标准差添加最小兜底值,避免除零 safe_std = max(std, 1e-9) exponent = exp(-(x - mean) ** 2 / (2 * safe_std ** 2)) return (1 / (sqrt(2 * pi) * safe_std)) * exponent
方案2:零标准差特殊分支处理
如果明确检测到标准差为0,可以直接根据特征匹配情况返回概率,不需要走高斯公式计算:
- 待预测样本的特征值和该类别下的特征均值(即固定值)相等时,返回概率1.0
- 不相等时返回极小概率
1e-12即可
示例代码修改:
from math import exp, sqrt, pi def prob_continous_value(x, mean, std): if abs(std) < 1e-9: # 该类别下特征取值固定,匹配则概率为1,否则为极小值 return 1.0 if abs(x - mean) < 1e-9 else 1e-12 exponent = exp(-(x - mean) ** 2 / (2 * std ** 2)) return (1 / (sqrt(2 * pi) * std)) * exponent
方案3:预处理阶段过滤无效特征
如果数据集存在大量方差为0的特征,这类特征对分类没有区分度,可以在数据预处理阶段直接删除,从根源避免问题出现。
分类结果提取
修复概率计算逻辑后,你得到的概率数组将不再包含NaN值,直接调用numpy.argmax即可提取最大值对应的分类:
import numpy as np # prob_array为每个类别的概率计算结果数组 predicted_class = np.argmax(prob_array)
内容的提问来源于stack exchange,提问作者Evan Gertis
相关产品推荐
相关产品推荐

