数值稳定性

时间:2020-04-21 13:55:58

标签: python numpy numeric

我有一个机器学习模型,可以输出直到第一个小数点的概率(即0.0、0.1、0.2,... 1.0)

编写循环时

for i in np.arange(0,1.1,0.1)
    if p >= i:
       print('yes for i = %f' % i)
    else:
       print('no for i = %f' % i)

但是问题是np.arange输出的三个值略有数字错误:

0.3变为0.30000000000000004:

0.6变为0.6000000000000001:

0.7变为0.7000000000000001

p=0.6时,将导致输出

否,i = 0.6000000000000001

我该如何规避这个问题?

1 个答案:

答案 0 :(得分:0)

“小数值错误”不是数字错误,而是浮点数的已知问题:它们是两个存储的二进制数和can't represent all real numbers的分数之和。

如果要打印精确的n位数字,则可能需要使用格式字符串(例如%.1f而不是%f

要解决比较问题,您可以更改数字的存储方式(但考虑到您使用它们的字段,我怀疑这是个好主意),也可以更改数字的比较方式:为两个数字之间的ε“错误”差异留出空间。如果您不想实现自己的方式,可以use numpy/math isclose for checking equality像这样:

import numpy as np

p = 0.6

for i in np.arange(0,1.1,0.1):
    if p > i or np.isclose(p,i):
        print('yes for i = %f' % i)
    else:
        print('no for i = %f' % i)

取决于您希望实际执行的操作,而不是您给出的最小示例,一次完成比较可能会更有效:

i = np.arange(0,1.1,0.1)
compres = np.logical_or(p>i, np.isclose(p,i))

for i, ge in zip(i, compres):
    if ge:
        print('yes for i = %.1f' % i)
    else:
        print('no for i = %.1f' % i)

编辑: 我删除了在比较之前先乘以10000并四舍五入的想法,因为这可能会导致例如舍入错误。 0.649999与0.650001的情况。它可能有用,但要小心。

相关问题