在我正在生成的模型的上下文中,我一度需要从一组实数中生成概率分布。我将省略相关细节,但基本上有一个函数(我们现在只称它为“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,我担心这可能会引入更多不必要的精确问题。有更好的解决方案吗?
答案 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'
];
但是对于需要更正确的更复杂的计算,您将不得不进行错误评估。