Probabilités

15 minutes de Python

Simulations de variables aléatoires continues : la méthode d’inversion

Thème : Probabilités

Niveau : ECG1–ECG2

Année : Maths appliquées, Maths approfondies

Objectif : Savoir simuler une variable aléatoire de fonction de répartition explicite par la méthode d’inversion : à partir d’une variable uniforme U sur [0,1[, construire X tel que \(X=F^{-1}(U)\), puis estimer une espérance ou une probabilité par simulation.

Méthode d’inversion

La méthode d’inversion permet de simuler une variable aléatoire réelle à densité à partir d’une variable uniforme. Dans toute cette page, on se place dans le cadre suivant :

  • \(X\) est une variable aléatoire réelle admettant une densité \(f\) et de fonction de répartition \( F\),
  • la densité \( f \) est nulle en dehors d’un intervalle \(\left]a,b\right[\) (avec \(a\) et \(b\) éventuellement infinis),
  • la fonction de répartition \(F\) est strictement croissante sur \(\left]a,b\right[\).

Fondements mathématiques

Bijection induite par la fonction de répartition

Sur l’intervalle \(\left]a,b\right[\), la fonction de répartition \(F\) est continue et strictement croissante. De plus, \[ \lim_{x\to a^+}F(x)=0 \qquad\text{et}\qquad \lim_{x\to b^-}F(x)=1 \]

Ainsi, l’application \[ G : \left]a,b \right[ \to \left]0,1 \right[, \quad x \mapsto F(x) \] est une bijection. On peut donc définir sa fonction réciproque \[ G^{-1} : \left]0,1\right[ \to \left]a,b\right[ \]

Loi de \(G^{-1}(U)\)

Soit \(U\sim\mathcal{U}(\left]0,1\right[)\) et posons \[ Y = G^{-1}(U) \] Pour tout \(x\in\left]a,b\right[\), comme \(G\) est strictement croissante, on a \begin{align*} Y \le x &\Leftrightarrow\; G^{-1}(U) \le x \\ &\Leftrightarrow\; U \le G(x) \end{align*}

Donc, comme \( G(x) = F(x) \) lorsque \( x \in \left] a,b \right[ \) : \begin{align*} \mathbb{P}(Y\le x) &=\mathbb{P}(U\le G(x)) \\ &=\mathbb{P}(U\le F(x)) \\ &=F(x) \end{align*} car \(U\) est uniforme sur \(\left]0,1\right[\) et \( F(x) \) appartient à \( ]0,1[ \). Ainsi, \(Y\) admet la même fonction de répartition que \(X\), donc elle suit la même loi que \( X\).


Conséquence pour la simulation

Le raisonnement précédent montre que si l’on sait calculer explicitement la fonction réciproque \(G^{-1}\), alors on peut simuler \(X\) de la façon suivante :

  1. on simule une variable uniforme \(U\) sur \(\left]0,1\right[\),
  2. on calcule \(X = G^{-1}(U)\).

C’est exactement le principe de la méthode d’inversion.


Exemple : loi exponentielle

Soit \(X\) une variable aléatoire de loi exponentielle de paramètre \(\lambda>0\). Elle admet une densité nulle en dehors de \(]0,+\infty[\), et sa fonction de répartition vérifie \[ F(x)=\left\{ \begin{array}{ll} 0 & \text{si }x\le 0\\ 1-e^{-\lambda x} & \text{si }x>0 \end{array} \right. \] Sur \(]0,+\infty[\), \(F\) est strictement croissante.

Pour \(u\in\left]0,1\right[\) et \( x \in \left] 0, + \infty \right[ \), on a de plus : \begin{align*} u=1-e^{-\lambda x} &\Leftrightarrow e^{-\lambda x} = 1-u &\\ &\Leftrightarrow x=-\dfrac{1}{\lambda} \, \ln(1-u) \end{align*} Ainsi, si \(U\sim\mathcal{U}(\left]0,1\right[)\), alors \[ X=-\dfrac{1}{\lambda} \, \ln(1-U) \] suit une loi exponentielle de paramètre \(\lambda\) d’après le point précédent et on peut donc simuler une réalisation de \( X\) avec le code suivant :

import numpy as np
import numpy.random as rd

# Paramètre
Lambda = 2.0

# 1) Simulation d'une uniforme sur ]0,1[
U = rd.random(N)

# 2) Inversion : X = G^{-1}(U)
X = -np.log(1 - U) / Lambda

# Renvoie de la valeur
print(X)

Exemple

import numpy as np
import numpy.random as rd

alpha = 3

U = rd.random()

X = 1 / (1 - U)**(1/alpha)

print("U =", U)
print("X =", X)

Explication

On souhaite simuler une variable aléatoire suivant une loi de Pareto de paramètre \(\alpha>0\), définie sur \([1,+\infty[\) par la fonction de répartition :

\(F(x)= \begin{cases} 0 & \text{si } x < 1\\ 1-\dfrac{1}{x^{\alpha}} & \text{si } x \ge 1 \end{cases}\)

Pour \(x \ge 1\), on a donc :

\begin{align*}u = 1 - \dfrac{1}{x^{\alpha}} &\Leftrightarrow\; \dfrac{1}{x^{\alpha}} = 1-u \\ &\Leftrightarrow\; x = \dfrac{1}{(1-u)^{1/\alpha}} \end{align*}

Ainsi, si \(U\) suit la loi uniforme sur \([0,1]\), la variable aléatoire

\(X = \dfrac{1}{(1-U)^{1/\alpha}}\)

suit une loi de Pareto de paramètre \(\alpha\).

Dans le script :

  • U = rd.random() simule une réalisation d’une variable uniforme sur \([0,1]\).
  • X = 1 / (1 - U)**(1/alpha) applique la fonction réciproque \(F^{-1}\).
  • Les deux instructions print affichent la valeur tirée de U et la valeur correspondante de X.

Trois commandes utiles aujourd’hui

Clique sur une carte pour voir l’instruction utile.

X > a
np.sum
plt.hist

Un exercice pour vérifier ta maîtrise

On considère une variable aléatoire \(X\) dont la fonction de répartition \(F\) est définie sur \(\mathbb{R}\) par

\[ \forall x \in \mathbb{R},\ F(x)=\exp(-\exp(-x)) \]

  1. Montrer que \(F\) est une bijection de \(\mathbb{R}\) sur \(\left]0,1\right[\) et déterminer \(F^{-1}\).
  2. Compléter la fonction Python suivante pour que l’appel de Simul_X() renvoie une simulation de \(X\).

Et pour quelques minutes de plus…

Prendre en main la programmation, pas à pas.

Ces exercices sont conçus pour t’aider à maîtriser progressivement la programmation en Python, en partant de la lecture et de la compréhension du code, jusqu’à l’écriture autonome de scripts complets.

L’objectif n’est pas d’aller vite, mais de construire des automatismes solides, en comprenant ce que fait chaque instruction, puis en apprenant à les utiliser par toi-même.

L’ordre des exercices est volontaire : on lit, on comprend, on complète, puis on écrit seul. Prends le temps de chaque étape : c’est la clé pour progresser durablement.

Niveau 1 Analyser un code

Comprendre avant d’écrire.
Dans cette première série, tu observes et analyses des scripts Python déjà écrits. L’objectif est de comprendre la logique du programme, le rôle des variables, des boucles et des conditions, et d’être capable de prévoir ce que le code affiche ou calcule.

Niveau 2 Compléter un code

Écrire, mais avec un cadre.
Ici, tu passes à l’écriture sans partir de zéro. Le squelette du programme est fourni : il te reste à compléter certaines instructions pour que le code fonctionne correctement. Ce format permet de se concentrer sur l’essentiel, sans se perdre dans la structure générale.

Niveau 3 Écrire un code complet

Passer à l’autonomie.
Dans cette dernière série, tu écris un programme complet à partir d’une consigne. Tu dois organiser ton code, choisir les bonnes instructions et construire la logique globale du script. C’est ici que tu mets en pratique tout ce que tu as appris dans les niveaux précédents.

error: Ce contenu est protégé !