web-dev-qa-db-fra.com

Comment calculer la distribution normale cumulative dans Python

Je cherche une fonction dans Numpy ou Scipy (ou toute autre bibliothèque Python) rigoureuse qui me donnera la fonction de distribution normale cumulative en Python.

85
toma

Voici un exemple:

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

En d’autres termes, environ 95% de l’intervalle normal standard est compris entre deux écarts-types, centrés sur une moyenne standard de zéro.

Si vous avez besoin du CDF inverse:

>>> norm.ppf(norm.cdf(1.96))
array(1.9599999999999991)
112
Alex Reynolds

Il est peut-être trop tard pour répondre à la question, mais comme Google guide toujours les gens ici, j'ai décidé d'écrire ma solution ici.

En d’autres termes, depuis Python 2.7, la bibliothèque math a intégré la fonction d’erreur math.erf(x)

La fonction erf() peut être utilisée pour calculer des fonctions statistiques traditionnelles telles que la distribution normale standard cumulative:

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

Quel est le lien entre la fonction d'erreur et la fonction de distribution standard normale?

33
WTIFS

Adapté à partir d'ici 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))
18
Unknown

Pour reprendre l'exemple de Unknown, l'équivalent Python de la fonction normdist () implémentée dans de nombreuses bibliothèques est le suivant:

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
14
Cerin

La réponse d'Alex vous montre une solution pour la distribution normale standard (moyenne = 0, écart type = 1). Si vous avez une distribution normale avec mean et std (ce qui est sqr(var)) et que vous voulez calculer:

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)

En savoir plus sur cdf ici et la mise en œuvre scipy de la distribution normale avec de nombreuses formules ici .

8
Salvador Dali

Commencer Python 3.8, la bibliothèque standard fournit l’objet NormalDist dans le cadre du module statistics .

Il peut être utilisé pour obtenir la fonction de distribution cumulative ( cdf = - probabilité qu'un échantillon aléatoire X soit inférieur ou égal à x) pour un donné moyen (mu) et écart type (sigma):

from statistics import NormalDist

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

Ce qui peut être simplifié pour la distribution normale standard (mu = 0 et sigma = 1):

NormalDist().cdf(1.96)
# 0.9750021048517796

NormalDist().cdf(-1.96)
# 0.024997895148220428
4
Xavier Guihot

Pris d'en haut:

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

Pour un test bilatéral:

Import numpy as np
z = 1.96
p_value = 2 * norm.cdf(-np.abs(z))
0.04999579029644087
1
David Miller