Aller au contenu

Elo : le modèle fondateur

Arpad Elo était un physicien et joueur d'échecs. Dans les années 1950-60, on lui demande de remplacer le système de classement de la fédération américaine par quelque chose de défendable. Il propose une idée si simple qu'on l'utilise encore partout soixante-dix ans plus tard, du tennis aux jeux vidéo : un nombre par joueur, et une règle de mise à jour proportionnelle à la surprise.

Tout ce qui suit dans cette partie — Glicko, Glicko-2, TrueSkill, pi-ratings — est une variation sur ce thème. Comprendre Elo, c'est comprendre 80 % du reste.

L'idée en une phrase

Chaque équipe porte un nombre. Avant un match, l'écart entre les deux nombres se traduit en probabilité. Après le match, chaque nombre bouge d'une quantité proportionnelle à l'écart entre ce qui était attendu et ce qui s'est produit.

   avant                       match                     après
  ┌──────┐                   ┌───────┐                 ┌──────┐
  │ r_A  │──┐             ┌──│ y = 1 │                 │ r_A' │ = r_A + K(y − E)
  └──────┘  ├─► E = ... ──┤  └───────┘  ──────────────►└──────┘
  ┌──────┐  │             └── surprise                 ┌──────┐
  │ r_B  │──┘                 = y − E                  │ r_B' │ = r_B − K(y − E)
  └──────┘                                             └──────┘

Deux formules, donc : celle qui prédit, et celle qui apprend.

La formule qui prédit : l'espérance logistique

L'idée de départ est qu'un écart de rating doit se traduire par un rapport de cotes, pas par une différence de probabilité. Deux équipes séparées de 400 points doivent avoir le même rapport de forces que deux autres séparées de 400 points, où qu'on se situe sur l'échelle.

\[ E = \frac{1}{1 + 10^{(r_B - r_A)/400}} \]

Les symboles :

  • \(E\) : la probabilité que l'équipe \(A\) gagne, entre 0 et 1 ;
  • \(r_A\) : le rating courant de l'équipe \(A\) ;
  • \(r_B\) : le rating courant de l'équipe \(B\) ;
  • \(400\) : l'échelle. C'est une convention pure — elle fixe ce que « 400 points d'écart » veut dire ;
  • \(10\) : la base. Avec la base 10 et l'échelle 400, un écart de 400 points correspond exactement à une cote de 10 contre 1, soit \(E \approx 0{,}909\).

Intuition

C'est une sigmoïde : une courbe en S. Au centre (ratings égaux) elle passe par 0,5 et elle est très pentue — 50 points d'écart changent beaucoup la probabilité. Aux extrêmes elle s'aplatit : entre 800 et 900 points d'écart, la probabilité passe seulement de 0,99 à 0,994. C'est exactement ce qu'on veut : battre une équipe déjà très inférieure n'apprend presque rien.

Exemple numérique

Prenons deux équipes de notre pool à un instant donné du balayage, l'une à \(r_A = 1650\), l'autre à \(r_B = 1500\) :

\[ E = \frac{1}{1 + 10^{(1500 - 1650)/400}} = \frac{1}{1 + 10^{-0{,}375}} = \frac{1}{1 + 0{,}4217} = 0{,}7034 \]

L'horloge annonce donc 70,3 % pour \(A\). Quelques autres valeurs, à garder en tête pour lire les chapitres suivants :

écart \(r_A - r_B\) \(E\)
0 0.500
150 0.703
200 0.760
300 0.849
400 0.909

Notez la symétrie : \(E(r_A, r_B) + E(r_B, r_A) = 1\) toujours. Elle est vérifiée comme invariant dans le code de production (vrs/model.py, fonction _demo).

La formule qui apprend : la mise à jour

\[ r_A \leftarrow r_A + K\,(y - E) \qquad\text{et}\qquad r_B \leftarrow r_B - K\,(y - E) \]

Les symboles :

  • \(y\) : le résultat observé, \(1\) si \(A\) a gagné, \(0\) sinon ;
  • \(E\) : la probabilité que l'horloge avait annoncée, avant le match ;
  • \(y - E\) : la surprise. Positive si \(A\) a fait mieux qu'attendu, négative sinon ;
  • \(K\) : le pas d'apprentissage, en points de rating. C'est le seul paramètre libre.

Deux propriétés méritent d'être soulignées, parce qu'elles sont vraies pour Elo et plus pour aucune des horloges suivantes.

La mise à jour est à somme nulle. Ce que \(A\) gagne, \(B\) le perd exactement. Le total des ratings du pool est donc conservé : Elo redistribue de la force, il n'en crée pas. C'est élégant, et c'est aussi une limite — une ligue entière qui progresse en niveau absolu est invisible pour Elo.

La correction est asymétrique en faveur des surprises. Si \(A\) est favorite à 70,3 % et gagne, elle prend \(K \times 0{,}297\). Si elle perd, elle lâche \(K \times 0{,}703\), soit 2,4 fois plus. Personne n'a codé cette asymétrie : elle sort de \(y - E\).

Exemple numérique

Reprenons nos deux équipes à 1650 et 1500, donc \(E = 0{,}7034\), avec \(K = 30\) (la valeur utilisée en production dans vrs/predict.py).

Cas 1, la favorite gagne (\(y = 1\)) :

\[ \Delta = 30 \times (1 - 0{,}7034) = 30 \times 0{,}2966 = +8{,}9 \]

\(A\) passe à 1658,9 et \(B\) tombe à 1491,1.

Cas 2, l'outsider gagne (\(y = 0\)) :

\[ \Delta = 30 \times (0 - 0{,}7034) = -21{,}1 \]

\(A\) tombe à 1628,9 et \(B\) monte à 1521,1. Une seule surprise coûte 21 points ; il faudra à \(A\) plus de deux victoires attendues pour les récupérer.

Le sens de \(K\) : vitesse d'adaptation contre bruit

\(K\) est le paramètre qui contient toute la philosophie du système. Il répond à une question et une seule : quelle part d'un seul résultat dois-je croire ?

  • \(K\) petit : l'horloge est lente. Elle ignore les accidents, mais elle met des dizaines de matchs à enregistrer un vrai changement de niveau — un transfert de star, par exemple.
  • \(K\) grand : l'horloge est rapide. Elle capte immédiatement un changement de forme, mais elle prend aussi le bruit pour du signal, et elle se met à annoncer des probabilités extrêmes qu'elle ne peut pas soutenir.

Voici la même séquence — l'équipe \(A\) bat l'équipe \(B\) quatre fois de suite, en partant de 1500 chacune — vue par deux horloges de vitesses différentes.

match \(K = 30\) : écart après \(p\) annoncée ensuite \(K = 90\) : écart après \(p\) annoncée ensuite
1 30,0 0.543 90,0 0.627
2 57,4 0.582 157,2 0.712
3 82,5 0.617 209,0 0.769
4 105,5 0.647 250,6 0.809

Après quatre victoires, l'horloge lente dit « \(A\) est favorite à 65 % » et l'horloge rapide dit « \(A\) est favorite à 81 % ». Quatre matchs, c'est très peu. Laquelle des deux a raison ? La question n'est pas rhétorique : c'est précisément ce que nous avons mesuré.

Notre mesure : faire varier \(K\) tout seul n'apporte rien

Le protocole est celui du script scratch/elo_variants.py. Chaque variante est rejouée en prédicteur pur sur le balayage chronologique complet, et évaluée sur le holdout commun des 42 derniers jours. Aucun modèle d'apprentissage par-dessus : la probabilité annoncée est directement la logistique de l'écart de rating.

Les mesures de la campagne (commit du 2026-08-24) :

variante accuracy Brier log-loss
Glicko de Valve (baseline) 56,0 % 0.2423 0.6773
Elo \(K = 15\) — pire que la baseline —
Elo \(K = 45\) — pire que la baseline —
Elo \(K = 90\) 57,8 % 0.2478 —
Elo \(K = 30\) + marge (chapitre 3) — 0.2398 0.6725

Le verdict tenait en une ligne dans le journal du projet : « \(K\) libre seul : rien. » Aucune valeur de \(K\), prise isolément, ne bat la formule de Valve au Brier. On a essayé 15, 45, 60 et 90 ; toutes perdent.

Pour aller plus loin — la table complète, re-mesurée

Le script scratch/elo_variants.py est reproductible. Relancé le 2026-08-25 sur un pool légèrement plus grand (6 080 matchs, holdout de 1 176 matchs après le 2026-07-13, donc pas strictement le holdout de 1 146 de la campagne), il donne :

variante accuracy Brier log-loss
Valve (Glicko \(RD = 75\), \(K \approx 30\)) 55,7 % 0.2428 0.6784
Elo \(K = 15\) 55,7 % 0.2442 0.6814
Elo \(K = 45\) 55,8 % 0.2432 0.6795
Elo \(K = 60\) 56,5 % 0.2446 0.6833
Elo \(K = 90\) 57,3 % 0.2489 0.6962
Elo \(K = 30\) + marge 57,5 % 0.2404 0.6736
Elo \(K = 45\) + marge 57,7 % 0.2417 0.6773
Elo \(K = 60\) + marge 58,0 % 0.2443 0.6848

Les valeurs absolues bougent de un à deux millièmes — le pool n'est pas le même — mais l'ordre est identique et les deux conclusions tiennent : \(K\) seul ne sert à rien, la marge gagne. Une conclusion qui survit à un changement de pool est une conclusion à laquelle on peut se fier.

\(K = 90\) : l'illustration parfaite de « accuracy ≠ calibration »

Regardez la ligne \(K = 90\) une deuxième fois. Elle a la meilleure accuracy du tableau parmi les Elo sans marge — 57,8 % contre 56,0 % pour la baseline — et le pire Brier de tous : 0.2478.

C'est le résultat le plus pédagogique de toute la campagne, alors prenons le temps.

Les deux métriques ne mesurent pas la même chose

L'accuracy est la proportion de fois où le camp annoncé favori l'emporte réellement. Elle ne regarde qu'une chose : de quel côté de 0,5 se trouve la probabilité. Annoncer 0,51 ou 0,99 lui est parfaitement égal.

Le score de Brier est l'erreur quadratique moyenne sur la probabilité elle-même :

\[ \mathrm{BS} = \frac{1}{n}\sum_{i=1}^{n} (p_i - y_i)^2 \]

où \(p_i\) est la probabilité annoncée pour le match \(i\), \(y_i\) le résultat observé (0 ou 1), et \(n\) le nombre de matchs — ici 1 146. Plus il est bas, mieux c'est ; 0,25 est le score d'un modèle qui annonce toujours 0,5.

Le Brier, lui, regarde la distance. Annoncer 0,99 sur un match qu'on perd coûte \(0{,}99^2 = 0{,}98\) ; annoncer 0,51 sur le même match coûte \(0{,}26\). Presque quatre fois moins.

Pourquoi \(K = 90\) tombe dans le piège

Une horloge rapide écarte les ratings. Le tableau de la section précédente le montrait déjà : après quatre victoires, \(K = 90\) produit 250 points d'écart contre 105 pour \(K = 30\). Sur des centaines de matchs, l'échelle entière se dilate.

Cette dilatation a deux effets opposés :

  • Elle aide l'accuracy. L'ordre des équipes est mieux résolu : les quasi-égalités qui étaient à 0,501 partent à 0,55, et les départager du bon côté devient un peu plus facile. D'où le passage de 56,0 % à 57,8 %.
  • Elle ruine le Brier. Toutes les probabilités deviennent extrêmes. Or CS2 est un sport à forte variance : une équipe favorite à 81 % selon \(K = 90\) ne gagne pas 81 % du temps, elle gagne peut-être 68 % du temps. Chaque match perdu par un « grand favori » se paie très cher.

Erreur fréquente

« Mon modèle est passé de 56 % à 58 % d'accuracy, il est meilleur. » Pas forcément. Un modèle qui exagère systématiquement ses convictions gagne souvent un peu d'accuracy en perdant beaucoup de calibration. Si vous comptez utiliser les probabilités pour autre chose que trancher — un Monte Carlo, un pari, une estimation de chances de qualification — c'est le Brier qui décide, pas l'accuracy.

Dans ce projet, les probabilités alimentent une simulation Monte Carlo de fin de saison. Une probabilité surconfiante s'y propage en composant ses erreurs sur des dizaines de matchs simulés. C'est pour cette raison que tout le projet a été arbitré au Brier, jamais à l'accuracy — y compris quand cela coûtait de l'accuracy affichée.

Le même phénomène, lu à l'envers

Il vaut la peine de noter la conclusion symétrique. Le modèle final de la campagne (le leader segmodel) atteint 0.2041 de Brier et 67,9 % d'accuracy. Les bookmakers professionnels, dans la littérature, sont à 0.198 et 68,7 % — sur du tier 1 uniquement, donc un pool différent du nôtre qui mélange tier 1 à tier 3, où les écarts de force sont plus francs. La comparaison directe n'a pas de sens ; ce qui en a, c'est de constater que les deux métriques progressent ensemble quand un modèle apprend vraiment quelque chose, et divergent quand il ne fait que se crisper sur ses convictions.

Ce qu'Elo ne sait pas faire

Trois angles morts, qui donnent leur sujet aux chapitres suivants.

Elo ne connaît pas son incertitude. Une équipe qui a joué 2 matchs et une qui en a joué 80 portent le même type de nombre, mis à jour avec le même \(K\). Rien ne dit à l'horloge que le premier rating est une devinette et le second une mesure. C'est le sujet du chapitre 2 et du chapitre 4.

Elo jette la marge. Un 2-0 et un 2-1 produisent exactement la même mise à jour, alors que l'information n'est manifestement pas la même. C'est le sujet du chapitre 3, et c'est notre variante gagnante.

Elo suit des équipes, pas des joueurs. Quand trois joueurs sur cinq changent, l'entité « équipe » garde son rating alors que l'objet a changé. C'est le sujet du chapitre 4.

À retenir

Elo tient en deux formules : \(E = 1/(1+10^{(r_B-r_A)/400})\) pour prédire, \(r \leftarrow r + K(y-E)\) pour apprendre. Le paramètre \(K\) arbitre entre réactivité et stabilité. Notre mesure : le faire varier seul n'apporte rien (\(K = 15, 45, 60, 90\) perdent tous au Brier contre la baseline), et \(K = 90\) est le contre-exemple à retenir — meilleure accuracy, pire Brier. Une accuracy qui monte pendant qu'une calibration s'effondre n'est pas un progrès.

Chapitre suivant : Glicko et le RD figé, où l'on démontre que le système de Valve, sous son nom savant, est exactement l'Elo qu'on vient de décrire.