在python中生成概率分布时处理精度错误

时间:2015-07-13 19:19:18

标签: python

在我正在生成的模型的上下文中,我一度需要从一组实数中生成概率分布。我将省略相关细节,但基本上有一个函数(我们现在只称它为“f”),它会生成一个n浮点数组:

arr = [value_1, value_2, ..., value_n]

现在,这些值比例与我接下来需要在多项采样程序中使用的概率,所以显而易见的方法就是:

result = np.random.multinomial(number_of_samples,arr/arr.sum())

但这(有时)不起作用!基本上,arr / arr.sum()的总和最终大于1.原则上这在数学上是不可能的,但我假设这归结为浮点精度问题。这是一个如何发生这种情况的简单例子:

In [58]: arr = np.array([1/20.]*20)

In [59]: arr/arr.sum()
Out[59]:
array([ 0.05,  0.05,  0.05,  0.05,  0.05,  0.05,  0.05,  0.05,  0.05,
    0.05,  0.05,  0.05,  0.05,  0.05,  0.05,  0.05,  0.05,  0.05,
    0.05,  0.05])

In [60]: (arr/arr.sum()).sum()
Out[60]: 1.0000000000000002

长话短说,我的问题是如何最好地处理这个问题。我可以通过简单地在总和中添加一个非常小的数字来作弊,即:

probs = arr / (arr.sum()+0.000001)

但这确实是hackish,我担心这可能会引入更多不必要的精确问题。有更好的解决方案吗?

1 个答案:

答案 0 :(得分:1)

首先阅读https://docs.python.org/2/tutorial/floatingpoint.html

简而言之,浮点不能真正代表0.05。影响很小:

>>> repr(round(sum([1/20.]*20),5))
'1.0'

正确的解决方案是为每个数学运算定义所需的精度,计算每个步骤的舍入误差,并在必要时进行相应的舍入。

在您的情况下,您可以舍入到5位数,因为您只添加了几个数字。

static private $foo = [
        16 => 'xyz',
        7 => 'x',
        8 => 'y',
        9 => 'xy'
];

但是对于需要更正确的更复杂的计算,您将不得不进行错误评估。