¿Cómo obtener una distribución normal dentro de un rango en números?

En la tarea de aprendizaje automático. Debemos 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 cómo hacer eso?

La parametrización de truncnorm es complicada , por lo 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, puedes 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 diferentes distribuciones normales truncadas:

 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() 

introduzca la descripción de la imagen aquí

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 los valores de clip para una media específica y una desviación estándar, use:

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

truncnorm toma a y b 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 (usando 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 gráfico de histogtwig para -6, 6:

introduzca la descripción de la imagen aquí

Además de la sugerencia de @bakkal (+1), también puede querer echar un vistazo a la receta de Vincent Mazet para lograr esto, reescrita como un módulo de piretría por Christoph Lassner .

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 simplemente recortará los valores más pequeños y más grandes a su min y max especificados