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
m=\frac{1}{n}\sum_{k=1}^nx_k
.. ipython:: python def moyenne(liste): somme = 0 for el in liste: somme += el return somme / len(liste) moyenne([1, 2, 3])
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.
v = \left(\frac{1}{n}\sum_{k=1}^nx_k^2\right)-m^2 = \frac{1}{n}\sum_{k=1}^n(x_k-m)^2
En utilisant la première expression, on peut par exemple donner cette fonction de calcul de la variance [2].
.. ipython:: python 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 variance([1, 2, 3])
On peut également utiliser une des fonctions de calcul de moyenne définies précédemment.
.. ipython:: python variance = lambda liste: moyenne([el ** 2 for el in liste]) - moyenne(liste) ** 2 variance([1, 2, 3])
Si l'on préfère, on peut également utiliser la deuxième expression de la variance.
.. ipython:: python def variance(liste): m = moyenne(liste) return moyenne([(el - m) ** 2 for el in liste]) variance([1, 2, 3])
Dans la suite, on fera appel à la fonction random
du module random
qui renvoie un flottant tiré aléatoirement dans l'intervalle [0,1[.
.. ipython:: python from random import random [random() for _ in range(10)]
Cela nous permettra de simuler des variables aléatoires connaissant leurs lois [3].
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.
.. ipython:: python def simul(loi): proba = random() s = 0 for i, p in enumerate(loi): s += p if proba < s: return i
.. ipython:: python [simul([.3, .5, .2]) for _ in range(20)]
On pourrait par exemple utiliser la méthode précédente pour simuler une loi binomiale.
.. ipython:: python from scipy.special import binom binomiale = lambda n,p: simul([binom(n, k) * p**k * (1-p)**(n-k) for k in range(n+1)]) [binomiale(5, .8) for _ in range(20)] [binomiale(5, .2) for _ in range(20)]
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.
.. ipython:: python def bernoulli(p): return 1 if random() < p else 0 def binomiale(n, p): return sum(bernoulli(p) for _ in range(n)) [binomiale(5, .8) for _ in range(20)] [binomiale(5, .2) for _ in range(20)]
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).
.. ipython:: python 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.
.. ipython:: python from math import factorial, exp # Simulation d'une loi de Poisson poisson = lambda l: simul(lambda n: exp(-l) * l**n / factorial(n)) [poisson(2) for _ in range(20)]
De la même manière, on peut simuler une loi géométrique.
.. ipython:: python from math import factorial, exp # Simulation d'une loi géométrique geometrique = lambda p: simul(lambda n: 0 if n==0 else (1-p)**(n-1) * p) [geometrique(.2) for _ in range(20)]
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.
.. ipython:: python def geometrique(p): n = 1 while random() > p: n +=1 return n [geometrique(.2) for _ in range(20)]
[1] | Evidemment, Python dispose déjà deux fonctions permettant de calculer aisément la moyenne d'une liste de nombres. On peut par exemple utiliser la fonction .. ipython:: python moyenne = lambda liste: sum(liste) / len(liste) moyenne([1, 2, 3]) Le module .. ipython:: python from numpy import mean mean([1, 2, 3]) |
[2] | Bien entendu, le module .. ipython:: python from numpy import var var([1, 2, 3]) |
[3] | A nouveau, le module numpy.random dispose déjà de fonctions permettant de simuler la plupart des lois classiques. |