我正在计算单词的相对频率(字数/单词总数)。这导致了相当多的非常小的数字(例如1.2551539760140076e-05)。我已经阅读了在这种情况下使用浮点的一些问题,例如在本文中
浮点值大约有七位小数精度。。。
有些人建议使用记录值。我要把这些数字相乘,想知道
- 一般来说,在Python中,七位数规则是可以遵循的吗
- 在我的情况下,我应该使用日志值吗
- 如果我不这样做,会发生什么坏事——只是一个不太准确的值或直接的错误,例如乘法
- 如果是这样的话,我只是用mathem.log()转换浮点值吗?我觉得在这一点上信息已经丢失了
非常感谢您的帮助!
这篇文章讨论了C中的类型float
,它是一个32位的量。Python类型的float
是一个64位数字,与C的double
类似,因此可以存储大约17个十进制数字(53个小数位数,而不是C的float
的24个小数位数)。虽然对于某些应用程序来说,这也可能是太低的精度,但它远没有32位浮点那么可怕。
此外,因为它是浮点格式,所以像1.2551539760140076e-05
这样的小数字(实际上并没有那么小)本质上并不不利。虽然只能表示大约17个十进制数字,但这17个数字不必是小数点后的前17个数字。它们可以四处移动,也就是说1。事实上,当您将一个数字作为一组十进制数字乘以十次方(e-5
)时,您使用了浮点(十进制)的相同概念。举个极端的例子,1-300可以表示得很好2,10300—只有当这两个数字相遇时,问题才会发生(1e300 + 1e-300 == 1e300
)。
对于日志表示,您应该尽早获取所有值的日志,并在日志空间中执行尽可能多的计算。在您的示例中,您可以将一个单词的相对频率计算为log(word_count) - log(total_words)
,这与log(word_count / total_words)
相同,但可能更准确。
如果我不这样做,会发生什么坏事——只是一个不太准确的值或直接的错误,例如乘法?
我不确定区别是什么。数值计算可以有几乎完美的精度(在2-50或更好的范围内的相对舍入误差),但在某些情况下,不稳定的算法也会给出可笑的糟糕结果。每个单独运算3的舍入误差都有相当严格的界限,但在较长的计算中,它们以令人惊讶的方式相互作用,导致非常大的误差。例如,即使只是对一大串浮点数求和,也会引入显著的误差,尤其是当它们的大小和符号非常不同时。正确分析和设计可靠的数值算法本身就是一门艺术,我在这里无法做到这一点,但由于IEEE-754的良好设计,大多数算法通常都能好的。不要太担心,但也不要忽视它。
1事实上,我们谈论的是53个二进制数字的移位,但这对这个概念来说并不重要。存在小数浮点格式。
2相对舍入误差小于2-54,这发生在分母不是二次幂的任何分数上,包括1/3或0.1
这样的普通分数。
3对于基本算术运算,舍入误差应为最后一位的半个单位,即必须精确计算结果,然后正确舍入。对于超越函数,误差很少超过最后一个单位或两个单位,但可能更大。