python numpy random machine-learning normal-distribution

python - ¿Cómo obtener una distribución normal dentro de un rango en numpy?



random machine-learning (4)

Además de la sugerencia @bakkal (+1), es posible que desee echar un vistazo a la receta de Vincent Mazet para lograr esto, reescrita como módulo py-rtnorm por Christoph Lassner .

En la tarea de aprendizaje automático. Deberíamos obtener un grupo de distribución normal aleatoria de wrt con límite. Podemos obtener un número de distribución normal con np.random.normal() pero no ofrece ningún parámetro enlazado. Quiero saber como hacer eso?


La parametrización de truncnorm es complicada , así que aquí hay una función que traduce la parametrización a algo más intuitivo:

from scipy.stats import truncnorm def get_truncated_normal(mean=0, sd=1, low=0, upp=10): return truncnorm( (low - mean) / sd, (upp - mean) / sd, loc=mean, scale=sd)

¿Cómo usarlo?

  1. Instale el generador con los parámetros: media , desviación estándar y rango de truncamiento :

    >>> X = get_truncated_normal(mean=8, sd=2, low=1, upp=10)

  2. Luego, puede usar X para generar un valor:

    >>> X.rvs() 6.0491227353928894

  3. O, una matriz numpy con N valores generados:

    >>> X.rvs(10) array([ 7.70231607, 6.7005871 , 7.15203887, 6.06768994, 7.25153472, 5.41384242, 7.75200702, 5.5725888 , 7.38512757, 7.47567455])

Un ejemplo visual

Aquí está la gráfica de tres distribuciones normales truncadas diferentes:

X1 = get_truncated_normal(mean=2, sd=1, low=1, upp=10) X2 = get_truncated_normal(mean=5.5, sd=1, low=1, upp=10) X3 = get_truncated_normal(mean=8, sd=1, low=1, upp=10) import matplotlib.pyplot as plt fig, ax = plt.subplots(3, sharex=True) ax[0].hist(X1.rvs(10000), normed=True) ax[1].hist(X2.rvs(10000), normed=True) ax[2].hist(X3.rvs(10000), normed=True) plt.show()


Si está buscando la distribución normal truncada , SciPy tiene una función llamada truncnorm

La forma estándar de esta distribución es una normal estándar truncada al rango [a, b]. Observe que a y b se definen sobre el dominio de la normal estándar. Para convertir valores de clip para una media específica y desviación estándar, use:

a, b = (myclip_a - my_mean) / my_std, (myclip_b - my_mean) / my_std

truncnorm toma ayb como parámetros de forma.

>>> from scipy.stats import truncnorm >>> truncnorm(a=-2/3., b=2/3., scale=3).rvs(size=10) array([-1.83136675, 0.77599978, -0.01276925, 1.87043384, 1.25024188, 0.59336279, -0.39343176, 1.9449987 , -1.97674358, -0.31944247])

El ejemplo anterior está limitado por -2 y 2 y devuelve 10 variables aleatorias (utilizando el método .rvs() )

>>> min(truncnorm(a=-2/3., b=2/3., scale=3).rvs(size=10000)) -1.9996074381484044 >>> max(truncnorm(a=-2/3., b=2/3., scale=3).rvs(size=10000)) 1.9998486576228549

Aquí hay un diagrama de histograma para -6, 6:


Si solo quieres trabajar con numpy , también puedes hacer algo como esto:

int(np.clip(int(np.random.normal(mean,std)),min_size,max_size)

Esto solo recortará valores cada vez más pequeños a su min y max especificados