在Python中规范化小概率

Ada*_*m_G 3 python probability

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

我意识到这是通过将每个概率除以总和来完成的probs.但是,如果概率变得非常小,Python就会告诉我sum(probs)=0.0.我知道这是一个下溢问题.我想我应该使用每个概率的日志.我该怎么做?

Mar*_*ers 7

甚至非常小的浮点值之和永远不会真正为0; 它们可能接近零,但永远不会完全为零.

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

def normalize(probs):
    prob_factor = 1 / sum(probs)
    return [prob_factor * p for p in probs]
Run Code Online (Sandbox Code Playgroud)

当然,一些概率可能只占总和的一小部分,而且该百分比可能接近于零.但这只是意味着在归一化时,最终可能会得到非常接近零的归一化概率,或者如果小于最小可表示浮点值,则等于零.后者只有在列表中的概率比其他概率小得多的情况下才会发生,以至于它们不再代表任何可能发生的事物.

演示:

>>> def normalize(probs):
...     prob_factor = 1 / sum(probs)
...     return [prob_factor * p for p in probs]
... 
>>> normalize([0.0000000001,0.000000000003,0.000000000000005])
[0.9708266589000533, 0.029124799767001597, 4.854133294500266e-05]
Run Code Online (Sandbox Code Playgroud)

极端的情况:

>>> 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
Run Code Online (Sandbox Code Playgroud)