x<0 时标准正态 CDF 的对数近似值

机器算法验证 正态分布 累积分布函数 近似 对数
2022-03-09 16:07:51

有谁知道 x<0 的标准正态 CDF 的对数的近似值?

我需要实现一个非常快速计算它的算法。当然,最直接的方法是首先计算 CDF(我可以在 Wikipedia 上找到合适的简单近似值),然后对其取对数。显然,我想避免计算两个特殊函数的时间成本,更不用说微小的中间值(尾部)排除了使用比浮点运算快得多的定点运算。

我知道各种统计函数有数百种近似值,但这是一个的对数这一事实使得找到一个变得更加困难。如果有人能给我指出一个,或者我可能找到的来源,我将不胜感激。

4个回答

,即使是一个简单的最小二乘三次拟合到似乎也足够了。log(Φ(x))x

只是为了快速了解它,我在 -5 和 0 之间每隔 0.01 生成值,并尝试将最小二乘三次和五次(5 次)多项式拟合到我想你可以像我一样轻松地做到这一点,所以我不会强调这一点。xlog2(Φ(x))

对于五次方的最大绝对误差,它出现在零处。log2(Φ(x))5.2×104

[不完全清楚你所说的“在 0.2 + 10% 左右”是什么意思。如果您可以详细说明以明确您的标准,那么我可以详细说明这一点,并可能调整权重以更好地优化您的标准。]

在评估多项式时,如果速度很重要,您应该牢记霍纳的方法。


正如红衣主教所建议的那样,情节非常具有说明性。既然我已经生成了一个,我应该把它放在这里:

在此处输入图像描述

这是(有符号的)错误(日志中的绝对比例错误):

在此处输入图像描述

它看起来和我们期望的最小二乘拟合一样。不合身度相当适中;出于许多目的,这很好。


另一种方法是您可以将上尾的 Karagiannidis 和 Lioumpas 近似值(参见此处)翻转到下尾(通过替换为)并获取日志:xx

Q(x)(1e1.4x)ex221.1352πx,x>0

所以我们得到

ln(Φ(x))ln(1e1.4x)ln(x)x221.04557

要获得以 2 为底的日志,只需将结果乘以log2(e)

这不如我提到的五次拟合准确,并且由于对数和求幂,评估可能更慢。不过,它又好又短,有一些优点。请注意,它不是为对数刻度设计的。


原始论文有 K&L 的公式 6:

(1eAx)ex2Bπxerfc(x)

对于值,他们建议xA=1.98B=1.135

除以以获得,这表明维基百科页面上的公式(x2Q1.98/21.40007


让我们看看对数尺度的近似质量。

在此处输入图像描述

紫色虚线是 K&L 近似值。现在让我们看看错误:

在此处输入图像描述

错误的大小比我们的五次要大得多。它在范围左半部分的中几乎是线性的这一事实来改善误差 - 但这会使接近值的近似值更差 - 1. 是否会这样做取决于所需的特征。x0.02x0.025x

这是神经网络用户的替代解决方案:

1 / (1 + 2*exp(-sqrt(2*pi)*x))您可以使用(扩展近似)来近似 CDF 。

并利用大多数深度学习框架具有log(1 + exp(x))作为softplus激活函数的数值稳定实现这一事实。

得到的公式可以写成两行pytorch:

def log_standard_normal_cdf(x):
    return -F.softplus(np.log(2) - x*np.sqrt(2*np.pi))

为了覆盖比最初要求的范围更广,我最终想出了这个有理近似值

ln(Φ(x<0))12x24.8+2509x13(x40)2(x5)

它的绝对误差在 0.04 到 20 个标准偏差下,之后误差可能会超过该值,但仍低于该值的 0.04%(据我可以通过数值计算验证)。

我最近遇到了同样的问题,并找到了我认为更好的解决方案。Faddeeva有一组用于计算 erf(z)、erfc(z) 等的精确函数。它们都从计算 Faddeeva 函数 w(z) 开始:

w(z)=ez2erfc(iz)

您可以显示正常 cdf 的日志是

logΦ(z)=log[12(1+erf(z2))]=log(12)+log[1+erf(z2)]=log(12)+log[ez2w(iz2)]=log(12)z22+log[w(iz2)]

所以现在我们可以计算三个表现良好的简单量,并得到对于非常小的 z 也表现良好。我验证了你得到的值与它有效的域 的常规值完全相同。logΦ(z)normcdf

对于非常小的 z,我不知道“正确”的答案,但是对于 z=-100,你会得到 -5005.5242,它通常只会给你 -inf。这种方法的优点是使用现有的包来进行棘手的计算,因此您不必自己制作近似值,而且速度很快。

在 python 中,w可以作为. w(z)scipy.special.wofz