Tag Archives: ordre

De la vitesse de convergence, partie 1

Samedi après midi, à l’heure de la sieste pour certains, nous discutions avec Magali, Jean Baptiste et Florent des machines qui pouvaient trier les cartes, de là, la discussion a dévié sur les algorithmes de tri, et sur la difficulté d’expliquer l’importance de la vitesse d’un algorithme, ou plus généralement, la vitesse de convergence. Bref, avant de parler de vitesse de convergence en statistique – ou peut être avant sur les méthodes de calcul d’intégrale (ou d’espérance) – je voulais faire un petit billet rapide sur les algorithmes de tri. Je commence par des choses simples. De mémoire c’est des choses que je me souviens avoir vu au lycée dans les années 90, dans les cours d’informatique… Mais l’exemple peut être intéressant pour comprendre la différence, par exemple, entre https://perso.univ-rennes1.fr/arthur.charpentier/latex/tri-02.pnghttps://perso.univ-rennes1.fr/arthur.charpentier/latex/tri-03.png et https://perso.univ-rennes1.fr/arthur.charpentier/latex/tri-04.png.
Le premier algorithme est appelé tri à bulles. C’est probablement l’algorithme le plus simple, et sa vitesse est en https://perso.univ-rennes1.fr/arthur.charpentier/latex/tri-01.png. On va balayer autant de fois la base que l’on a d’observations, et à chaque passage, on récupère le maximum (ou le minimum, peu importe). L’algorithme ressemble à ça,

> n=25; s=1
> X=sample(1:n,size=n,replace=FALSE)
>          for(i in 1:(n-1)){
+          for(j in 1:(n-1)){
+          s=s+1
+          if(X[j] > X[j + 1]){X[c(j,j+1)]=X[c(j+1,j)]}
+          }}

Si on l’implémente, voilà ce que ça donne (tous les graphiques partent de la même permutation initiale, et tous contiennent autant d’images, de l’ordre de https://perso.univ-rennes1.fr/arthur.charpentier/latex/tri-01.png)

Bref, un algorithme en https://perso.univ-rennes1.fr/arthur.charpentier/latex/tri-05.png.Bon, j’ai été un peu brutal dans mon algorithme. En fait, on voit que les derniers points sont rapidement bien classés, donc inutile que la seconde boucle aille jusqu’au bout… on peut donc faire du https://perso.univ-rennes1.fr/arthur.charpentier/latex/tri-06.png, en faisant

 

+          for(j in 1:(n-i)){

Bref, la constante dans les https://perso.univ-rennes1.fr/arthur.charpentier/latex/tri-05.png peut être relativement importante comme on le voit ici.

Mais on peut faire  mieux, voire beaucoup mieux comme on le verra ensuite.
Le second algorithme est le tri par insertion. C’est aussi un algorithme très simple:  on balaye l’ensemble en plaçant les valeurs rencontrées à leur place, un peu comme quand on tri ses cartes… L’algorithme est là aussi en https://perso.univ-rennes1.fr/arthur.charpentier/latex/tri-05.png. Ici l’algorithme converge un peu plus rapidement que le précédant, mais cela vient du fait que les données étaient partiellement ordonnées sur la fin. Autrement dit, un autre échantillon aurait pu donner autre chose… Mais généralement, c’est le cas.

>          for(i in 1:n){
+           x = X[i]
+          for(j in (i+1):2){
+          s=s+1
+         if(X[j - 1] < x){X[j] = X[j - 1];  j = j - 1;  X[j] = x}
+         }
+         }

(le tri est fait à l’envers ici…. mais c’est un détail).

Enfin, le tri fusion est un autre algorithme en https://perso.univ-rennes1.fr/arthur.charpentier/latex/tri-07.png. L’idée est de couper, de trier, puis de fusionner. L’idée étant que trier un tableau dont la première moitié des éléments sont ordonnés, et où la dernière moitié est ordonné doit être plus rapide que quand tout est dans le désordre. A chaque étape, l’algorithme est simple, on compare le minimum des deux listes, puis on le vire à l’étape suivante. Sous R, ça donne, quand on commence

 

> for(i in 0:(trunc(n/2)-1)){
+ Y=X[c(1,2)+2*i]
+ if(Y[1]>Y[2]){X[c(1,2)+2*i]=X[c(2,1)+2*i]}
+ }

Bref, en commençant par classer les paires (1,2) puis (3,4), etc, puis les listes (1,2) versus (3,4). Le code est alors de la forme

> k=4
> for(i in 0:(trunc(n/4)-1)){
+ Y=X[1:k+k*i]
+ Y1=c(Y[1:(k/2)],rep(999999,k/2));Y2=c(Y[(k/2+1):k],rep(999999,k/2));
+ for(j in 1:k+k*i){
+     X[j]=min(c(Y1[1],Y2[1]),na.rm=TRUE)
+    if(X[j]==Y1[1]){Y1=Y1[
-1]}
+    if(X[j]==Y2[1]){Y2=Y2[-1]}
+ }}

(avec une petite correction pour le dernier bloc, qui ne compare pas forcément un bloc de taille 2 contre un autre de taille 2 (mais l’adaptation du code est infime). Puis on continue avec (1,2,3,4) versus (5,6,7,8), c’est relativement rapide de tout classer, comme le montre l’animation ci-dessous.

Il existe de très nombreux autres algorithmes de tri, le but étant de monter qu’un algorithme en https://perso.univ-rennes1.fr/arthur.charpentier/latex/tri-07.png va effectivement beaucoup plus vite qu’un algorithme en https://perso.univ-rennes1.fr/arthur.charpentier/latex/tri-05.png. J’ai tout fait ici en R, mais pour les adeptes d’autres langages, il existe plein de code en ligne, ici par exemple. Pour conclure, le graphique ci-dessous montre les différences entre les vitesses de convergence en https://perso.univ-rennes1.fr/arthur.charpentier/latex/tri-08.png (en noir), en https://perso.univ-rennes1.fr/arthur.charpentier/latex/tri-09.png (en rouge) et en https://perso.univ-rennes1.fr/arthur.charpentier/latex/tri-10..png (en bleu),

La suite sur la convergence des méthodes de monte carlo, puis des théorèmes limites en stats….

Discussions géométriques du matin (partie 2)

Suite rapide de mon billet sur la construction de triangles avec des bouts de bois (ici). Adrian me faisait remarquer () qu’il y avait plus simple pour calculer la probabilité de construire un triangle (je suis d’ailleurs affreusement jaloux de ne pas y avoir pensé tout seul). Mon principal soucis que j’ai en lisant le commentaire est “ça semble juste, mais est-ce que c’est juste ?” (mon expérience en TD de proba est que l’on peut souvent trouver un paquet de solutions qui “semblent” justes). Bref, faisons preuve de rigueur quelques minutes (même si France Inter continue à nous dire que le mot est toujours tabou ces temps-ci).
Rappelons que si on dispose d’un échantillon L'image “https://perso.univ-rennes1.fr/arthur.charpentier/latex/tr-ordre-01.png” ne peut être affichée car elle contient des erreurs. i.i.d. de loi https://perso.univ-rennes1.fr/arthur.charpentier/latex/tr-ordre-02.png, et de densité https://perso.univ-rennes1.fr/arthur.charpentier/latex/tr-ordre-03.png, et que l’on définie les statistiques d’ordre

https://perso.univ-rennes1.fr/arthur.charpentier/latex/tr-ordre-04.png

la loi du couple https://perso.univ-rennes1.fr/arthur.charpentier/latex/tr-ordre-05.png, avec https://perso.univ-rennes1.fr/arthur.charpentier/latex/tr-ordre-06.png,est alors

https://perso.univ-rennes1.fr/arthur.charpentier/latex/tr-ordre-07.png

à condition que https://perso.univ-rennes1.fr/arthur.charpentier/latex/tr-ordre-08.png (sinon la densité sera nulle). C’est jsute des histoires de compter les classements possibles, et puis de calculer quelques probas simples. Un cas particulier connu de tous est la loi du couple https://perso.univ-rennes1.fr/arthur.charpentier/latex/tr-ordre-09.png, i.e.

https://perso.univ-rennes1.fr/arthur.charpentier/latex/tr-ordre-10.png

Dans le cas qui nous intéresse, supposons que l’on tire deux bâtons, alors la loi du couple s’écrit

https://perso.univ-rennes1.fr/arthur.charpentier/latex/tr-ordre-11.png

alors que la densité du maximum était

https://perso.univ-rennes1.fr/arthur.charpentier/latex/tr-ordre-12.png

donc la loi du minimum conditionnellement au maximum doit d’écrire, par la formule de Bayes

https://perso.univ-rennes1.fr/arthur.charpentier/latex/tr-ordre-13.png

qui est effectivement la densité de la loi uniforme sur https://perso.univ-rennes1.fr/arthur.charpentier/latex/tr-ordre-14.png. Bref, ça marche pour deux bâtons.
Dans le cas de trois bâtons, la loi du triplet s’écrit

https://perso.univ-rennes1.fr/arthur.charpentier/latex/tr-ordre-15.png

alors que la loi du maximum devient

https://perso.univ-rennes1.fr/arthur.charpentier/latex/tr-ordre-30.png

aussi la loi conditionnelle du couple des deux premiers s’écrit

https://perso.univ-rennes1.fr/arthur.charpentier/latex/tr-ordre-31.png

Or si l’on avait deux lois uniformes sur https://perso.univ-rennes1.fr/arthur.charpentier/latex/tr-ordre-16.png, compte tenu de ce que l’on a écrit auparavant, la loi du couple des deux statistiques d’ordre seraient

https://perso.univ-rennes1.fr/arthur.charpentier/latex/tr-ordre-17.png

soit

https://perso.univ-rennes1.fr/arthur.charpentier/latex/tr-ordre-18.png

Bref, il semble qu’effectivement, le résultat soit correct: conditionnellement au maximum, les autres variables sont indépendantes, et suivent un loi uniforme sur https://perso.univ-rennes1.fr/arthur.charpentier/latex/tr-ordre-19.png.
Moralité, effectivement, les non-maximum sont indépendants, et leur loi est uniforme sur https://perso.univ-rennes1.fr/arthur.charpentier/latex/tr-ordre-16.png. On peut alors sommer ces deux lois uniformes et indépendantes, ce qui donne une loi triangulaire, sur https://perso.univ-rennes1.fr/arthur.charpentier/latex/tr-ordre-20.png, avec le sommet en https://perso.univ-rennes1.fr/arthur.charpentier/latex/tr-ordre-21.png. Et par des raisons de symmétrie, la probabilité de dépasser https://perso.univ-rennes1.fr/arthur.charpentier/latex/tr-ordre-21.png est alors https://perso.univ-rennes1.fr/arthur.charpentier/latex/tr-ordre-22.png.Merci Adrian. C’est effectivement plus élégant que mon calcul moche…