【问题标题】:Getting high precision values from qnorm in the tail从尾部的 qnorm 获取高精度值
【发布时间】:2017-04-12 07:07:19
【问题描述】:

问题

我正在寻找尾部 (1e-10 and 1 - 1e-10) 中正态分布的高精度值,因为我使用的 R 包将超出此范围的任何数字设置为这些值,然后调用 qnorm 和 @ 987654325@函数。

我注意到的是,R 中的 qnorm 实现在查看尾部时是不对称的。这让我很惊讶,因为众所周知这种分布是对称的,而且我已经看到其他对称语言的实现。我检查了qt 函数,它的尾部也不是对称的。

以下是 qnorm 函数的结果:

x       qnorm(x)                qnorm(1-x)              qnorm(1-x) + qnorm(x)
1e-2    -2.3263478740408408     2.3263478740408408      0.0 (i.e < machine epsilon)
1e-3    -3.0902323061678132     3.0902323061678132      0.0 (i.e < machine epsilon)
1e-4    -3.71901648545568       3.7190164854557084      2.8421709430404007e-14
1e-5    -4.2648907939228256     4.2648907939238399      1.014299755297543e-12
1e-10   -6.3613409024040557     6.3613408896974208      -1.2706634855419452e-08

很明显,x 的值接近 0 或 1 时,此函数会失效。是的,在“正常”使用中这不是问题,但我正在查看边缘情况并将小概率乘以非常大的值,在这种情况下,错误 (1e-08) 会变成一个很大的值。

注意:我已经尝试过使用1-x 并输入实际数字0.000010.99999,但准确性问题仍然存在。

问题

首先,这是qnormqt 实现的已知问题吗?我在文档中找不到任何内容,对于来自10^-314 的 p 值,该算法应该是准确的 16 位数字,如@9​​87654321@ 论文中所述。

引用自 R 文档:

Wichura, M. J. (1988) 算法 AS 241:正态分布的百分比。应用统计,37, 477–484。

提供高达约 16 位的精确结果。

如果 R 代码实现了 7 位版本,为什么它要求 16 位?还是说“准确”但原算法不对称且错误?

如果 R 确实实现了 Algorithm AS 241 的两个版本,我可以打开 16 位版本吗?

或者,R 中是否有更准确的qnorm 版本? 或者,我的问题的另一种解决方案是我需要高精度的分位数函数的尾部。

R 版本

>version 
platform       x86_64-w64-mingw32          
arch           x86_64                      
os             mingw32                     
system         x86_64, mingw32             
status                                     
major          3                           
minor          3.2                         
year           2016                        
month          10                          
day            31                          
svn rev        71607                       
language       R                           
version.string R version 3.3.2 (2016-10-31)
nickname       Sincere Pumpkin Patch   

【问题讨论】:

  • 最好在 R-dev 邮件列表中询问。
  • 好主意@Spacedman,我不是一个狂热的 R 用户,也不知道这个列表。

标签: r normal-distribution


【解决方案1】:

事实证明(正如 Spencer Graves 在his response 中对 R-devel list-serve 上的同一个问题所指出的那样)qnorm() 确实 确实像宣传的那样执行。只是,要在分布的上尾得到高度准确的结果,您需要利用函数的 lower.tail 参数。

这是怎么做的:

options(digits=22)

## For values of p in [0, 0.5], specify lower tail probabilities 
qnorm(p = 1e-10)                      ## x: P(X <= x) == 1e-10
# [1] -6.3613409024040557

## For values of p in (0.5, 1], specify upper tail probabilities
qnorm(p = 1e-10, lower.tail=FALSE)    ## x: P(X > x)  == 1e-10     (correct approach)
# [1] 6.3613409024040557
qnorm(p = 1 - 1e-10)                  ## x: P(X <= x) == 1-(1e-1)  (incorrect approach)
# [1] 6.3613408896974208

问题在于1-1e-10(例如)存在浮点舍入误差,因此它与1(区间的上端)的距离与1e-10 的距离并不相同0(区间下限)。当以更熟悉的形式出现时,潜在的问题(它是R-FAQ 7.31!)变得显而易见:

1 - (1 - 1e-10) == 1e-10
## [1] FALSE

最后,快速确认qnorm() 提供与其帮助文件中声明的值一致的(或至少对称)结果:

qnorm(1e-314)
## [1] -37.906647423565666
qnorm(1e-314, lower.tail=FALSE)
## [1] 37.906647423565666

## With this failing in just the way (and for just the reason) you'd now expect
qnorm(1-1e-314)
# [1] Inf
1 == (1-1e-314)
# [1] TRUE

【讨论】:

  • 感谢您在@Josh 此处添加 Spences 的答案。我知道这个浮点错误,但我认为从 0 到 1e-10 的距离与从 1 到 0.9999999999 的距离相同;如果我明确输入 0.9999999999。但我看到,由于函数的编码方式,这是不正确的。
  • @Sheldon 这就是它们与端点的距离不能相同的原因。首先,(0.1)^n 形式的任何值都不能用浮点数绝对精确地表示。只有通过添加额外的二进制数字才能越来越近。在值1e-10 的情况下,那些有限的数字在0.0000000001 的右侧开始用完,而对于0.9999999999,您必须开始“用尽”有限数量的二进制数字第一个 9 的左侧,留下更多的近似值以继续超出最终的 9。 HTH!
猜你喜欢
  • 2013-12-28
  • 1970-01-01
  • 2012-06-20
  • 2016-02-18
  • 1970-01-01
  • 2012-12-12
  • 1970-01-01
  • 1970-01-01
  • 2014-11-29
相关资源
最近更新 更多