8.4. Probabilités¶
8.4.1. Statistiques¶
Le calcul de la moyenne est on ne peut plus simple : il s’agit de la somme des éléments de la liste divisée par le nombre d’éléments de cette liste [1]. De manière plus formmelle, la moyenne \(m\) d’une liste \((x_1,\dots,x_n)\) de nombres est
In [1]: def moyenne(liste):
...: somme = 0
...: for el in liste:
...: somme += el
...: return somme / len(liste)
...:
In [2]: moyenne([1, 2, 3])
Out[2]: 2.0
On peut donner deux expressions de la variance \(v\) d’une liste \((x_1,\dots,x_n)\) de nombres dont on dispose déjà de la moyenne \(m\).
En utilisant la première expression, on peut par exemple donner cette fonction de calcul de la variance [2].
In [3]: def variance(liste):
...: s1, s2 = 0, 0
...: n = len(liste)
...: for el in liste:
...: s1 += el
...: s2 += el * el
...: return s2 / n - (s1 / n) ** 2
...:
In [4]: variance([1, 2, 3])
Out[4]: 0.666666666666667
On peut également utiliser une des fonctions de calcul de moyenne définies précédemment.
In [5]: variance = lambda liste: moyenne([el ** 2 for el in liste]) - moyenne(liste) ** 2
In [6]: variance([1, 2, 3])
Out[6]: 0.666666666666667
Si l’on préfère, on peut également utiliser la deuxième expression de la variance.
In [7]: def variance(liste):
...: m = moyenne(liste)
...: return moyenne([(el - m) ** 2 for el in liste])
...:
In [8]: variance([1, 2, 3])
Out[8]: 0.6666666666666666
8.4.2. Simuler une variable aléatoire¶
Dans la suite, on fera appel à la fonction random
du module random
qui renvoie un flottant tiré aléatoirement dans l’intervalle \([0,1[\).
In [9]: from random import random
In [10]: [random() for _ in range(10)]
Out[10]:
[0.5482426686157745,
0.026431151841090794,
0.25126388990526305,
0.30600886835596897,
0.5612372655336763,
0.10168486062819282,
0.4874913243778479,
0.6872614645961589,
0.9751794225826002,
0.6645486996202976]
Cela nous permettra de simuler des variables aléatoires connaissant leurs lois [3].
8.4.2.1. Variables aléatoires finies¶
On cherche dans un premier temps à simuler une variable aléatoire \(X\) à valeurs dans un ensemble fini, disons \(\{0,\dots,n-1\}\) où \(n\in\mathbb{N}^*\), dont on connaît la loi, c’est-à-dire les valeurs de \(\mathbb{P}(X=k)\) pour \(k\in\{0,\dots,n-1\}\).
On construit pour cela une fonction prenant pour argument la loi d’une telle variable aléatoire sous la forme d’une liste de réels positifs de somme 1.
In [11]: def simul(loi):
....: proba = random()
....: s = 0
....: for i, p in enumerate(loi):
....: s += p
....: if proba < s:
....: return i
....:
In [12]: [simul([.3, .5, .2]) for _ in range(20)]
Out[12]: [0, 1, 0, 1, 0, 1, 1, 1, 2, 2, 0, 0, 2, 1, 1, 0, 1, 1, 0, 2]
On pourrait par exemple utiliser la méthode précédente pour simuler une loi binomiale.
In [13]: from scipy.special import binom
In [14]: binomiale = lambda n,p: simul([binom(n, k) * p**k * (1-p)**(n-k) for k in range(n+1)])
In [15]: [binomiale(5, .8) for _ in range(20)]
Out[15]: [3, 5, 3, 5, 5, 5, 4, 3, 4, 4, 4, 3, 4, 3, 4, 4, 5, 4, 4, 5]
In [16]: [binomiale(5, .2) for _ in range(20)]
Out[16]: [0, 0, 2, 2, 2, 2, 1, 0, 0, 0, 3, 1, 1, 2, 1, 2, 0, 0, 1, 1]
Evidemment, il existe un méthode plus simple pour simuler une variable suivant une loi binomiale puisque l’on sait qu’elle est de même loi qu’une somme de variables de Bernoulli indépendantes.
In [17]: def bernoulli(p):
....: return 1 if random() < p else 0
....:
In [18]: def binomiale(n, p):
....: return sum(bernoulli(p) for _ in range(n))
....:
In [19]: [binomiale(5, .8) for _ in range(20)]
Out[19]: [4, 5, 4, 3, 4, 4, 1, 3, 2, 4, 5, 4, 4, 3, 4, 4, 3, 3, 4, 4]
In [20]: [binomiale(5, .2) for _ in range(20)]
Out[20]: [1, 1, 1, 0, 1, 1, 1, 2, 1, 0, 1, 0, 1, 2, 1, 2, 0, 1, 0, 1]
8.4.2.2. Variables aléatoires dénombrables¶
On désire maintenant simuler une variable aléatoire \(X\) à valeurs dans un ensemble dénombrable, disons \(\mathbb{N}\), dont on connaît la loi, c’est-à-dire les valeurs de \(\mathbb{P}(X=k)\) pour \(k\in\mathbb{N}\).
La loi de cette variable aléatoire ne peut alors plus être représentée sous la forme d’une liste finie ; on la représente donc comme une fonction d’argument un entier \(n\) et renvoyant \(\mathbb{P}(X=n)\).
In [21]: def simul(loi):
....: proba = random()
....: s = loi(0)
....: n = 0
....: while proba >= s:
....: n += 1
....: s += loi(n)
....: return n
....:
On peut utiliser cette méthode pour simuler une loi de Poisson.
In [22]: from math import factorial, exp
# Simulation d'une loi de Poisson
In [23]: poisson = lambda l: simul(lambda n: exp(-l) * l**n / factorial(n))
In [24]: [poisson(2) for _ in range(20)]
Out[24]: [3, 2, 3, 1, 2, 2, 2, 1, 0, 2, 2, 1, 3, 2, 0, 4, 1, 0, 1, 4]
De la même manière, on peut simuler une loi géométrique.
In [25]: from math import factorial, exp
# Simulation d'une loi géométrique
In [26]: geometrique = lambda p: simul(lambda n: 0 if n==0 else (1-p)**(n-1) * p)
In [27]: [geometrique(.2) for _ in range(20)]
Out[27]: [10, 3, 4, 6, 3, 1, 8, 1, 3, 2, 5, 1, 3, 2, 3, 5, 10, 2, 4, 1]
Bien entendu, il est plus facile d’utiliser l’interprétation de la loi géométrique comme le numéro d’un premier succès.
In [28]: def geometrique(p):
....: n = 1
....: while random() > p:
....: n +=1
....: return n
....:
In [29]: [geometrique(.2) for _ in range(20)]
Out[29]: [1, 4, 2, 1, 6, 6, 2, 2, 12, 2, 3, 4, 5, 3, 2, 6, 2, 4, 2, 4]