Dans cet article, nous allons voir comment obtenir des nombres aléatoires associes à une densité de probabilité quelconque. Pour cela, supposons que nous avons un ensemble de données allant de 0 à 10 réparties suivant une fonction $f: 2*cos(x) + 3$. (Obtenir le code complet de l'exemple ci-dessous: [attachment:382])
from scipy.integrate import quadfrom random import randrangefrom scipy import miscimport numpy as npimport matplotlib.pyplot as plt
Etape 1: Définir la fonction
xmin = 0xmax = 10def f(x):return 2 * np.cos(x) + 3
Tracer la fonction
x1 = np.arange(xmin,xmax,0.1)fig = plt.figure()ax = fig.add_subplot(1,1,1)ax.grid(True)ax.fill_between(x1, 0, f(x1))plt.plot(x1,f(x1))plt.savefig('function.png')plt.show()
Etape 2: Calculer la densité de probabilité (probability density function: pdf) à partir de la fonction f.
global normnorm, err = quad(f, xmin, xmax)print 'norm: ', normy1 = f(x1) / norm
Tracer
fig = plt.figure()ax = fig.add_subplot(1,1,1)ax.grid(True)ax.fill_between(x1, 0, y1)plt.plot(x1,y1)plt.savefig('pdf.png')plt.show()
Etape 3: Calculer la fonction de répartition (cumulative distribution function cdf).
def pdf(x):pdf_x, err = quad(f, 0.0, x)return pdf_xy2 = np.empty(x1.shape[0])for i in range(x1.shape[0]):y2[i] = pdf(x1[i]) / norm
Tracer
fig = plt.figure()ax = fig.add_subplot(1,1,1)ax.grid(True)plt.plot(x1,y2)plt.savefig('cdf.png')plt.show()
Etape 4: Créer une liste de nombres aléatoires associée à la fonction f en utilisant la fonction de repartition "cdf" construite dans l'étape 3.
NbRV = 5000def NewtonsMethod(f, x, tolerance=0.000001):while True:x1 = x - f(x) / misc.derivative(f, x)t = abs(x1 - x)if t < tolerance:breakx = x1return xdef rv(x):pdf_x, err = quad(f, 0.0, x)return pdf_x / norm - rvhRandomValueY_list = []for i in range(NbRV):RandomValueY_list.append(randrange(NbRV)/float(NbRV))global rvhRandomValueX_list = []for i in range(NbRV):rvh = RandomValueY_list[i]RandomValueX_list.append(NewtonsMethod(rv,rvh))
Etape 5: Tester la répartition des nombres aléatoires en construisant un histogramme avec un nombre de classes (NbBin) quelconque (Par exemple 50).

Exemple d'histogramme obtenu avec 2000 points aléatoires et un nombre de classes = 50.
NbBin = 50BinWidth = float( xmax - xmin ) / NbBinh = np.zeros( NbBin )for i in range(NbRV):k = int( RandomValueX_list[i] / BinWidth )#print kh[k] = h[k] + 1x1 = range(NbBin)fig = plt.figure()plt.grid(True)bar1 = plt.bar(x1,h,width=1.0,bottom=0)plt.savefig('rv_histo.png')plt.show()
Références
| Liens | Site |
|---|---|
| wiki article | wikipedia |
| Constructing Random Numbers with an Arbitrary Distribution | av8n |



