Les cotes étaient là¶
L'épilogue de la campagne classait les cotes en voie bloquée : pas de source
gratuite, cotes injectées en JavaScript géolocalisé sur le site source, réservées
aux offres payantes chez le fournisseur professionnel identifié. La mission de
reconnaissance avait cherché le mot odds dans trente pages du cache et n'avait
trouvé que des commentaires de forum.
Le diagnostic était juste — pour le cache HTML. Il était faux pour l'autre moisson, celle qu'on avait faite pour une raison complètement différente.
La découverte¶
Quelques jours plus tôt, l'API publique de bo3.gg avait été aspirée pour en extraire le détail manche par manche : valeurs d'équipement, premiers kills, clutchs, raisons de fin de manche. C'est la source qui a produit les features d'économie.
Chaque objet « match » renvoyé par cette API porte un champ nommé bet_updates.
Personne ne l'avait ouvert : il ne servait pas au sujet du moment. Il contenait,
pour une partie des matchs, une cote décimale par équipe, l'identifiant bo3
de chaque équipe, une cote maximale et un score d'accord entre opérateurs.
Les cotes étaient sur disque depuis le début.
À retenir — inventoriez ce que vous avez déjà collecté
Le chantier qui a débloqué la question la plus importante de la campagne a coûté zéro requête réseau. Trois autres pistes étaient prêtes — scraping HLTV, archives web, jeux de données publics — et n'ont pas eu lieu d'être ouvertes ; le budget de requêtes est resté intact.
Une moisson faite pour un objectif contient presque toujours des champs collectés « au passage ». Les relire avant de lancer une collecte neuve est le meilleur rapport information / effort du métier.
L'appariement, et pourquoi il est sûr¶
Une cote ne sert à rien si l'on ne sait pas à quelle équipe elle se rapporte. Deux garde-fous ont été posés.
D'abord l'orientation : le fichier de correspondance construit pour la moisson des manches fournit déjà l'identifiant bo3 de chaque équipe. Sur les 662 matchs du holdout portant une cote, l'orientation a été résolue par identifiant dans tous les cas sauf un, rejeté comme ambigu. Aucune correspondance par nom d'équipe — la source d'erreur classique — n'a été nécessaire.
Ensuite le contrôle croisé : deux fichiers ont été collectés indépendamment par la moisson, l'un pour la fenêtre récente, l'autre pour l'historique long. Ils portent 5 001 matchs en commun et zéro désaccord sur les cotes. Quand deux collectes séparées disent la même chose, l'hypothèse d'une erreur de lecture tombe.
Lire une cote¶
Une cote décimale est un multiplicateur de mise. Une cote de 1,445 signifie : si vous misez 1 € et que vous gagnez, vous récupérez 1,445 € — votre mise plus 0,445 € de gain.
Plus la cote est basse, plus l'équipe est favorite. Une cote de 1,05 annonce une victoire quasi certaine ; une cote de 5,00 annonce un outsider.
L'intuition à garder : la cote est l'inverse d'une probabilité. Si un opérateur pensait qu'une équipe gagne une fois sur deux et ne prenait aucune marge, il proposerait 2,00. S'il pense une fois sur quatre, 4,00.
où \(c\) est la cote décimale et \(p_{\text{brute}}\) la probabilité que cette cote suggère avant toute correction.
L'overround : la marge cachée dans les deux cotes¶
Si les deux cotes d'un match traduisaient des probabilités honnêtes, leurs inverses feraient exactement 1 : l'une ou l'autre équipe gagne, il n'y a pas de troisième issue.
En pratique, la somme dépasse 1. Cet excédent s'appelle l'overround, et c'est la marge de l'opérateur :
où \(c_j\) est la cote proposée sur l'issue \(j\) et \(\Omega\) l'overround. Un \(\Omega\) de 1,0727 signifie que l'opérateur a vendu 107,27 % de probabilité pour 100 % d'issues possibles : les 7,27 % d'excédent sont sa marge.
La dévigorisation, pas à pas¶
Pour comparer la croyance d'un bookmaker à celle d'un modèle, il faut retirer cette marge — l'opération s'appelle la dévigorisation (de vigorish, le nom argotique de la marge). La méthode la plus simple, et celle utilisée ici, consiste à redistribuer proportionnellement :
où \(c_i\) est la cote de l'équipe \(i\), \(p_i\) sa probabilité dévigorisée, et le dénominateur l'overround \(\Omega\) défini plus haut. Par construction, les \(p_i\) somment à 1.
Un exemple avec les valeurs médianes réellement observées sur notre pool — cote du favori 1,445 et overround 7,27 % :
| Étape | Équipe favorite | Équipe outsider | Somme |
|---|---|---|---|
| cote décimale \(c\) | 1,445 | 2,627 | — |
| inverse \(1/c\) | 0,6920 | 0,3807 | 1,0727 |
| dévigorisé \(p = (1/c)/\Omega\) | 64,5 % | 35,5 % | 1,0000 |
L'opération a retiré 7,27 % de « probabilité » vendue en trop. Sans elle, on attribuerait au bookmaker une confiance de 69,2 % là où il ne croit qu'à 64,5 % — et on le jugerait plus mauvais qu'il n'est, puisque le score de Brier punit la surconfiance.
Intuition — pourquoi la marge n'est pas une opinion
L'overround ne dit rien sur qui va gagner : c'est un péage prélevé sur les deux issues à la fois. Le dévigoriser, c'est demander à l'opérateur ce qu'il croit, séparément de ce qu'il facture. Ce sont deux questions différentes, et le dernier chapitre montre que la seconde compte au moins autant que la première.
L'overround est aussi une signature. Un vrai marché d'avant-match prend une marge comprise, dans notre pool, entre 6,4 % et 8,2 % selon les mois. Une marge absente, ou une distribution de cotes concentrée près de 1,00, signale que quelque chose ne va pas — et c'est exactement ce qui est arrivé.
Le piège : 86,6 % d'exactitude au bookmaker¶
La toute première mesure a porté sur les 662 matchs du holdout qui portaient une cote. Le journal du chantier en garde la trace :
2026-08-25T11:59:26+00:00 BOOKMAKER n=662 acc=86.6% brier=0.0927 logloss=0.3118
Un bookmaker à 86,6 % d'exactitude et 0.0927 de Brier. C'est-à-dire deux fois mieux que le repère de littérature, sur un Brier meilleur que celui de nos segments les plus faciles.
Ce chiffre est impossible.
Limite importante — un résultat trop beau est un bug jusqu'à preuve du contraire
C'est la règle générale que ce chapitre existe pour transmettre. Devant un résultat spectaculaire, la seule conduite raisonnable est de chercher l'erreur avant de chercher l'explication.
Un marché à 0.0927 de Brier signifierait que les matchs de CS2 sont presque déterministes, ce que dix mois de mesures contredisent. Il signifierait aussi que ce marché aurait été arbitragé jusqu'à disparition. Quand un résultat implique que le monde entier a manqué quelque chose d'évident, ce n'est pas le monde qui se trompe.
L'enquête¶
Trois indices, dans l'ordre où ils sont apparus.
L'URL d'affiliation. Chaque entrée du champ porte un lien vers l'opérateur,
et ce lien contient la taxonomie interne de celui-ci : /en/line/ pour le
marché d'avant-match, /en/live/ pour le marché en direct. Sur l'ensemble des
matchs bo3 disponibles, la répartition est de 1 300 contre 3 700 ; sur notre
holdout, 160 contre 502.
Les cotes plancher. 442 matchs portent une cote minimale d'exactement 1,001, soit un dixième de pour cent de gain. Aucun marché d'avant-match ne price une équipe à 1,001 : personne n'ouvrirait un marché où l'on immobilise 1 000 € pour en gagner 1.
La calibration. C'est la preuve décisive. Sur le segment en direct du holdout, la table de calibration n'est pas seulement bonne, elle est déterministe :
| Tranche annoncée (segment en direct) | n | Taux observé | Attendu si honnête |
|---|---|---|---|
| 0 – 20 % | 152 | 0,0 % | ~9 % |
| 80 – 100 % | 218 | 99,5 % | ~87 % |
Une probabilité annoncée à 9 % qui ne se réalise jamais sur 152 cas n'est pas une probabilité : c'est une observation. Ces cotes ont été capturées alors que les matchs étaient déjà largement joués, parfois à quelques manches de la résolution.
Le segment d'avant-match, lui, se comporte comme un vrai marché sur les mêmes critères : overround médian de 7,27 %, cote du favori médiane à 1,445, calibration monotone mais non déterministe.
Cote du favori — deux populations, deux mondes
/en/line/ (avant-match) médiane 1,445 8 cotes < 1,05
|----------[####]-------------------------|
1,0 3,0
/en/live/ (en direct) médiane 1,03 286 cotes < 1,05
|[############]--------------------------|
1,0 3,0
La cause : un instantané sans horodatage¶
Le champ bet_updates est un instantané unique, capturé après la fin des
matchs, et il ne porte aucune date de capture. Pour les matchs dont le marché
d'avant-match avait été archivé, il contient une vraie cote d'avant-match. Pour
les autres, il contient la dernière cote vue — c'est-à-dire une cote en
direct, prise à un moment où l'issue était presque connue.
C'est une fuite du futur caractérisée, de la même famille que celles étudiées au chapitre intégrité temporelle : une information postérieure au moment de la prédiction s'est glissée dans les données de la prédiction.
Le segment en direct a été mis en quarantaine. Détail qui mérite d'être copié :
il n'a pas été supprimé. Il reste dans l'artefact sous une étiquette
explicite, market == "live", uniquement pour que l'erreur reste traçable et que
personne ne la redécouvre par accident dans six mois.
Erreur fréquente — supprimer les données contaminées
Effacer un segment fautif fait disparaître la preuve en même temps que le problème. Le successeur qui rouvrira la source retombera exactement dans le même piège, sans rien pour l'avertir. Étiqueter et isoler coûte une colonne ; supprimer coûte une redécouverte.
Le premier verdict, et le vrai palier¶
Restaient 160 matchs d'avant-match sur le holdout — 14 % de celui-ci — appariés au match près, avec notre modèle gelé.
| Sur les 160 matchs d'avant-match | Exactitude | Brier | Log-loss |
|---|---|---|---|
| bookmaker réel (dévigorisé) | 65,6 % | 0.2094 | 0.6067 |
nous (segmodel, gelé) |
64,4 % | 0.2138 | 0.6151 |
| Glicko de Valve (ancre) | 61,3 % | 0.2427 | — |
| littérature, pour mémoire (autres matchs) | 68,7 % | 0.198 | — |
L'écart est de +0.0044 de Brier en notre défaveur, avec un intervalle de confiance à 95 % de [−0.009 ; +0.017] et \(P(\text{nous meilleurs}) = 28{,}5\,\%\). Sur l'exactitude, −1,2 point, intervalle [−6,9 ; +4,4]. Rien n'est tranché : à \(n = 160\), les intervalles avalent tout.
Le résultat qui compte est dans la première ligne du tableau, pas dans la comparaison. Le vrai marché, sur nos matchs, ne fait pas 68,7 % / 0.198 : il fait 65,6 % / 0.2094.
Le palier de la littérature n'a jamais été le bon palier pour notre échantillon. Il décrivait un pool tier 1 que notre holdout ne reproduit pas — et l'ancre externe ne montre aucun signe d'un sous-ensemble plus facile : le Glicko de Valve y affiche 0.2427 de Brier, contre 0.2422 sur le holdout complet.
La question a donc changé de nature. Elle est passée de indécidable faute de données à statistiquement indécidée sur 160 matchs, avec un palier corrigé.
Il restait à augmenter \(n\) — et c'est là que le verdict s'est mis à changer de signe.
Chapitre précédent : La vraie barre · Chapitre suivant : Le verdict · Glossaire