Algorithme : espérance et variance d'une loi
Énoncé
On code la loi d'une variable aléatoire par deux listes Python de même longueur : `valeurs` et `probas`.
```python
def esperance(valeurs, probas):
E = 0
for i in range(len(valeurs)):
E = E + valeurs[i] * probas[i]
return E
def variance(valeurs, probas):
E = esperance(valeurs, probas)
V = 0
for i in range(len(valeurs)):
ecart = valeurs[i] - E
V = V + ...
return V
```
a) Expliquer ce que calcule la fonction `esperance`, en lien avec la définition du cours.
b) Compléter la ligne `V = V + ...` pour que `variance` renvoie V(X).
c) Calculer à la main ce que renvoient `esperance([0, 1, 2], [0.3, 0.5, 0.2])` et `variance([0, 1, 2], [0.3, 0.5, 0.2])`.
d) Python affiche `0.49000000000000005` pour la variance. Est-ce une erreur ?
e) Écrire une fonction `ecart_type(valeurs, probas)` qui renvoie σ(X).
Indice : Reprends la définition V(X) = Σ (xᵢ - E(X))² × P(X = xᵢ) : la variable `ecart` contient xᵢ - E(X).
Correction
- Étape 1 : Un algorithme de calcul d'espérance ou de variance n'invente rien : il traduit mot pour mot la définition du cours. Lire le programme, c'est retrouver la formule ; le compléter, c'est l'écrire.
Les définitions :
E(X) = Σᵢ xᵢ × P(X = xᵢ) V(X) = Σᵢ (xᵢ - E(X))² × P(X = xᵢ)
👉 Une somme se programme toujours de la même façon : une variable mise à 0, puis une boucle qui lui ajoute un terme à chaque tour.
- Étape 2 : a) « E » commence à 0. À chaque tour de boucle, d'indice « i », on lui ajoute « valeurs[i] * probas[i] », c'est-à-dire xᵢ × P(X = xᵢ). Après le dernier tour, « E » contient la somme de tous ces produits : c'est l'espérance, moyenne des valeurs pondérée par leurs probabilités.
- Étape 3 : b) Le terme à ajouter est (xᵢ - E(X))² × P(X = xᵢ). Comme « ecart » contient déjà xᵢ - E(X), on complète la ligne par
« V = V + pow(ecart, 2) * probas[i] »
où « pow(ecart, 2) » est le carré de l'écart.
L'appel « esperance(valeurs, probas) » en tête de la fonction est indispensable : la variance se calcule autour de l'espérance, qu'il faut donc connaître avant la boucle.
- Étape 4 : c) L'espérance : 0 × 0,3 + 1 × 0,5 + 2 × 0,2 = 0,9.
La variance, terme par terme, avec E = 0,9 :
(0 - 0,9)² × 0,3 = 0,81 × 0,3 = 0,243
(1 - 0,9)² × 0,5 = 0,01 × 0,5 = 0,005
(2 - 0,9)² × 0,2 = 1,21 × 0,2 = 0,242
V = 0,243 + 0,005 + 0,242 = 0,49
Contrôle par König-Huygens : E(X²) = 0,5 + 0,8 = 1,3, et 1,3 - 0,9² = 0,49 ✓
E(X) = 0,9 ; V(X) = 0,49
- Étape 5 : d) Ce n'est pas une erreur de la fonction. La machine calcule avec des nombres à virgule approchés : 0,3 ou 0,9 n'ont pas d'écriture exacte dans sa mémoire, et de minuscules arrondis s'accumulent. Le résultat est 0,49 à 10⁻¹⁶ près ; on l'arrondit à l'affichage.
e) L'écart type est la racine carrée de la variance : après « from math import sqrt », la fonction « ecart_type(valeurs, probas) » n'a qu'une ligne,
« return sqrt(variance(valeurs, probas)) »
Ici, σ(X) = √(0,49) = 0,7.
- Étape 6 : L'erreur classique :
Écrire « V = V + ecart * probas[i] », sans élever l'écart au carré. On calcule alors Σ (xᵢ - E) pᵢ, qui vaut toujours 0 — les écarts positifs et négatifs se compensent exactement. Une fonction « variance » qui renvoie 0 pour une variable qui varie doit alerter.
À retenir :
Une somme se programme par une variable initialisée à 0 et une boucle qui lui ajoute un terme. Pour la variance : calculer d'abord l'espérance, puis sommer les carrés des écarts pondérés par les probabilités.