Как рассчитать кумулятивное нормальное распределение в Python - PullRequest
83 голосов
/ 01 мая 2009

Я ищу функцию в Numpy или Scipy (или в любой строгой библиотеке Python), которая даст мне интегральную функцию нормального распределения в Python.

Ответы [ 8 ]

111 голосов
/ 01 мая 2009

Вот пример:

>>> from scipy.stats import norm
>>> norm.cdf(1.96)
0.9750021048517795
>>> norm.cdf(-1.96)
0.024997895148220435

Другими словами, приблизительно 95% стандартного нормального интервала лежит в пределах двух стандартных отклонений, центрированных по стандартному среднему нулю.

Если вам нужен обратный CDF:

>>> norm.ppf(norm.cdf(1.96))
array(1.9599999999999991)
31 голосов
/ 26 марта 2015

Возможно, уже слишком поздно отвечать на вопрос, но, поскольку Google по-прежнему приводит людей сюда, я решил написать свое решение здесь.

То есть, начиная с Python 2.7, библиотека math имеет встроенную функцию ошибок math.erf(x)

Функция erf() может использоваться для вычисления традиционных статистических функций, таких как совокупное стандартное нормальное распределение:

from math import *
def phi(x):
    #'Cumulative distribution function for the standard normal distribution'
    return (1.0 + erf(x / sqrt(2.0))) / 2.0

Ref:

https://docs.python.org/2/library/math.html

https://docs.python.org/3/library/math.html

Как связаны функция ошибок и функция стандартного нормального распределения?

18 голосов
/ 01 мая 2009

Адаптировано отсюда http://mail.python.org/pipermail/python-list/2000-June/039873.html

from math import *
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 ncdf(x):
    return 1. - 0.5*erfcc(x/(2**0.5))
14 голосов
/ 19 августа 2010

Если исходить из примера Unknown, эквивалент Python функции normdist (), реализованной во многих библиотеках, будет:

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
8 голосов
/ 20 ноября 2015

Ответ Алекса показывает вам решение для стандартного нормального распределения (среднее = 0, стандартное отклонение = 1). Если у вас нормальное распределение с mean и std (что составляет sqr(var)), и вы хотите вычислить:

from scipy.stats import norm

# cdf(x < val)
print norm.cdf(val, m, s)

# cdf(x > val)
print 1 - norm.cdf(val, m, s)

# cdf(v1 < x < v2)
print norm.cdf(v2, m, s) - norm.cdf(v1, m, s)

Подробнее о cdf здесь и scipy реализация нормального распределения со многими формулами здесь .

2 голосов
/ 28 февраля 2019

Начиная с Python 3.8, стандартная библиотека предоставляет объект NormalDist в составе модуля statistics.

Может использоваться для получения кумулятивной функции распределения (cdf) - вероятность того, что случайная выборка X будет меньше или равна x ) для данного означает (mu) и стандартное отклонение (sigma):

from statistics import NormalDist

NormalDist(mu=0, sigma=1).cdf(1.96)
# 0.9750021048517796

Что может быть упрощено для стандартного нормального распределения (mu = 0 и sigma = 1):

NormalDist().cdf(1.96)
# 0.9750021048517796

NormalDist().cdf(-1.96)
# 0.024997895148220428
1 голос
/ 07 февраля 2019

Взятые сверху:

from scipy.stats import norm
>>> norm.cdf(1.96)
0.9750021048517795
>>> norm.cdf(-1.96)
0.024997895148220435

Для двустороннего теста:

Import numpy as np
z = 1.96
p_value = 2 * norm.cdf(-np.abs(z))
0.04999579029644087
0 голосов
/ 18 октября 2012

Поскольку Google дает этот ответ для поиска netlogo pdf , вот версия netlogo приведенного выше кода Python


    ;; Normal distribution cumulative density function
    to-report normcdf [x mu sigma]
        let t x - mu
        let y 0.5 * erfcc [ - t / ( sigma * sqrt 2.0)]
        if ( y > 1.0 ) [ set y 1.0 ]
        report y
    end

    ;; Normal distribution probability density function
    to-report normpdf [x mu sigma]
        let u = (x - mu) / abs sigma
        let y = 1 / ( sqrt [2 * pi] * abs sigma ) * exp ( - u * u / 2.0)
        report y
    end

    ;; Complementary error function
    to-report erfcc [x]
        let z abs x
        let t 1.0 / (1.0 + 0.5 * z)
        let r t *  exp ( - z * z -1.26551223 + t * (1.00002368 + t * (0.37409196 +
            t * (0.09678418 + t * (-0.18628806 + t * (.27886807 +
            t * (-1.13520398 +t * (1.48851587 +t * (-0.82215223 +
            t * .17087277 )))))))))
        ifelse (x >= 0) [ report r ] [report 2.0 - r]
    end

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...