在Python中规范化小概率

在Python中规范化小概率,python,probability,Python,Probability,我有一个概率列表,需要将其标准化为1.0。 e、 g.probs=[0.01,0.03,0.005] 我意识到这是通过将每个概率除以probs之和来实现的。然而,如果概率变得非常小,Python会告诉我sum(probs)=0.0。我理解这是一个下溢问题。我想我应该用每个概率的对数。我该怎么做呢?即使是非常小的浮点值之和也永远不会真正为0;它们可能接近于零,但不可能完全为零 只需将1除以它们的总和,然后将概率乘以该因子: def normalize(probs): prob_factor

我有一个概率列表,需要将其标准化为1.0。
e、 g.
probs=[0.01,0.03,0.005]


我意识到这是通过将每个概率除以
probs
之和来实现的。然而,如果概率变得非常小,Python会告诉我
sum(probs)=0.0
。我理解这是一个下溢问题。我想我应该用每个概率的对数。我该怎么做呢?

即使是非常小的浮点值之和也永远不会真正为0;它们可能接近于零,但不可能完全为零

只需将1除以它们的总和,然后将概率乘以该因子:

def normalize(probs):
    prob_factor = 1 / sum(probs)
    return [prob_factor * p for p in probs]
当然,有些概率可能只占总数的一个很小的百分比,而且这个百分比可能接近零。但这仅仅意味着,当归一化时,可能会得到非常接近于零的归一化概率,或者如果小于最小的可表示浮点值,则等于零。只有当列表中的概率比其他概率小得多,以至于它们不再代表任何接近将要发生的事情时,后者才会发生

演示:

极端情况是:

>>> import sys
>>> normalize([sys.float_info.max, sys.float_info.min])
[0.9999999999999999, 0.0]
>>> normalize([sys.float_info.max, sys.float_info.min])[-1] == 0
True

您始终可以使用比例因子来避免底流问题,手动输入或自动计算,例如:

import math
no_z = ([x for x in probs if x > 0.0])
if len(no_z) == 0:
   print "Unable to calculate with 0.0 as all the probabilities"
order = int(-math.log10(min(no_z)))
if order > 0:
   order = 0
sf = 10**order
scaled = [x * sf for x in probs]
tot = sum(scaled)
norm = [x/tot for x in scaled]

当然,你最好只使用或numpy,做高精度的数学。

你想让它们在[1-0]之间吗?这就是标准化的意思。我想他想把每个值乘以某个常数,这样
sum(probs)
等于一。你确定这不是打印问题吗?如果数组中的单个元素不完全为零,那么总和应该是机器可表示的,但可能您的打印选项仅将其显示为零。谢谢。我不知道为什么这对我仍然不起作用——这是有道理的。我怀疑零在我的代码中的位置更深。
import math
no_z = ([x for x in probs if x > 0.0])
if len(no_z) == 0:
   print "Unable to calculate with 0.0 as all the probabilities"
order = int(-math.log10(min(no_z)))
if order > 0:
   order = 0
sf = 10**order
scaled = [x * sf for x in probs]
tot = sum(scaled)
norm = [x/tot for x in scaled]