Вычисление вероятности случайной величины в распределении в Python - PullRequest
7 голосов
/ 26 февраля 2012

Учитывая среднее значение и стандартное отклонение, определяющее нормальное распределение , как бы вы рассчитали следующие вероятности в чистом Python (т.е. нет Numpy / Scipy или других пакетов, отсутствующих в стандартной библиотеке)? *

  1. Вероятность случайной величины r, где r
  2. Вероятность случайной величины r, где r> x или r> = x.
  3. Вероятность случайной величины r, где x> r> y.

Я нашел несколько библиотек, таких как Pgnumerics , которые предоставляют функции для их вычисления, но основная математика мне не ясна.

Редактировать: чтобы показать, что это не домашнее задание, ниже приведен мой рабочий код для Python <= 2.6, хотя я не уверен, правильно ли он обрабатывает граничные условия. </p>

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 Ответ

9 голосов
/ 26 февраля 2012

Все они очень похожи: если вы можете вычислить # 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 - стандартное отклонение.

Некоторые примечания, поскольку то, что вы спросили, показалось относительно простым, учитывая информацию в статье:

  • CDF случайной величины (скажем, X) - это вероятность того, что X лежит между -infinity и некоторым пределом, скажем, x (нижний регистр). CDF является интегралом pdf для непрерывных распределений. Файл cdf - именно то, что вы описали для # 1, вы хотите, чтобы некоторые нормально распределенные RV находились между -infinity и x (<= x). </li>
  • <и <=, а также> и> = одинаковы для непрерывных случайных величин, так как вероятность того, что rv является какой-либо одной точкой, равна 0. Поэтому, действительно ли включен сам x, не имеет значения, когда вычисление вероятностей для непрерывных распределений.
  • Сумма вероятностей равна 1, если не > = x, поэтому если у вас есть cdf(x). тогда 1 - cdf(x) - вероятность того, что случайная величина X> = x. Поскольку> = для непрерывных случайных величин эквивалентно>, это также вероятность X> x.
...