Revenir
Revenir

Algorithmique et programmation

Dans cette activité, les variables aléatoires seront représentées à l'aide de deux listes Python : la...

Sommaire

Activité CAPYTALE : simulation d'un échantillon de variables aléatoiresReprésentation d'une variable aléatoire
Simulation d'une variable aléatoire suivant une loi donnéeIllustration sur un exemplePython et les flottantsAlgorithme général
Espérance, variance et écart-typeCalcul de l'espérance, de la variance et de l'écart-type
Échantillon de variables aléatoiresSimulation d'un échantillonComparaison avec l'espéranceUtilisation de l'écart-type

Activité CAPYTALE : simulation d'un échantillon de variables aléatoires

Représentation d'une variable aléatoire

Dans cette activité, les variables aléatoires seront représentées à l'aide de deux listes Python : la première donnera les valeurs prises par la variable aléatoire et la seconde indiquera les probabilités correspondantes.
Par exemple, la variable aléatoire 
X
dont la loi est la suivante
k−1237P(X=k)0,10,20,30,4\begin{array}{|c|c|c|c|c|}\hline k&-1&2&3&7\\ \hline P(X=k) & 0,1 & 0,2 & 0,3 & 0,4 \\ \hline \end{array}kP(X=k)​−10,1​20,2​30,3​70,4​​
sera représentée à l'aide des listes : 
valeurs = [-1, 2, 3, 7]
proba = [0.1, 0.2, 0.3, 0.4]

Simulation d'une variable aléatoire suivant une loi donnée

Illustration sur un exemple

On rappelle que, en Python, la fonctionrandomdu module random permet de générer un nombre aléatoire dans l'intervalle [0 ; 1].
from random import random
random()
Reprenons la variable aléatoire donnée en exemple.
k−1237P(X=k)0,10,20,30,4\begin{array}{|c|c|c|c|c|}\hline k&-1&2&3&7\\ \hline P(X=k) & 0,1 & 0,2 & 0,3 & 0,4 \\ \hline \end{array}kP(X=k)​−10,1​20,2​30,3​70,4​​
On génère un nombre aléatoire entre 0 et 1.
Selon la valeur de ce nombre, on renverra alors l'une des valeurs que peut prendre la variable
XXX
.
  • Si ce nombre au hasard est entre 0 et 0,1, on renvoie la première valeur, à savoir -1 ;
  • si ce nombre est entre 0,1 et0,1 + 0,2,on renvoie la deuxième valeur, à savoir 2 ;
  • si ce nombre au hasard est entre0,1 + 0,2et0,1 + 0,2 + 0,3, on renvoie la troisième valeur, à savoir 3 ;
  • sinon, on renvoie la dernière valeur, à savoir 7.

Python et les flottants

En Python, les nombres « à virgule » utilisés sont appelés flottants.
Les calculs sur ces nombres ne sont pas effectués en base 10 comme nous le faisons mais en base 2 ou binaire. Cette méthode de calcul propre à l'informatique peut mener à diverses erreurs d'approximation.
Par exemple, si vous essayez de calculer 0,1 + 0,2 en utilisant Python, celui-ci vous répondra 0,30000000000000004.
En raison de ces erreurs, il est en général très mauvais de tester une égalité sur des nombres flottants en Python. Toutefois, dans le cadre de ce TP, l'erreur que nous ferons pour effectuer notre simulation sera négligeable et nous n'en tiendrons pas compte.

Algorithme général

Notons x = [x0, x1, ..., xk] la liste des valeurs prises par la variable aléatoire 
XXX
et p = [p0, p1, ..., pk] la liste des probabilités correspondantes.
Pour simuler une variable aléatoire suivant une loi donnée, on procède comme suit .
1.On génère à l'aide de Python un nombre au hasard dans l'intervalle [0;1]. Ce nombre est ensuite stocké dans une variablenb.
2.On initialise une variableià 0.
3.On initialise une variablep_totaleà 0.
4.Tant que la valeur dep_totaleest inférieure ànb:
  • on ajoute p[i] à la valeur de la variable p_totale ;
  • on ajoute 1 à la valeur de i ;
  • on renvoie la valeur de x[i-1].
Exercice
1.En suivant l'algorithme donné ci-dessus, compléter la fonctionsimulation(x, p)qui permet de simuler une variable aléatoire dont la loi est donnée par les listesxetp.
from random import random
def simulation(x, p):
    nb = random()
    i = ...
    p_totale = ...
    while ... :
        p_totale = ...
        i = ...
    return ...
2.En utilisant la fonction précédemment implémentée, simuler la réalisation d'une variable aléatoire suivant la loi suivante.
k−1237P(X=k)0,10,20,30,4\begin{array}{|c|c|c|c|c|}\hline k&-1&2&3&7\\ \hline P(X=k) & 0,1 & 0,2 & 0,3 & 0,4 \\ \hline \end{array}kP(X=k)​−10,1​20,2​30,3​70,4​​

Espérance, variance et écart-type

Calcul de l'espérance, de la variance et de l'écart-type

Rappel
Soit \(X\) une variable aléatoire réelle qui prend les valeurs 
x1x_1x1​
, 
x2x_2x2​
, ..., 
xkx_kxk​
. 
L'espérance de 
XXX
 est alors : 
E(X)=x1P(X=x1)+x2P(X=x2)+⋯+xkP(X=xk)E(X) = x_1P(X=x_1)+x_2P(X=x_2) + \dots + x_k P(X=x_k)E(X)=x1​P(X=x1​)+x2​P(X=x2​)+⋯+xk​P(X=xk​)
.
Sa variance vaut alors
V(X)=E[(X−E(X))2]V(X)=E[(X-E(X))^2]V(X)=E[(X−E(X))2]
 et son écart-type vaut
σ(X)=V(X)\sigma(X)=\sqrt{V(X)}σ(X)=V(X)​
.
Exercice
1.Expliquer pourquoi les fonctions suivantes permettent bien de calculer respectivement l'espérance, la variance et l'écart-type d'une variable aléatoire dont la loi estdonnée par les listesxetpen argument.
from math import sqrt
def esperance(x, p):
    e = 0
    for i in range(len(x)) :
        e = e + x[i] * p[i]
    return e
def variance(x, p):
    e = esperance(x, p)
    x_var = [(x_k - e)**2 for x_k in x]
    v = esperance(x_var, p)
    return v
def ecart_type(x, p):
    v = variance(x, p)
    return sqrt(v)
2.À l'aide des fonctions précédentes, déterminer
E(X)E(X)E(X)
, 
V(X)V(X)V(X)
(ne pas oublier ici que Python commet des erreurs d'approximation !) ainsi qu'une valeur approchée de 
σ(X)\sigma(X)σ(X)
à 
10−210^{-2}10−2
près lorsque 
XXX
est une variable aléatoire dont la loi est donnée ci-dessous.
k−1237P(X=k)0,10,20,30,4\begin{array}{|c|c|c|c|c|}\hline k&-1&2&3&7\\ \hline P(X=k) & 0,1 & 0,2 & 0,3 & 0,4 \\ \hline \end{array}kP(X=k)​−10,1​20,2​30,3​70,4​​

Échantillon de variables aléatoires

Simulation d'un échantillon

On considère une variable aléatoire réelle 
XXX
dont la loi est représentée en Python à l'aide de deux listes x et p.
On simule alors 
N
 échantillons de taille n de cette variable aléatoire et on stocke les résultats de cette simulation dans une liste de listes à l'aide de la fonction suivante.
def simulation_multiple(x, p, N, n):
    return [[simulation(x,p) for i in range(n)] for i in range(N)]
Par exemple, la commande simulation_multiple([-1,2,3,7], [0.1, 0.2, 0.3, 0.4], 20, 10) permet de simuler 20 échantillons de taille 10 de la variable aléatoire 
XXX
dont la loi est donnée ci-dessous.
k−1237P(X=k)0,10,20,30,4\begin{array}{|c|c|c|c|c|}\hline k&-1&2&3&7\\ \hline P(X=k) & 0,1 & 0,2 & 0,3 & 0,4 \\ \hline \end{array}kP(X=k)​−10,1​20,2​30,3​70,4​​
resultat = simulation_multiple([-1,2,3,7], [0.1, 0.2, 0.3, 0.4], 20, 10)
# Affichage des résultats du premier échantillon
print("Premier échantillon : ", resultat[0])
# Affichage des résultats du cinquième échantillon
print("Cinquième échantillon : ", resultat[4])
>>> Premier échantillon : [3, 2, 3, 3, 2, 7, -1, -1, -1, 7]
>>> Cinquième échantillon : [7, 3, 7, 7, 3, 7, 3, 7, 7, 3]

Comparaison avec l'espérance

Pour chaque échantillon, on va calculer la valeur moyennes des
nnn
réalisations de la variable aléatoire puis on les comparera avec la valeur de l'espérance de la variable aléatoire.
Exercice 
Compléter la fonctionmoyenneci-dessous qui prend en entrée une liste de nombres et renvoie la valeur moyenne de cette liste.
On rappelle que le nombre d'éléments d'une liste peut être obtenu à l'aide de la fonctionlenen Python.
def moyenne(liste):
    total = ...
    for elt in liste :
        total = ...
    moyenne = total / ...
    return moyenne
Le programme suivant permet de réaliser la simulation de 10 000 échantillons de taille 1 000 de la variable aléatoire
XXX
, puis de calculer la moyenne des résultats pour chaque échantillon.
L'histogramme des résultats est alors représenté et la valeur de l'espérance est symbolisée par une droite en pointillés.
import matplotlib.pyplot as plt
valeurs = [-1,2,3,7]
proba = [0.1, 0.2, 0.3, 0.4]
resultat = simulation_multiple(valeurs, proba, 1000, 100)
moy = [moyenne(L) for L in resultat]
e = esperance(valeurs, proba)
plt.title("Histogramme des moyennes")
plt.xlabel("Moyennes")
plt.ylabel("Quantités")
# On trace l'histogramme
data = plt.hist(moy, bins = 20)
plt.plot([e, e], [0,max(data[0])], 'r--', lw=2)
plt.show()
plt.close()

Utilisation de l'écart-type

On s'intéresse désormais à la proportion des échantillons pour lesquels l'écart par rapport à l'espérance est inférieur à un, deux ou trois écarts-types.
Exercice 
Soit 
XXX
une variable aléatoire réelle non constante et
(X1,X2,…,Xn)(X_1, X_2, \ldots, X_n)(X1​,X2​,…,Xn​)
 un échantillon de variables aléatoires de même loique
XXX
. On note 
Mn=X1+X2+⋯+XnnM_n=\dfrac{X_1+X_2+\dots + X_n}{n}Mn​=nX1​+X2​+⋯+Xn​​
.
1.À l'aide de l'inégalité de concentration, minorer les probabilités suivantes :
P(∣Mn−E(X)∣<2σ(X)n)P\left(|M_n-E(X)| < \dfrac{2\sigma(X)}{\sqrt{n}}\right)P(∣Mn​−E(X)∣<n​2σ(X)​)
P(∣Mn−E(X)∣<3σ(X)n)P\left(|M_n-E(X)| < \dfrac{3\sigma(X)}{\sqrt{n}}\right)P(∣Mn​−E(X)∣<n​3σ(X)​)
2. Compléter la fonction suivante qui prend en entrée deux listes 
x
 et 
p
 correspondant à une variable aléatoire
XXX
, un entier 
N
 correspondant au nombre d'échantillons à simuler et 
n
 la taille de ces échantillons.
Cette fonction devra renvoyer la proportion des échantillons pour lesquels l'écart entre la valeur moyenne et l'espérance est inférieure à 2 écarts-types divisés par
n\sqrt{n}n​
.
def proportion(x, p, N, n):
    total = 0
    simu = simulation_multiple(x, p, N, n)
    e = esperance(x, p)
    s = ecart_type(x, p)
    for sim in simu :
        if abs(...) <= ... :
            total = ...
    return ...
valeurs = [-1,2,3,7]
proba = [0.1, 0.2, 0.3, 0.4]
print(proportion(valeurs, proba, 1000, 100))
3. En modifiant les valeurs prises par la variable aléatoire 
XXX
et les probabilités correspondantes, vérifier que la borne fournie pas l'inégalité de concentration est loin d'être optimale.