I. Introduction▲
Après la distribution normale, on s'intéresse maintenant à la loi de Poisson. On va cette fois montrer comment simuler à l'aide d'un générateur de nombres pseudo-aléatoires une variable aléatoire discrète kitxmlcodeinlinelatexdvpS_{n}finkitxmlcodeinlinelatexdvp suivant une distribution de Poisson. Puis, on va implémenter ce procédé aléatoire en Python afin de vérifier visuellement sur un graphique que la variable kitxmlcodeinlinelatexdvpS_{n}finkitxmlcodeinlinelatexdvp suit approximativement une loi de Poisson sous certaines conditions.
Pour rappel, un exemple simple de variable aléatoire est donné par le résultat de plusieurs lancers d’un dé à six faces, pour lequel les valeurs possibles sont 1 pour un six, 0 pour les autres cas. Un autre exemple est la variable aléatoire qui associe au résultat des jets de n lancers, le nombre de six obtenus.

Distribution de probabilité :
Si kitxmlcodeinlinelatexdvpXfinkitxmlcodeinlinelatexdvp est une variable aléatoire dont l'univers image est kitxmlcodeinlinelatexdvpX(Ω) = \left\{ x_{1},x_{2},\cdots ,x_{n} \right\}finkitxmlcodeinlinelatexdvp et que l'on connait kitxmlcodeinlinelatexdvpp_{1} = P(X=x_{1}),p_{2} = P(X=x_{2}),\cdots , p_{i} = P(X=x_{i}),\cdots , p_{n} = P(X=x_{n})finkitxmlcodeinlinelatexdvp, avec kitxmlcodeinlinelatexdvpp_{1} + p_{2} + \cdots + p_{n} = 1finkitxmlcodeinlinelatexdvp, alors l'ensemble des couples kitxmlcodeinlinelatexdvp\left( x_{i} , p_{i} \right)finkitxmlcodeinlinelatexdvp est la distribution de probabilité de kitxmlcodeinlinelatexdvpXfinkitxmlcodeinlinelatexdvp, aussi appelée loi de probabilité de kitxmlcodeinlinelatexdvpXfinkitxmlcodeinlinelatexdvp.
II. Loi binomiale▲
D'après Wikipédia, la loi binomiale est une loi de probabilité discrète décrite par deux paramètres : n le nombre d'expériences réalisées, et p la probabilité de succès. Pour chaque expérience appelée épreuve de Bernoulli, on utilise une variable aléatoire qui prend la valeur 1 lors d'un succès et la valeur 0 sinon. La variable aléatoire, somme de toutes ces variables aléatoires, compte le nombre de succès et suit une loi binomiale. Il est alors possible d'obtenir la probabilité de k succès dans une répétition de n expériences :
kitxmlcodelatexdvpP\left( X=k \right) = \binom{n}{k} p^{k} \left( 1-p \right)^{n-k}finkitxmlcodelatexdvpReprésentation graphique de cette loi pour n=120 et p=0.02 :
III. Loi de Poisson▲
Une variable aléatoire X suit la loi de Poisson P(λ) de paramètre λ, réel strictement positif, lorsque sa loi de probabilité est définie par :
kitxmlcodelatexdvpp(k)=P\left( X=k \right) = \frac{\lambda^{k}}{k!}e^{-\lambda }finkitxmlcodelatexdvpOù k est un entier naturel, k = 0, 1, 2…
En particulier, une loi binomiale B(n, λ/n) peut être approchée par une loi de Poisson de paramètre λ si n est grand.
Exemple simple de mise en œuvre de cette loi de Poisson :
Dans une entreprise, une étude statistique a montré qu'en moyenne 2 % des articles d'une chaîne de fabrication présentent des défauts. Lors d'un contrôle de qualité, on envisage de prélever un échantillon de 120 articles. Bien que ce prélèvement soit exhaustif (sans remise), on considère que la production est suffisamment importante pour que l'on puisse assimiler cette épreuve à un tirage avec remise et que la probabilité qu'un article prélevé soit défectueux est constante.
On reconnaît ici une suite de n=120 épreuves indépendantes avec pour chaque expérience une probabilité élémentaire p=0.02 d'avoir un article défectueux.
La variable aléatoire X donnant le nombre d'articles défectueux d'un tel échantillon suit donc une loi binomiale B(n,p) qui peut être approchée par une loi de Poisson de paramètre λ=np :
Les lois de Poisson interviennent dans la modélisation de phénomènes aléatoires où le futur est indépendant du passé (pannes de machines, sinistres, appels téléphoniques à un standard, files d'attente, mortalité, temps de guérison de petites blessures, stocks, nombre d'étoiles filantes dans le ciel d'été…)
* Extrait de Statistique inférentielle en BTSA - B. Chaput - ENFA - Lois de Poisson
Le nombre Nt d'occurrences dans un intervalle de longueur t suit ainsi une loi de Poisson d'intensité λt :
quel que soit l'entier naturel k (à la différence de la loi binomiale où k est compris entre 0 et n).
Le processus de Poisson peut ainsi être représenté par le schéma :

IV. Simulation d'une variable de Poisson▲
Reprenons notre exemple indiquant que dans une chaîne de fabrication en moyenne 2 % des articles présentent des défauts.
La fabrication de n=120 articles peut alors être modélisé par n tirages successifs d'entiers compris entre 0 et 1 (0 : conforme, 1 : défectueux), chaque entier ayant un poids (0 : 0.98, 1 : 0.02). La variable somme kitxmlcodeinlinelatexdvpS_{n}finkitxmlcodeinlinelatexdvp représente alors le nombre d'articles défectueux dans une suite de n épreuves indépendantes et suit donc une loi binomiale B(n,p) qui peut être approchée par une loi de Poisson de paramètre λ=np.
Par la suite, on va utiliser un générateur de nombres pseudo-aléatoires pour simuler ces tirages successifs. Ces suites de nombres sont en fait générées à l'aide d'un algorithme dit déterministe et sont au moins en partie prévisibles. C'est pourquoi on parle de nombres pseudo-aléatoires.
Si maintenant on réitère un grand nombre de fois ces n tirages d'entiers consécutifs, on peut donc s'attendre à ce que la variable kitxmlcodeinlinelatexdvpS_{n}finkitxmlcodeinlinelatexdvp suive approximativement une distribution de Poisson :
On va ensuite effectuer des tests en fixant le paramètre λ et en faisant varier le nombre d'itérations.
V. Implémentation en Python▲
V-A. Fonctions utilisées▲
V-A-1. Distribution de Poisson▲
L'objet poisson du module scipy.stats représente une variable aléatoire discrète suivant une loi de Poisson qui est en fait une instance de la classe rv_discrete avec ses différentes méthodes.
La fonction de masse de la loi de Poisson poisson.pmf(x, loc=λ) d'espérance λ peut être invoquée comme ceci :
xi =
10
; λ =
2.4
val =
poisson.pmf
(
xi, loc=
λ)
La fonction de masse donne la probabilité d'avoir exactement kitxmlcodeinlinelatexdvpx_{i}finkitxmlcodeinlinelatexdvp occurrences pour une loi de Poisson de paramètre λ. Elle donne également la proportion de valeurs égales à kitxmlcodeinlinelatexdvpx_{i}finkitxmlcodeinlinelatexdvp pour cette distribution de Poisson.
Traçons maintenant la courbe représentative de la distribution de Poisson pour une série de valeurs et à l'aide de la bibliothèque Matplotlib :
from
scipy.stats import
poisson
import
matplotlib.pyplot as
plt
import
numpy as
np
# nombre d'épreuves indépendantes
n =
120
# probabilité de succès
p =
0.02
# espérance λ
λ =
n*
p
# génère la séquence des x : 0 -> n
x =
np.arange
(
0
, n+
1
)
# nom et dimensions de la figure contenant le graphique
plt.figure
(
num=
"Figure : Loi de Poisson"
, figsize=(
8
, 5
), dpi=
80
)
# trace le graphique représentant la distribution de Poisson
plt.bar
(
x, poisson.pmf
(
x,λ), color=
"teal"
, width =
0.2
, align=
'center'
)
# limites sur l'axe des x : [-0.5, 4λ]
plt.xlim
(-
0.5
, 4
*
λ)
# limites sur l'axe des y
plt.ylim
(
0
, 0.30
)
plt.title
(
"Distribution de Poisson de paramètre λ={0}"
.format
(
λ))
# affiche le graphique
plt.show
(
)
Le code affiche :
V-A-2. Générateur d'entiers aléatoires▲
La fonction choices(population, weights, k) du module random renvoie une séquence de k éléments tirés au hasard dans population suivant leur poids.
La fonction choices peut être invoquée comme ceci :
import
numpy as
np
# tirage avec remise de 10 entiers choisis entre 0 et 1 en fonction des poids de ces 2 entiers
seq =
np.choices
(
population=
[0
,1
], weights=
[0.02
, 0.98
], k=
10
)
Les modules random et numpy de Python utilisent l'algorithme de Mersenne Twister comme générateur de nombre pseudo-aléatoires.
V-B. Approximation d'une distribution de Poisson à l'aide d'un procédé aléatoire▲
V-B-1. Script Python▲
L'objectif va être maintenant de générer un graphique en Python permettant de montrer que la variable somme kitxmlcodeinlinelatexdvpS_{n}finkitxmlcodeinlinelatexdvp suit approximativement une loi de Poisson quand n est suffisamment grand. Pour cela, on va d'abord décrire les différentes parties du code mises en œuvre :
- Initialisation des paramètres λ, n et p ;
- Création de la liste des valeurs en abscisse ;
- Génération des séquences d'entiers aléatoires et des sommes d'entiers ;
- Traçage du graphique représentant la distribution de Poisson et les fréquences d'apparition de chaque valeur de x.
Reprenons maintenant plus en détail ces différents points :
1. Initialisation des paramètres λ, n et p :
# nombre de séquences de bits ou nombre d'itérations
sequences_nb =
100000
# espérance de la loi de Poisson
λ =
2.4
# taille des séquences : nombre d'épreuves indépendantes
n =
120
# probabilité élémentaire
p =
λ/
n
2. Création de la liste des valeurs en abscisse, et initialisation du tableau des valeurs en ordonnée :
# initialisation des listes de valeurs et de fréquences
x_values =
np.arange
(
0
, n+
1
) # [0,..., n]
f_values =
np.array
(
[0
]*(
n+
1
)) # [0, ..., 0]
3. Génération des séquences d'entiers aléatoires et des sommes d'entiers aléatoires :
# initialisation du générateur aléatoire
random.seed
(
)
# génération des séquences d'entiers aléatoires et des sommes d'entiers aléatoires
for
i in
range(
sequences_nb):
# tirage aléatoire d'une séquence de n entiers compris entre 0 et 1, puis réalisation de la somme des entiers obtenus
x_value =
sum(
random.choices
(
population=
[0
, 1
], weights=
[1
-
p, p], k=
n))
# incrémentation du compteur de la valeur d'indice x_value dans la liste f_values
f_values[x_value] +=
1
4. Traçage du graphique représentant la distribution de Poisson et les fréquences d'apparition de chaque valeur :
# calcul de la borne supérieure (en abscisse) en fonction du paramètre λ de la distribution de Poisson: [0, high_value]
high_value =
round(
4
*
λ)
# calcul de la moyenne des valeurs en tenant compte de leur poids et de la fenêtre des valeurs
m =
np.average
(
x_values[0
:high_value+
1
], weights=
f_values[0
:high_value+
1
])
print
(
)
print
(
"Moyenne observée, μ ="
, μ)
# division des effectifs par le nombre de séquences
f_values =
f_values/
sequences_nb
print
(
)
print
(
"Génération du graphique.."
)
## génération du diagramme en bâtons représentant la distribution de Poisson de paramètre λ
plt.bar
(
x_values-
0.1
, poisson.pmf
(
x_values, λ), color=
"teal"
, label=
'P(X=k), loi de Poisson de paramètre λ={0}'
.format
(
λ), width =
0.2
, align=
'center'
)
# génération du diagramme en bâtons représentant les fréquences obtenues par valeur
plt.bar
(
x_values+
0.1
, f_values, color=
"red"
, label=
'fréquences observées'
, width =
0.2
, align=
'center'
)
# limites sur l'axe des x : [-0.5, 4λ]
plt.xlim
(-
0.5
, 4
*
λ)
# limites sur l'axe des y : [0, 0.3]
plt.ylim
(
0
, 0.3
)
# Ajout de la légende
plt.legend
(
)
plt.title
(
"Distribution de la variable Sn pour {0} itérations"
.format
(
sequences_nb))
# affichage du graphique
plt.show
(
)
Code complet :
Les tableaux d'entiers aléatoires sont donc générés avec l'instruction random.choices(population=[0, 1], weights=[1-p, p], k=n).
Comme précisé plus haut, chaque séquence d'entiers aléatoires peut donc être associée à une variable somme kitxmlcodeinlinelatexdvpS_{n}finkitxmlcodeinlinelatexdvp distribuée approximativement suivant une loi de Poisson de paramètre λ=np.
V-B-2. Tests du code▲
On va maintenant tester ce code en fixant les paramètres λ et n, mais en faisant varier le nombre d'itérations.
Test n°1
L'exécution du code affiche pour 10 000 itérations :
Approximation d'une distribution de Poisson à l'aide d'un procédé aléatoire :
Nombre d'itérations = 10000
Espérance attendue, λ = 2.4
Nombre d'épreuves indépendantes, n = 120
Probabilité élémentaire, p = 0.02
Moyenne observée, μ = 2.407
Génération du graphique..
Le graphique montre que les barres des fréquences (en rouge) sont déjà assez proches de celles représentant la distribution de Poisson (en vert).
Test n°2
L'exécution du code affiche pour 100 000 itérations :
Approximation d'une distribution de Poisson à l'aide d'un procédé aléatoire :
Nombre d'itérations = 100000
Espérance attendue, λ = 2.4
Nombre d'épreuves indépendantes, n = 120
Probabilité élémentaire, p = 0.02
Moyenne observée, μ = 2.4033022641811344
Génération du graphique..
Le graphique montre que les barres des fréquences obtenues (en rouge) sont cette fois très proches de celles représentant la distribution de Poisson (en vert). La convergence de kitxmlcodeinlinelatexdvpS_{n}finkitxmlcodeinlinelatexdvp vers une variable de Poisson se confirme donc bien.
Libre à chacun ensuite de vérifier cette tendance en effectuant des tests avec d'autres valeurs de n. On pourra également constater que si les conditions d'approximation ne sont pas respectées, dans le cas où λ/n est supérieure à 0.1, la variable kitxmlcodeinlinelatexdvpS_{n}finkitxmlcodeinlinelatexdvp suit alors une loi normale.
VI. Conclusion▲
Après avoir présenté la distribution de Poisson, on a pu montrer comment simuler une variable de Poisson à l'aide d'un générateur de nombres pseudo-aléatoires. Puis, on a su implémenter ce procédé aléatoire en Python afin de vérifier sur un graphique que la variable kitxmlcodeinlinelatexdvpS_{n}finkitxmlcodeinlinelatexdvp suivait approximativement une loi de Poisson sous certaines conditions.
Ce code nous aura donc permis de simuler des variables aléatoires à l'aide d'un algorithme dit déterministe. En effet, même si le hasard est lui par nature imprévisible, ces algorithmes restent pour le moment plus simples à mettre en œuvre et plus efficaces que les générateurs de nombres aléatoires classiques.
VII. Téléchargement▲
Le fichier compresséfichier de test contenant le module Python pour effectuer les différents tests.
VIII. Remerciements▲
Je tiens à remercier Laurent Ott pour ses différentes suggestions, ainsi que f-leb pour sa relecture.
Sources