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