2016-04-27 3 views
12

In der maschinellen Lernaufgabe. Wir sollten eine Gruppe von zufälligen Normalverteilung mit gebunden erhalten. Wir können eine normale Verteilungsnummer mit np.random.normal() bekommen, aber es bietet keine gebundenen Parameter an. Ich möchte wissen, wie das geht? Wie bekomme ich eine normale Verteilung innerhalb eines Bereichs in numpy?

+4

Shouldn‘ t Stichproben von normalerweise verteilte Daten per Definition unbegrenzt sein? – Tom

Antwort

8

Wenn Sie die Truncated normal distribution suchen, hat SciPy eine Funktion für sie truncnorm

Die Standardform dieser Verteilung bezeichnet, ist ein Standard-Normal verkürzten auf den Bereich [a, b] - Beachten Sie, dass a und b sind über die Domäne der Standardnormalen definiert. Um Clip-Werte für einen bestimmten Mittelwert wandeln und Standardabweichung, zu verwenden:

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

truncnorm nimmt a und b als Formparameter .

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

Das obige Beispiel ist mit -2 begrenzt und 2 und gibt 10 Zufallszahl (unter Verwendung der Methode .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 

Hier ist ein Histogramm-Diagramm für -6, 6:

enter image description here

+0

Warum truncnorm nicht verwendet wird (a = -2, b = 2, scale = 1) – maple

+2

Nur um klarzustellen, dass a und b Formparameter sind, könnte ein Leser -2, 2 mit einer anderen Skala als 1 versuchen , und dann erhalten Sie zufällige Werte außerhalb [-2, 2] – bakkal

12

Die Parametrisierung von truncnorm ist kompliziert, so ist hier eine Funktion, die die Parametrisierung auf etwas intuitivere übersetzt:

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) 


Wie es zu benutzen?

  1. Instanz der Generator mit den Parametern: bedeuten, Standardabweichung und Verkürzungsbereich:

    >>> X = get_truncated_normal(mean=8, sd=2, low=1, upp=10) 
    
  2. Dann können Sie X verwenden, um einen Wert zu erzeugen:

    >>> X.rvs() 
    6.0491227353928894 
    
  3. Oder ein numpy a rray mit N erzeugten Werte:

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

als Anschauungsbeispiel

Hier ist die Handlung von drei verschiedenen abgeschnittene Normalverteilungen:

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

enter image description here

+1

Fantastische Antwort, danke! – Gabriel

+0

+1. Es ist jedoch zu beachten, dass die Funktion viel schneller wird, wenn 'get_truncated_normal.rvs()' sofort innerhalb der Funktion verwendet wird, anstatt sie außerhalb aufzurufen. Natürlich hilft das nur, wenn Sie zufällige Draws haben wollen –

Verwandte Themen