我有一些函数来实现朴素贝叶斯分类器(对于我的数据集),而不使用任何ML库。 我想知道如何在这段代码中解决数值下溢问题。我知道我需要使用log来计算分类器中的概率,但我无法让它工作。当我打印p1和p0时,我当前得到0作为两者的输出。如何更改函数以使用log计算概率p0和p1
# build a naive bayes classifier
def classifyNB0(vec2Classify, p0Vec, p1Vec, pAbusive):
p1 = np.prod(np.power(p1Vec, vec2Classify)) * pAbusive
print('p1 =',p1)
# element-wise power computation
p0 = np.prod(np.power(p0Vec, vec2Classify)) * (1.0 - pAbusive)
print('p0 =',p0)
if p1 > p0:
return 1
else:
return 0
p1Vec中的值:
p1Vec = [0.05263158 0.15789474 0.05263158 0. 0. 0.05263158
0. 0.05263158 0. 0.10526316 0. 0.
0. 0. 0.05263158 0.05263158 0.05263158 0.05263158
0.10526316 0.05263158 0. 0. 0.05263158 0.
0.05263158 0.05263158 0. 0. 0. 0.
0. 0. ]
vec2Classify中的值:
vec2Classify = [0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0]
我认为这实际上是一个数学问题,你的帖子可能更适合Math Exchange
我同意@simon的观点,最好用一些“对数”来解决这个问题,但首先我建议用纸和笔来简化代码:
我对“朴素贝叶斯分类”一无所知,但就我从您的代码中所见,您基本上需要计算不等式
p1 > p0
。让我们做一些数学题显然,我们可以等价地计算
log (p_1) > log (p_0)
。让我们试着重写p1
和p0
的两个表达式在代码中,我们希望您需要迭代列表/向量以获得总和
log_p1 = log(p1) = V[0]*log(U[0]) + ... + V[n]*log(U[n]) + log(pA)
根据您的数值,我希望这些计算不会受到下溢的影响,因此可以进行评估:
log_p1 > log_p0
就python代码而言,总和为
然后评估一下
编辑: 当我查看您在稍后的编辑中添加到文章中的数据时,您的数学变得微不足道。您不需要
power
或log
。你可以一起避免它们。请注意power(x,0) = 1
power(x,1) = x
log(1) = 0
<永远
你可以简单地写
或者,作为一行列表
如果出现下溢,请使用log重试
EDIT2: 您实际上没有下溢问题。我尝试输入您的数据,坦率地说,
p1
的计算结果正确到0.0
。如果你仔细看一下vec2Classify
,你会发现它只在三个不同的索引中保存1
,而p1Vec
在完全相同的索引中保存0
如果
p1Vec
在至少其中一个vec2Classify
是1
的索引处p1Vec
为零,那么整个p1 = prod( ... )
将始终为零,因为您将与power(0,1) = 0
相乘可能您的输入数据(
p1Vec, vec2Classify
)键入错误相关问题 更多 >
编程相关推荐