Як розрахувати кумулятивний нормальний розподіл?


99

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

Відповіді:


125

Ось приклад:

>>> 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)

9
Крім того, ви можете вказати середні значення (loc) та дисперсію (масштаб) як параметри. наприклад, d = норма (loc = 10,0, шкала = 2,0); d.cdf (12,0); Подробиці тут: docs.scipy.org/doc/scipy-0.14.0/reference/generated / ...
Ірван

6
@Irvan, параметр шкали насправді є стандартним відхиленням, А НЕ дисперсією.
qkhhly

2
Чому Scipy називає їх такими як locі scale? Я використав, help(norm.ppf)але тоді, що за біса locі scale- потрібна допомога для допомоги ..
javadba

2
@javadba - місце розташування та масштаб є більш загальними термінами в статистиці, які використовуються для параметризації широкого кола розподілів. Для нормального розподілу вони вирівнюються із середнім значенням і sd, але не так для інших розподілів.
Майкл Ольрогге

1
@MichaelOhlrogge. Дякую! Ось сторінка з NIST, що пояснює далі itl.nist.gov/div898/handbook/eda/section3/eda364.htm
javadba

40

Можливо, пізно відповісти на питання, але оскільки 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

Довідка:

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

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

Як пов’язані функція помилки та стандартна нормальна норма розподілу?


3
Це було саме те, що я шукав. Якщо хтось, крім мене, задається питанням, як це можна використовувати для обчислення "відсотка даних, що лежить в межах стандартного розподілу", добре: 1 - (1 - phi (1)) * 2 = 0,6827 ("68% даних в межах 1 стандарту відхилення ")
Hannes Landeholm

1
Для загального нормального розподілу це було б def phi(x, mu, sigma): return (1 + erf((x - mu) / sigma / sqrt(2))) / 2.
Бернхард Баркер

19

Адаптовано звідси 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))

3
Оскільки std lib реалізує math.erf (), немає потреби в сеп-реалізації.
Марк

я не зміг знайти відповідь, звідки ці цифри?
TmSmth

15

На основі прикладу 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

15

Починаючи із того 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

9

Відповідь Алекса показує вам рішення для стандартного нормального розподілу (середнє = 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 читайте тут, а про впровадження звичайного розподілу за допомогою багатьох формул тут .


2

Взяті зверху:

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


-9

Оскільки Google дає цю відповідь для пошуку netlogo pdf , ось версія netlogo вищезазначеного коду python

    ;; Функція кумулятивної щільності нормального розподілу
    повідомляти нормуcdf [x mu sigma]
        нехай tx - mu
        нехай y 0,5 * erfcc [- t / (sigma * sqrt 2.0)]
        якщо (y> 1,0) [встановити y 1,0]
        звіт y
    кінець

    ;; Функція густини ймовірності нормального розподілу
    повідомляти normpdf [x mu sigma]
        нехай сигма u = (x - mu) / abs
        нехай y = 1 / (sqrt [2 * pi] * abs sigma) * exp (- u * u / 2.0)
        звіт y
    кінець

    ;; Додаткова функція помилки
    звітувати про erfcc [x]
        нехай z абс х
        нехай t 1,0 / (1,0 + 0,5 * z)
        нехай rt * 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) [звіт r] [звіт 2.0 - r]
    кінець


6
Питання стосується Python, а не NetLogo. Тут відповіді не повинно бути. І не редагуйте питання, щоб змінити його значення.
інтержой

Я усвідомлюю, що це не найкращий спосіб, але, мабуть, це найбільш корисно, оскільки людей спрямовує на цю сторінку Google (наразі ...)
platipodium
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.