【问题标题】:Python and R are returning different results where they should be exactly the same [closed]Python和R返回不同的结果,它们应该完全相同[关闭]
【发布时间】:2016-09-11 08:39:26
【问题描述】:

[Python numpy 代码]

In [171]: A1*b
Out[171]: 
array([ -7.55603523e-01,   7.18519356e-01,   3.98628050e-03,
     9.27047917e-04,  -1.31074698e-03,   1.44455190e-03,
     1.02676602e-03,   5.03891225e-02,  -1.15752426e-03,
    -2.43685270e-02,   5.88382307e-03,   2.63372861e-04])
In [172]: (A1*b).sum()
Out[172]: -1.6702134467139196e-16    

[R码]

> cholcholT[2,] * b
[1] -0.7556035225  0.7185193560  0.0039862805  0.0009270479 -0.0013107470
[6]  0.0014445519  0.0010267660  0.0503891225 -0.0011575243 -0.0243685270
[11]  0.0058838231  0.0002633729
> sum(cholcholT[2,] * b)
[1] -9.616873e-17

第一个是R代码,第二个是numpy。直到两个向量的元素乘积,它们返回相同的结果。但是,如果我尝试将它们加起来,它们就会变得不同。我相信这与两者的精度设置无关,因为它们都是基于双精度的。为什么会这样?

【问题讨论】:

  • 请不要发布图片来分享数据或代码。
  • 哦,天哪……这些数字太小了……你不能指望两个不同的系统返回完全相同的数字,直到第 16 位!
  • @digEmAll 所以这是自然的?!
  • @DaeyoungLim:您应该将这些结果都视为零(1*10^-16 基本上为零)。 python 和 R 都使用浮点精度,即使它们执行相同的操作,内部操作的顺序也可能略有不同,这可能导致非常小的差异(即使在数学上它们是相等的)。这是一个很好的例子,说明浮点数学是如何不是完美if(0.1+0.1+0.1 != 0.3) print('OMG !')
  • 如何也发布输入。

标签: python r numpy


【解决方案1】:

您正在经历所谓的灾难性取消。您正在从彼此减去仅略有不同的数字。结果,您得到的数字相对于它们的值具有非常高的误差。该错误源于舍入错误,当您的系统存储无法由二进制系统准确表示的值时引入。

直观地说,您可以认为这与将 1/3 写为十进制数时遇到的困难相同。你必须写 0.3333... ,所以小数点后面有无数个 3。你不能这样做,你的电脑也不能。

因此,您的计算机必须在某处对数字进行四舍五入。

如果你使用类似的东西,你可以看到舍入错误

"{:.20e}".format(0.1)

您会看到在第 16 位左右之后,您要存储的数字(1.0000000000000000000...×10^-1)与计算机存储的数字不同(1.00000000000000005551...×10^-1)

要查看这种不准确性的数量级,您可以查看机器 epsilon。简而言之,该值为您提供了相对于您的值的最小数量,您可以将其添加到您的值中,以便计算机仍然可以将结果与旧值区分开来(因此在将结果存储在内存中时不会四舍五入)。

如果你执行

import numpy as np
eps = np.finfo(float).eps

你可以看到这个值在 10^-16 的数量级上。

计算机以SIGN|EXPONENT|FRACTION 之类的形式表示浮点数。所以为了大大简化,如果计算机内存以十进制格式存储数字,则像 -0.0053 这样的数字将存储为1|-2|.53|1 表示负号,-2 表示“FRACTION 乘以 10^-2”。

如果对浮点数求和,计算机必须用相同的指数来表示每个浮点数,以便将 FRACTION 的数字相加/相减。因此,您的所有值都将以数据的最大指数表示,即 -1。因此,您的舍入误差将在 10^-16*10^-1 的数量级,即 10^-17。你可以看到你的结果也是这个数量级的,所以它受你的数字舍入误差的影响很大。

【讨论】:

    【解决方案2】:

    您正在使用浮点数并对其应用算术运算。 Floating point arithmetic is a dangerous thing 因为它总是会产生一个小的舍入误差。无论此错误是向上还是向下舍入,或者只是从二进制表示中“截断”,都可能出现不同的结果。

    【讨论】:

    • 当您对我的回答投反对票时,请告诉我原因。我只是来帮忙的。
    • 可能是因为太简单了?浮点数是确定性的。如果输入和操作顺序相同,则浮点每次都会确定相同的结果,因为您产生的舍入误差在每种情况下都是相同的。有些东西必须有所不同(在这种情况下可能是顺序)。顺便说一句,我没有投反对票。
    • 确定性说相同输入的相同程序产生相同的输出。但是我们在这里比较两个不同的程序
    猜你喜欢
    • 1970-01-01
    • 2017-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多