8

给定定义正态分布的均值和标准差,您将如何在纯 Python 中计算以下概率(即没有 Numpy/Scipy 或其他不在标准库中的包)?

  1. 随机变量 r 的概率,其中 r < x 或 r <= x。
  2. 随机变量 r 的概率,其中 r > x 或 r >= x。
  3. 随机变量 r 的概率,其中 x > r > y。

我发现了一些库,比如Pgnumerics,它们提供了计算这些函数的函数,但我不清楚底层的数学。

编辑:为了表明这不是家庭作业,下面发布的是我的 Python<=2.6 工作代码,尽管我不确定它是否正确处理边界条件。

from math import *
import unittest

def erfcc(x):
    """
    Complementary error function.
    """
    z = abs(x)
    t = 1. / (1. + 0.5*z)
    r = t * exp(-z*z-1.26551223+t*(1.00002368+t*(.37409196+
        t*(.09678418+t*(-.18628806+t*(.27886807+
        t*(-1.13520398+t*(1.48851587+t*(-.82215223+
        t*.17087277)))))))))
    if (x >= 0.):
        return r
    else:
        return 2. - r

def normcdf(x, mu, sigma):
    t = x-mu;
    y = 0.5*erfcc(-t/(sigma*sqrt(2.0)));
    if y>1.0:
        y = 1.0;
    return y

def normpdf(x, mu, sigma):
    u = (x-mu)/abs(sigma)
    y = (1/(sqrt(2*pi)*abs(sigma)))*exp(-u*u/2)
    return y

def normdist(x, mu, sigma, f):
    if f:
        y = normcdf(x,mu,sigma)
    else:
        y = normpdf(x,mu,sigma)
    return y

def normrange(x1, x2, mu, sigma, f=True):
    """
    Calculates probability of random variable falling between two points.
    """
    p1 = normdist(x1, mu, sigma, f)
    p2 = normdist(x2, mu, sigma, f)
    return abs(p1-p2)
4

1 回答 1

10

所有这些都非常相似:如果您可以使用函数计算#1 cdf(x),那么#2 的解决方案是简单1 - cdf(x)的,而对于#3 它是cdf(x) - cdf(y)

由于 Python 包含自 2.7 版以来内置的(高斯)误差函数,您可以通过使用您链接到的文章中的公式计算正态分布的 cdf 来做到这一点:

import math
print 0.5 * (1 + math.erf((x - mean)/math.sqrt(2 * standard_dev**2)))

其中mean是平均值,standard_dev是标准差。

鉴于文章中的信息,自您提出的问题以来的一些注释似乎相对简单:

  • 随机变量(比如 X)的 CDF 是 X 位于 -infinity 和某个极限之间的概率,比如 x(小写)。CDF 是连续分布的 pdf 的积分。cdf 正是您为#1 所描述的,您希望一些正态分布的 RV 介于 -infinity 和 x (<= x) 之间。
  • < 和 <= 以及 > 和 >= 对于连续随机变量是相同的,因为 rv 是任何单点的概率为 0。因此,在计算连续分布的概率时,是否包含 x 本身实际上并不重要.
  • 概率之和为 1,如果它不是 < x 那么它是 >= x 所以如果你有cdf(x). 然后1 - cdf(x)是随机变量 X >= x 的概率。由于 >= 等价于连续随机变量 >,这也是概率 X > x。
于 2012-02-25T21:40:22.077 回答