Sto cercando una funzione in Numpy o Scipy (o qualsiasi libreria Python rigorosa) che mi fornirà la funzione di distribuzione normale cumulativa in Python.Come calcolare la distribuzione normale cumulativa in Python
risposta
Adattato da qui 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))
Ecco un esempio:
>>> from scipy.stats import norm
>>> norm.cdf(1.96)
array(0.97500210485177952)
Se avete bisogno della CDF inversa:
>>> norm.ppf(norm.cdf(1.96))
array(1.9599999999999991)
Inoltre, è possibile specificare la media (loc) e la varianza (scala) come parametri. per esempio, d = norma (loc = 10.0, scale = 2.0); d.cdf (12.0); Dettagli qui: http://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.stats.norm.html – Irvan
@Irvan, il parametro di scala è in realtà la deviazione standard, NON la varianza. – qkhhly
Perché scipy le chiama "loc" e "scale"? Ho usato 'help (norm.ppf)' ma poi cosa diamine sono 'loc' e' scale' - ho bisogno di un aiuto per l'aiuto .. – javadba
Per sviluppare l'esempio di Unknown, l'equivalente Python la funzione normdist() implementata in molte librerie sarebbe:
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
Come Google dà questa risposta per la ricerca NetLogo pdf, ecco la versione NetLogo del codice Python sopra
;; 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
La domanda riguarda Python, non NetLogo. Questa risposta non dovrebbe essere qui. E per favore non modificare la domanda per cambiarne il significato. – interjay
Sono consapevole che questo non è il modo preferito, ma immagino che sia molto utile in questo modo dato che le persone sono indirizzate a questa pagina da google (attualmente ...) – platipodium
Potrebbe essere troppo tardi per rispondere alla domanda, ma dal momento che Google ancora contatti gente qui, decido di scrivere la mia soluzione qui.
Cioè, dato che Python 2.7, la libreria math
ha integrato la funzione di errore math.erf(x)
La funzione erf()
può essere usato per calcolare funzioni statistiche tradizionali come la cumulativa della distribuzione normale standard:
from math import *
def phi(x):
#'Cumulative distribution function for the standard normal distribution'
return (1.0 + erf(x/sqrt(2.0)))/2.0
Rif:
https://docs.python.org/2/library/math.html
https://docs.python.org/3/library/math.html
How are the Error Function and Standard Normal distribution function related?
Questo era esattamente quello che stavo cercando. Se qualcun altro oltre a me si chiede come questo possa essere utilizzato per calcolare "la percentuale di dati che si trova all'interno della distribuzione standard", beh: 1 - (1 - phi (1)) * 2 = 0,6827 ("68% dei dati all'interno di 1 standard deviazione") –
risposta di Alex mostra una soluzione per la distribuzione normale standard (media = 0, deviazione standard = 1). Se si dispone di una distribuzione normale con mean
e std
(che è sqr(var)
) e si vuole calcolare:
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)
Per saperne di più cdf here e SciPy implementazione di distribuzione normale con molte formule here.
Poiché la std lib implementa math.erf(), non è necessaria un'implementazione sep. – Marc