Approximation graphique d'une distribution de Poisson à l'aide d'un procédé aléatoire

Denis Hulo

Objectif : approcher graphiquement une distribution de Poisson à l'aide d'un procédé aléatoire et de la bibliothèque Matplotlib.

Niveau requis : confirmé

Commentez cet article : Commentez

- Titre : Approximation graphique d'une distribution de Poisson à l'aide d'un procédé aléatoire

- Auteur : Denis Hulo

- Parution : 4 avril 2025

- Public visé :

- Licence : Copyright ® 2025 Denis Hulo. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Sommaire

- I. Introduction

- II. Loi binomiale

- III. Loi de Poisson

- IV. Simulation d'une variable de Poisson

- V. Implémentation en Python

- V-A. Fonctions utilisées

- V-A-1. Distribution de Poisson

- V-A-2. Générateur d'entiers aléatoires

- V-B. Approximation d'une distribution de Poisson à l'aide d'un procédé aléatoire

- V-B-1. Script Python

- V-B-2. Tests du code

- VI. Conclusion

- VII. Téléchargement

- VIII. Remerciements

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 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 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 est une variable aléatoire dont l'univers image est et que l'on connait , avec , alors l'ensemble des couples est la distribution de probabilité de , aussi appelée loi de probabilité de .

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 :

Représentation graphique de cette loi pour n=120 et p=0.02 :

Loi binomiale

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 :

Où 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 :

Distribution de Poisson

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 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 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 occurrences pour une loi de Poisson de paramètre λ. Elle donne également la proportion de valeurs égales à 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 :

Distribution de Poisson

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 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 :

1. Initialisation des paramètres λ, n et p ;

2. Création de la liste des valeurs en abscisse ;

3. Génération des séquences d'entiers aléatoires et des sommes d'entiers ;

4. 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 :

import numpy as np
import random
import math
from scipy.stats import poisson
import matplotlib.pyplot as plt

print("Approximation d'une distribution de Poisson à l'aide d'un procédé aléatoire :\n")

# 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

print("Nombre d'itérations =", sequences_nb)

print()
print("Espérance attendue, λ =", λ)

print("Nombre d'épreuves indépendantes, n =", n)
print("Probabilité élémentaire, p =", p)

# initialisation des listes de valeurs et de fréquences
x_values = np.arange(n+1) # [0,..., n]
f_values = np.array([0]*(n+1)) # [0, ..., 0]

# 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

# 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
μ = 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..")

# nom et dimensions de la figure contenant le graphique
plt.figure(num="Figure : approcher une distribution de Poisson", figsize=(8, 5), dpi=80)

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

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 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 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 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 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é 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

- Page sur les distributions de probabilité

- Page Wikipédia sur les distributions de probabilité

- Loi binomiale

- Loi de Poisson

- Statistique inférentielle en BTSA - B. Chaput - ENFA - Lois de Poisson

- Processus de Poisson

- Page Wikipédia sur les générateurs de nombres pseudo-aléatoires