Psi 999 – 2020/2021
http://www.psi945.fr
TP Python
Loi des grands nombres
Vendredi 5 février 2021
Buts du TP
— S’émerveiller devant la loi des grands nombres.
— L’utiliser pour estimer des espérances ou variances.
— Se risquer dans le bizarre, lorsque l’espérance est infinie.
Exercice 1. Créer (au bon endroit) un dossier associé à ce TP. Lancer Spyder/Pyzo/Idle, sauvegarder au bon endroit le fichier grands_nombres.py; écrire une commande absurde, de type print( 6*7 ) dans l’éditeur, sauvegarder et exécuter. En profiter pour importer ce qu’il faut : Si vous êtes sous Spyder, changez (via F6) les options d’exécution, pour avoir à chaque exécution une nouvelle console et garder la main dessus. (il y a donc deux cases à vérifier/cocher).Récupérer le fichier-cadeau sur le réseau.
En décommentant et complétant progressivement les lignes du fichier offert, vous pouvez avancer rapi- dement !
Exercice 2. Vérifier que le premier exo a effectivement bien été fait : tout manquement donnera lieu de ma part à une agitation néfaste pour tout le monde...
La loi forte des grands nombres dit que si (X1, ..., Xn, ...) est une suite de variables aléatoires indé- pendantes identiquement distribuées (plus quelques hypothèses variables !) alors avec probabilité 1, on aura :
X1+X2+· · ·+Xn
n −→
n→+∞E(X).
La loi faible des grands nombres dit qu’àε >0fixé (et en cas d’existence d’une variance), la probabilité pour la moyenne s’écarte de plus deεde l’espérance tend vers0 quandntend vers+∞.
1 Vérifications sur les lois usuelles
Vous trouverez dans le fichier-cadeau du code permettant de réaliser un grand nombre de tirages de Bernoulli : on y utilise la fonctionbinomialde la bibliothèquenumpy.random:binomial(N, p)renvoie un tirage aléatoire selon la loi qu’on imagine ; si on met un troisième paramètre entier, on obtient même une liste (enfin, unarray) de tels tirages. Le casN= 1 permet de traiter la loi de Bernoulli.
def moyenne_bernoulli(Nb, p):
...
def moyenne_suite_bernoulli(Nb, p):
...
def visualisations_bernoulli(Nb, p, nb_courbes):
...
Exercice 3. Recopier ces fonctions, comprendre leur fonctionnement : que prennent-elles comme para- mètres ? Que renvoient-elles ?
Exécuter les commandes suivantes, copier/coller le résultat, le comprendre.
>>> [moyenne_bernoulli(10**k, 0.3) for k in range(2, 7)]
...
>>> moyenne_suite_bernoulli(10, 0.3) ...
>>> visualisations_bernoulli(1000, 0.3, 5) ...
Pour la suite du TP, la partie strictement entre legrid() et le savefig(...) pourra être oubliée : il s’agissait simplement de montrer un tunnel dans lequel les courbes s’engouffrent avec probabilité1! Les exercices suivants de cette partie vont consister à refaire la même chose... pour d’autres lois usuelles.
Un point de vue raisonnable (a.k.a. : meilleur) consisterait à écrire les fonctions précédentes sous forme paramétrée, en prenant en entrée une variable aléatoire ; une telle variable aléatoire pourrait alors être définie par :
def ber():
return binomial(1, 0.8) def pois():
return poisson(10) ...
Je vous laisse choisir entre « je fais des copier-coller puis je modifie » et « j’écris seulement trois fonctions paramétrées que j’applique ensuite aux bonnes lois ». Grosso-modo vous choisissez entre faire travailler vos doigts ou votre tête. À quelques heures des vacances, je présente dans les exos et le corrigé la version
« doigts »/« copier-coller », mais n’hésitez pas à changer !
On s’intéresse maintenant à la loi uniforme. On obtient un tirage uniforme sur [[a, b[[via le bon vieux randint(a, b)(attention à la borne droite, exclue). Par exemple un tirage de dé classique sera obtenu viarandint(1, 7).
Exercice 4. Reprendre les fonctions définies pour les Bernoulli en les adaptant à une loi uniforme sur [[1, N]].
>>> [moyenne_uniforme(10**k, 6) for k in range(2, 7)]
[3.6, 3.492, ...
>>> moyenne_suite_uniforme(10, 6) Out[2]:
[5.0, 3.0, 3.3333333333333335, ...
>>> visualisations_uniforme(1000, 6, 5) Exercice 5. Rejouer avec la loi binomiale !
0 200 400 600 800 1000
0.0 0.2 0.4 0.6 0.8 1.0
0 200 400 600 800 1000
1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0
0 200 400 600 800 1000
6.5 7.0 7.5 8.0 8.5 9.0
Figure 1 – Moyennes au cours du temps quandX ,→ B(3/10)puisU([[1,6]])puisB(10,7/10) Pour les deux dernières lois usuelles, on utilisera les fonctions geometric et poisson de la librairie numpy.random: leur fonctionnement est celui qu’on imagine, avec un premier paramètre correspondant à la loi, et un deuxième optionnel correspondant au nombre éventuel de tirages souhaités (1par défaut).
Exercice 6. Rejouer avec la loi géométrique.
Exercice 7. Terminer avec des variables de Poisson.
0 200 400 600 800 1000 3
4 5 6 7 8 9 10
0 200 400 600 800 1000
36 38 40 42 44 46
Figure 2 – Moyennes au cours du temps quandX ,→ G(1/5) puisP(42)
2 Estimation d’une variance
On a vu qu’on peut estimer/vérifier facilement l’espérance d’une variable aléatoireX grâce à un calcul de moyenne sur de nombreuses expériences. Mais on peut aussi estimer sa variance, a priori de deux façons :
— si on connaît son espérance (la vraie !) on peut estimer l’espérance du carré de la différence à celle-ci :
Var(X)' 1 n
n
X
i=1
(Xi−E(X))2.
— sinon, on peut commencer par estimer son espérance via une moyenne, puis (il faut avoir gardé lesXi en mémoire) calculer la moyenne des carrés des différences à la moyenne :
µ= 1
n(X1+X2+· · ·+Xn) et Var(X)' 1 n
n
X
i=1
(Xi−µ)2.
Mais attention, si on considère la variable aléatoire 1 n
n
X
i=1
(Xi−µ)2 (c’est ce qu’on appelle un « estima- teur » de la variance), on constate que son espérance est... TADAM : non pas Var(X)mais 1−n1
VarX. On dit que l’estimateur précédent est biaisé : on le redresse en le multipliant par n
n−1, avec donc comme estimateur non biaisé :
Var(X)' 1 n−1
n
X
i=1
(Xi−µ)2
La seule façon pour moi de comprendre il y a quelques années seulement ce mystérieux facteur 1 n−1 dont j’entendais parler depuis le lycée a été de calculer effectivement l’espérance de l’estimateur initial : si on ne fait pas ce calcul, on est obligé de croire/d’accepter...
Exercice 8. Écrire une fonction estimant la moyenne et l’espérance d’une variable aléatoire grâce aux formules précédentes. Tester sur les lois usuelles.
def ber():
return binomial(1, 0.8) def unif():
...
for va in [ber, binom, unif, pois, geom]:
print(moyenne_variance(10**6, va))
"""
(0.799944, 0.16003359686394888, 0.16003375689770577) (1.998975, ...
...
"""
J’ai renvoyé la version non redressée et la version redressée. Bon, quandnest grand (ce qu’il a vocation à être !) ça ne fera pas une grosse différence !
3 Points fixes d’une permutation
On va faire ici des expériences autour du nombre de points fixes d’une permutation. La théorie nous dit que pourσ∈ Sn choisie aléatoirement et uniformément parmi les n! permutations de[[1, n]], le nombre X de points fixes vérifie (évidemment)06X 6n, et son espérance vaut1 (quantité constante, ce qui surprend en général la première fois). Ceci peut s’obtenir en sommant des variables « compteur » Xi égales à1siiest fixe et0sinon. Il s’agit de variables de Bernoulli dont le paramètre s’obtient facilement.
On termine en sommant les espérances (de variables non indépendantes, mais on s’en fiche).
Pour la variance, le calcul n’a pas été fait en cours, mais peut s’obtenir de la même façon, via :
Var X
i
Xi
!
= Covar X
i
Xi,X
i
Xi
!
=X
i
Covar(Xi, Xi)
| {z }
Var(Xi)
+X
i6=j
Covar(Xi, Xj)
sachant queXi est une Bernoulli donc de variance connue, et que la covariance deXietXj (pouri6=j) se calcule via l’espérance deXiXj... qui est une variable de Bernoulli dont on peut à nouveau facilement calculer l’espérance/le paramètre ! Je laisse le lecteur finir les calculs...
Exercice 9. Exécuter (plusieurs fois !) permutation(list(range(0, 5))) et comprendre le résultat (vous aurez importé avant la fonctionpermutation de la bibliothèque numpy.random)
Écrire une fonction (sans paramètre) tirant au sort une permutation aléatoire de [[1,10]] (ou [[0,9]], si vous voyez ce que je veux dire...) et renvoyant le nombre de points fixes (lesitels que σ(i) =i).
Vous pouvez maintenant estimer la moyenne et la variance du nombre de points fixes d’une permutation...
>>> moyenne_variance(10**6, pf) (0.998089, ...
Vous pouvez aussi tester la loi des grands nombres !
0 200 400 600 800 1000
0.0 0.5 1.0 1.5 2.0 2.5 3.0
Figure3 – Moyennes au cours du temps pour le nombre de points fixes d’une permutation de[[1,10]]
4 Record à battre
Dans cette dernière partie, on s’intéresse au temps nécessaire pour qu’une variable aléatoire « batte un record ». Plus précisément, on considère une suite(X0, X1, ...)de variables aléatoires indépendantes identiquement distribuées :
— Si on se fixe une valeur v, quel sera le premier i >0 tel queXi > v?(On ne prend pas X0 en compte.)
— Si on prend une suite de variables indépendantes identiquement distribuéesX0, X1, ..., quel sera le premieri>1tel queXi> X0?
On aura noté que les inégalités sont strictes :Xi> vouXi> X0. Cela ne change pas fondamentalement les choses si on prend une inégalité large... mais un petit peu quand même !
Comme on peut l’imaginer, un point important est de savoir si les Xi peuvent prendre des valeurs arbitrairement grandes. Par exemple si on prend une loi uniforme sur [[1,6]], on va devoir attendre un moment avant de battrev= 6!
Ainsi, dans la suite, on suppose que lesXiprennent des valeurs arbitrairement grandes. Plus précisément : pour tout n∈N, P(X > n)>0. C’est par exemple le cas pour les variables aléatoires suivant des lois géométriques ou de Poisson. On peut alors montrer qu’avec probabilité1, toute valeur sera effectivement battue dans une série infinie de tirages deX.
Exercice 10. Écrire une fonction prenant en entrée une valeur et une variable aléatoire, et retournant le nombren>1 qui auront été nécessaires pour battre strictement cette valeur.
Écrire ensuite une fonction permettant d’évaluer l’espérance du temps d’attente.
D’une manière générale on peut montrer (il y a une loi géométrique derrière, avec la recherche d’un premier succès) que le temps d’attente moyen pour battre v est 1
P(X > v)· Dans l’exemple qui suit les Xi suivent une loi géométrique G(2/5), et P(X > v) = (1−2/5)v (v échecs dans lesv premières expériences...) :
>>> [(1/0.6**v, moyenne_record(geom, 10**4, v)) for v in range(10)]
[(1.0, 1.0), (1.6666666666666667, 1.6759) ...
(99.22903012752124, 101.0066)]
Dans le cas d’une variable aléatoire de Poisson P(λ), on connaît également P(X > v), mais sans jolie formule : c’est minablement
P(X > v) = 1−e−λ
v
X
i=0
ik k!·
Exercice 11. Comparer les temps d’attentes expérimentaux et théoriques pour battre une valeur donnée dans le cas de la loi de Poisson.
>>> [(theo_poisson(v), moyenne_record(pois, 10**4, v)) for v in range(20)]
[(1.0000454019910097, 1.0001), (1.0004996487515878, 1.0006), ...
(36.980046970504574, 35.8523), (70.03971589528416, 69.4415), (139.14970561121993, 136.8705), (289.4907357144317, 288.3366)]
On termine par le temps d’attente du « deuxième record » : on convient queX0est le premier record de la suite de tirages, et on cherche donc le temps d’attente du deuxième record, c’est-à-dire le plus petit i>1 tel queXi> X0. Ensuite, on veut estimer son espérance.
Exercice 12. Écrire une fonction prenant en entrée une variable aléatoire et renvoyant le temps d’attente du deuxième record. Estimer son espérance. Représenter la moyenne des valeurs lors de séries de tirages de longueurs103 ou105.
On pourra prendre une loi géométrique, ou de Poisson...
>>> moyenne_deuxieme_record(geom, 10**3) 13.066
>>> moyenne_deuxieme_record(geom, 10**3) 7.902
>>> moyenne_deuxieme_record(pois, 10**3)
28.057
>>> moyenne_deuxieme_record(pois, 10**3) 19.323
Ces moyennes très différentes sont surprenantes, non ? Regardez la tête de l’évolution des moyennes en cours de tirages...
0 200 400 600 800 1000
0 25 50 75 100 125 150 175 200
0 20000 40000 60000 80000 100000
0 10 20 30 40 50 60 70 80
Figure4 – Moyennes du temps d’attente pour battre le record quandX ,→ G(2/5)
0 200 400 600 800 1000
0 20 40 60 80
0 20000 40000 60000 80000 100000
0 50 100 150 200 250 300 350 400
Figure5 – Moyennes du temps d’attente pour battre le record quandX ,→ P(10)
Épilogue (pour les records)
Ces comportements étranges sont liés au fait que le temps d’attenteTn’a pas d’espérance (« son espérance est infinie »). Quelle que soit la façon de faire, on revient plus ou moins àPP(X =n)
P(X > n)·
Si on note (pourn>−1)αn=P(X > n), on est alors ramené à l’étude de la série Pαn−1−αn αn
· Une comparaison somme-intégrale nous donne la minoration
N
X
n=0
αn−1−αn αn >
Z 1
αN
dt
t =−lnαN −→
N→+∞+∞
car en tant que reste d’une série convergente,αn −→
n→+∞0.
Terminons en signalant que le cas des records larges conduit à établir la divergence dePαn−1−αn
αn−1 qui demande un peu plus de finesse... et est laissé aux réflexions du lecteur.