normal - rvs python
DistribuciĆ³n normal sesgada en scipy (2)
De la description Wikipedia,
from scipy import linspace
from scipy import pi,sqrt,exp
from scipy.special import erf
from pylab import plot,show
def pdf(x):
return 1/sqrt(2*pi) * exp(-x**2/2)
def cdf(x):
return (1 + erf(x/sqrt(2))) / 2
def skew(x,e=0,w=1,a=0):
t = (x-e) / w
return 2 / w * pdf(t) * cdf(a*t)
# You can of course use the scipy.stats.norm versions
# return 2 * norm.pdf(t) * norm.cdf(a*t)
n = 2**10
e = 1.0 # location
w = 2.0 # scale
x = linspace(-10,10,n)
for a in range(-3,4):
p = skew(x,e,w,a)
plot(x,p)
show()
Si desea buscar los parámetros de escala, ubicación y forma de un conjunto de datos, utilice scipy.optimize.leastsq
, por ejemplo, utilizando e=1.0
, w=2.0
y a=1.0
,
fzz = skew(x,e,w,a) + norm.rvs(0,0.04,size=n) # fuzzy data
def optm(l,x):
return skew(x,l[0],l[1],l[2]) - fzz
print leastsq(optm,[0.5,0.5,0.5],(x,))
debería darle algo como
(array([ 1.05206154, 1.96929465, 0.94590444]), 1)
¿Alguien sabe cómo trazar una distribución normal sesgada con scipy? Supongo que se puede usar la clase stats.norm pero no puedo entender cómo. Además, ¿cómo puedo estimar los parámetros que describen la distribución normal oblicua de un conjunto de datos unidimensional?
La respuesta aceptada está más o menos desactualizada, porque ahora se implementa una función skewnorm en scipy. Así que el código se puede escribir mucho más corto:
from scipy.stats import skewnorm
import numpy as np
from matplotlib import pyplot as plt
X = np.linspace(min(your_data), max(your_data))
plt.plot(X, skewnorm.pdf(X, *skewnorm.fit(your_data))