用Python计算分布中随机变量的概率


问题内容

给定定义正态分布的均值和标准差,您将如何计算纯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)

问题答案:

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

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

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

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

考虑到本文中的信息,自您提出的问题起一些注意事项似乎相对简单:

  • 随机变量的CDF(例如X)是X介于-无限和某个极限之间的概率,例如x(小写)。CDF是连续发行版pdf的组成部分。cdf正是您为#1所描述的,您希望一些正态分布的RV在-infinity和x(<= x)之间。
  • 连续随机变量的 <和<=以及>和> =相同,因为rv是任意单点的概率为0。因此,计算连续分布的概率时,是否包含x本身实际上并不重要。 。
  • 概率之和为1,如果它不是 = x,所以如果有 cdf(x)。那么 1 - cdf(x)是随机变量X> = x的概率。因为> =对于连续随机变量等于>,所以这也是X> x的概率。