Analyse de pronostics pour le Mondial 2018

On est les champions ! Si nous n’avons pas eu le temps de faire un modèle de prédiction pour cette coupe du monde de football 2018 (mais FiveThirtyEight en a fait un très sympa, voir ici), cela ne nous a pas empêché de faire un concours de pronostics entre collègues et ex-collègues statisticiens, sur le site Scorecast. Les résultats obtenus sont les suivants :

JoueurScore
Nic102
Cle100
Ron100
Lud96
Tho90
Lio88
Lis87
Pap86
Mau84
Yan78
Ant78
Lau75
Thi71
Arn56
Oli28
Mar7

Un autre système de points ?

Le système de points utilisé par Scorecast est le suivant : si on a le bon gagnant, on gagne un faible nombre de points ; si en plus du bon gagnant, on a bien prédit l’écart de buts, on gagne un peu plus de points ; et enfin, si on a le score exact, on gagne le nombre maximal de points. Ce nombre maximal de points augmente au fur et à mesure de la compétition : la finale vaut plus de points qu’un match de poules. Ce système ne tient pas compte de cotes préexistantes (comme le fait par exemple Mon petit prono), ou du fait que certains matchs sont bien prédits par tout le monde alors que pour d’autres seule une personne a bien trouvé, voire personne.

Je propose donc ici d’altérer légèrement l’attribution des points, de la façon suivante : on dispose d’un nombre de points équivalent pour chaque match d’une même manche (match de poule, de quart, etc.), qu’on répartit entre les joueurs qui ont bien prédit le score, avec un avantage pour ceux qui ont le bon écart de points ou le bon score exact. Le nombre de points à répartir augmente tout au long de la compétition, de sorte que les phases finales aient plus d’importance dans le classement final.

Pourquoi faire ça ? Pour favoriser les joueurs qui ont fait des paris plus originaux et potentiellement plus risqués, ou en tout cas qui étaient les seuls à avoir la bonne intuition. Voici les résultats :

JoueurScoreScore modifié
Mau84185
Lud96163
Nic102144
Tho90136
Ant78135
Cle100126
Ron100123
Lis87120
Lio88115
Pap86108
Yan78105
Lau75100
Thi7190
Arn5678
Oli2843
Mar710

On constate que le classement évolue sensiblement avec cette nouvelle méthode de points ! Mais peut-être que certains auraient fait d’autres paris si ces règles étaient décidées…

Choix des scores

Une des principales difficultés du pronostic est qu’il ne suffit pas de savoir (ou de penser savoir) qui va gagner le match, mais il faut aussi indiquer le score attendu. Regardons si les prédictions de l’ensemble des parieurs de notre ligue ont été pertinentes par rapport aux vrais scores ! Pour cela, on détermine pour chaque score le pourcentage des matchs qui ont abouti à ce résultat d’une part, et le pourcentage des paris faits avec ce score. On regarde ensuite la différence entre les pourcentages, qu’on va illustrer par la heatmap ci-dessous. Les cases vertes correspondent aux scores des matchs trop rarement prédits ; les cases rouges aux scores très souvent prédits mais qui n’arrivent que peu ou pas.

On constate que l’on a surestimé largement le nombre de 2-1, de 3-0 et de 4-0 (score qui n’est jamais arrivé lors de cette coupe du monde) ; ce sont d’ailleurs les seuls “gros” scores qui ont été surestimés dans les prédictions : tous les autres ont été sous-évalués. Cela peut laisser penser que les paris ont été faits avec une logique conservative et en évitant de tenter des scores absurdes, comme 7-0 pour l’Arabie Saoudite contre la Russie !

Analyse de données et classification

Enfin, une dernière utilisation possible de ce jeu de données est d’en faire l’analyse pour en extraire des classes de parieurs ayant un peu le même profil (ou en tout cas les mêmes réussites), et pour voir ce qui les sépare. Plusieurs méthodes sont possibles pour cela.

Commençons par un grand classique : la Classification Ascendante Hiérarchique (CAH pour les intimes), qui est une méthode qui part de groupes d’une personne, et qui, à chaque étape, regroupe deux groupes de telle façon à ce que l’inertie intra augmente au minimum. De façon moins barbare, cela veut dire qu’on regroupe les deux groupes qui se ressemblent le plus, étape par étape, jusqu’à arriver à la population totale. On représente souvent ce type de méthodes par un dendogramme, qui ressemble un peu à un arbre phylogénétique en biologie de l’évolution, et qui illustre la construction des classes, de bas en haut.

On remarque qu’il y a de nombreux binômes qui sont cohérents, et qui signalent des parieurs avec des profils comparables (par exemple, Mar et Oli, qui correspondent à deux joueurs ayant raté une bonne partie de la compétition, soit en arrêtant les paris, soit en arrivant en cours), et qu’il y a une séparation entre les quatre joueurs de gauche et les autres (eux-mêmes largement séparés entre les 3 les plus à gauche et les autres).

Une autre possibilité est d’utiliser l’Analyse en Composantes Principales, que nous avions déjà utilisé dans un contexte footballistique ici ou ici (en). La logique est ici de chercher à résumer une matrice avec beaucoup d’informations (pour chaque joueur, l’ensemble des points obtenus via ses paris pour chaque match) en un nombre minimal de dimensions, dits d’axes, qui suffisent pour avoir une bonne idée de la logique d’organisation du jeu de données.

Si l’on réalise cette méthode ici, voici ce que l’on obtient sur les premiers axes :

L’axe 1 est souvent victime de ce qu’on appelle l'”effet taille” : on entend par là le fait que les individus ayant de grandes valeurs de certaines variables en ont souvent aussi pour les autres variables, et symétriquement pour les individus qui ont des petites valeurs. En effet, on voit que la variable supplémentaire, le total de points obtenus (avec la méthode Scorecast), en bleu, est proche de l’axe 1. Cela veut dire que les individus à droite de l’axe ont tendance à avoir un score important, tandis que ceux à gauche n’ont pas très bien réussi leurs prédictions.

On constate également que les représentations sur les plans constitués des dimensions 1-2, et 2-3, ont tendance à rapprocher les individus que la classification effectuée plus haut associait en binôme. Cela montre une certaine cohérence, ce qui est toujours rassurant !

Plus dans le détail, on voit que les axes 2 et 3 semblent correspondre aux paris suivants, qui sont donc discriminants entre les différents joueurs :

  • Pour l’axe 2, avoir réussi son pari sur les matchs Pérou-Danemark, Mexique-Suède, Brésil-Suisse, Espagne-Russie et Argentine-Croatie
  • Pour l’axe 3, avoir réussi son pari sur les matchs Japon-Sénégal, Suisse-Costa Rica, Danemark-France ou encore Brésil-Mexique

Difficile de trouver une interprétation de ces axes…

Weighting tricks for machine learning with Icarus – Part 1

Calibration in survey sampling is a wonderful tool, and today I want to show you how we can use it in some Machine Learning applications, using the R package Icarus. And because ’tis the season, what better than a soccer dataset to illustrate this? The data and code are located on this gitlab repo: https://gitlab.com/haroine/weighting-ml

weighting ML gitlab
https://gitlab.com/haroine/weighting-ml

First, let’s start by installing and loading icarus and nnet, the two packages needed in this tutorial, from CRAN (if necessary):

install.packages(c("icarus","nnet"))
library(icarus)
library(nnet)

Then load the data:

load("data/weighting_ML_part1.RData")

The RData file contains two dataframes, one for the training set and one for the test set. They contain results of some international soccer games, from 01/2008 to 12/2016 for the training set, and from 01/2017 to 11/2017 for the test. Along with the team names and goals scored for each side, a few descriptive variables that we’re going to use as features of our ML models:

> head(train_soccer)
        Date                   team opponent_team home_field elo_team
1 2010-10-12                Belarus       Albania          1      554
2 2010-10-08 Bosnia and Herzegovina       Albania          0      544
3 2011-06-07 Bosnia and Herzegovina       Albania          0      594
4 2011-06-20              Argentina       Albania          1     1267
5 2011-08-10             Montenegro       Albania          0      915
6 2011-09-02                 France       Albania          0      918
  opponent_elo importance goals_for goals_against outcome year
1          502          1         2             0     WIN 2010
2          502          1         1             1    DRAW 2010
3          564          1         2             0     WIN 2011
4          564          1         4             0     WIN 2011
5          524          1         2             3    LOSS 2011
6          546          1         2             1     WIN 2011

elo_team and opponent_elo are quantitative variables indicative of the level of the team at the date of the game ; importance is a measure of high-profile the game played was (a friendly match rates 1 while a World Cup game rates 4). The other variables are imo self-descriptive.

Then we can train a multinomial logistic regression, with outcome being the predicted variable, and compute the predictions from the model:

outcome_model_unw <- multinom(outcome ~ elo_team + opponent_elo + home_field + importance,
data = train_soccer)

test_soccer$pred_outcome_unw <- predict(outcome_model_unw, newdata = test_soccer)

The sheer accuracy of this predictor is kinda good:

> ## Accuracy
> sum(test_soccer$pred_outcome_unw == test_soccer$outcome) / nrow(test_soccer)
[1] 0.5526316

but it has a problem: it never predicts draws!

> summary(test_soccer$pred_outcome_unw)
DRAW LOSS  WIN 
   0  208  210

And indeed, draws being less common than other results, it seems more profitable for the algorithm that optimizes accuracy never to predict them. As a consequence, the probabilities of the game being a draw is always lesser than the probability of one team winning it. We could show that the probabilities are not well calibrated.

A common solution to this problem is to use reweighting to correct the imbalances in the sample, which we’ll now tackle. It is important to note that the weighting trick has to happen in the training set to avoid “data leaks”. A very good piece on this subject has been written by Max Kuhn in the documentation of caret.

R package caret
https://topepo.github.io/caret/

Commonly, you would do:

train_soccer$weight <- 1
train_soccer[train_soccer$outcome == "DRAW",]$weight <- (nrow(train_soccer)/table(train_soccer$outcome)[1]) * 1/3
train_soccer[train_soccer$outcome == "LOSS",]$weight <- (nrow(train_soccer)/table(train_soccer$outcome)[2]) * 1/3
train_soccer[train_soccer$outcome == "WIN",]$weight <- (nrow(train_soccer)/table(train_soccer$outcome)[3]) * 1/3

> table(train_soccer$weight)

0.916067146282974  1.22435897435897 
             3336              1248

The draws are reweighted with a factor greater than 1 and the other games with a factor lesser than 1. This balances the predicted outcomes and thus improves the quality of the probabilities …

outcome_model <- multinom(outcome ~ elo_team + opponent_elo + home_field + importance,
data = train_soccer,
weights = train_soccer$weight)

test_soccer$pred_outcome <- predict(outcome_model, newdata = test_soccer)
> summary(test_soccer$pred_outcome)
DRAW LOSS  WIN 
  96  167  155

… though at a loss in accuracy:

> ## Accuracy
> sum(test_soccer$pred_outcome == test_soccer$outcome) / nrow(test_soccer)
[1] 0.5263158

Now let’s look at the balance of our training sample on other variables:

> round(table(test_soccer$importance) / nrow(test_soccer),2)

   1    2    3    4 
0.26 0.08 0.54 0.12 
> round(table(train_soccer$importance) / nrow(train_soccer),2)

   1    2    3    4 
0.56 0.08 0.23 0.12

It seems that the test set features a lot more important matches than the training set. Let’s look further, in particular at the dates the matches of the training set were played:

> round(table(train_soccer$year) / nrow(train_soccer),2)

2008 2009 2010 2011 2012 2013 2014 2015 2016 
0.10 0.11 0.11 0.10 0.11 0.13 0.11 0.11 0.12

Thus the matches of each year between 2008 and 2016 have the same influence on the final predictor. A better idea would be to give the most recent games a slightly higher influence, for example by increasing their weight and thus reducing the weights of the older games:

nyears <- length(unique(train_soccer$year))
year_tweak <- rep(1/nyears,nyears) * 1:nyears
year_tweak <- year_tweak * 1/sum(year_tweak) ## Normalization

> year_tweak
[1] 0.02222222 0.04444444 0.06666667 0.08888889 0.11111111 0.13333333
[7] 0.15555556 0.17777778 0.20000000

We determine it is thus a good idea to balance on these two additional variables (year and importance). Now how should we do this? A solution could be to create an indicator variable containing all the values of the cross product between the variables outcome, year and importance, and use the same reweighting technique as before. But this would not be very practical and more importantly, some of the sub-categories would be nearly empty, making the procedure not very robust. A better solution is to use survey sampling calibration and Icarus 🙂

train_soccer$weight_cal <- 1
importance_pct_test <- unname(
table(test_soccer$importance) / nrow(test_soccer),
)

marginMatrix <- matrix(, nrow = 0, ncol = 1) %>% ## Will be replaced by newMarginMatrix() in icarus 0.3.2
addMargin("outcome", c(0.333,0.333,0.333)) %>%
addMargin("importance", importance_pct_test) %>%
addMargin("year", year_tweak)

train_soccer$weight_cal <- calibration(data=train_soccer, marginMatrix=marginMatrix,
colWeights="weight_cal", pct=TRUE, description=TRUE,
popTotal = nrow(train_soccer), method="raking")

outcome_model_cal <- multinom(outcome ~ elo_team + opponent_elo + home_field + importance,
data = train_soccer,
weights = train_soccer$weight_cal)

test_soccer$pred_outcome_cal <- predict(outcome_model_cal, newdata = test_soccer)

icarus gives a summary of the calibration procedure in the log (too long to reproduce here). We then observe a slight improvement in accuracy compared to the previous reweighting technique:

> sum(test_soccer$pred_outcome_cal == test_soccer$outcome) / nrow(test_soccer)
[1] 0.5478469

But more importantly we have reason to believe that the we improved the quality of the probabilities assigned to each event (we could check this using metrics such as the Brier score or calibration plots) 🙂

It is also worth noting that some algorithms (especially those who rely on bagging, boosting, or more generally on ensemble methods) naturally do a good job at balancing samples. You could for example rerun the whole code and replace the logit regressions by boosted algorithms. You would then observe fewer differences between the unweighted algorithm and its weighted counterparts.

Stay tuned for the part 2, where we’ll show a trick to craft better probabilities (particularly for simulations) using external knowledge on probabilities.

Prédictions Eurovision 2018 – bilan

Pendant que Lisbonne se réveille sous des cris de poulet et des chats maneki-neko suite à la victoire de Netta, la candidate israélienne à l’Eurovision 2018, voici quelques commentaires à chaud sur le modèle de prédictions mis en oeuvre (détaillé ici, et repris ici pour les résultats de la finale)

Ce qu’on a réussi

La prédiction du vainqueur ! Les données Youtube étaient clairement atypiques cette année pour Israël (beaucoup plus de vues qu’une vidéo de l’Eurovision usuelle, et largement plus que les autres pays), mais cela ne prouvait pas que cette information uniquement impliquerait la victoire du pays. À voir ce qui se passera sur une année plus “classique”, mais cela reste une belle première performance.

Ce qu’on a moins bien réussi

À peu près tout le reste ! Le tableau ci-dessous récapitule nos prévisions et celles des bookmakers (arrêtées le soir de la seconde demi-finale), pour les comparer aux vrais résultats ; on calcule à chaque fois l’écart absolu, c’est à dire la différence entre la place prédite et la vraie place sans prendre en compte le signe de cette différence.

PaysModèleBookmakersRéalitéErreur modèleErreur bookmakers
Israël12101
Chypre1312111
Autriche151831215
Allemagne2274183
Italie1110565
République Tchéque311635
Suède56721
Estonie88800
Danemark1016917
Moldavie19141094
Albanie2525111414
Lituanie1441228
France7313610
Bulgarie4914105
Norvège6515910
Irlande12121644
Ukraine18201713
Pays-Bas26211883
Serbie16261937
Australie91920111
Hongrie24152136
Slovénie21242212
Espagne21723216
Royaume-Uni20232441
Finlande231325212
Portugal17222694

L’erreur totale (la somme de ces différences) est de 170 pour notre modèle, contre uniquement 138 pour les bookmakers. Nous sommes donc moins efficaces qu’eux pour l’instant, mais ce sera à charge de revanche l’année prochaine (et leur gagnant était Chypre…).

En particulier, les plus grosses erreurs de notre modèle sont l’Espagne, l’Allemagne et Chypre (même si on avait remarqué leur remontée ici). Les plus grosses erreurs des bookmakers sont la Finlande, la Norvège et la France (sur-estimée !). Enfin, les deux prévisions sont très mauvaises sur l’Autriche et sur l’Albanie, qui ont fait tous les deux un score bien meilleur qu’attendu.

Sur l’Espagne, notre supposé deuxième qui a fini dans les derniers : notre prédiction venait d’un très grand nombre de “like” sur la vidéo espagnole, qui n’est absolument pas corrélé avec le résultat définitif. Il semblerait donc que cette variable ne soit pas forcément pertinente. Ou alors cela vient du fait de la rumeur/question qui se posait sur leur couple ou non (en), qui aurait attiré un autre public plus adepte des likes ? Difficile à savoir.

Et pour l’année prochaine

Une idée : séparer le vote public et le vote des jurys ? A priori, les données Youtube devraient être plus efficaces pour prédire le vote du public. Reste à savoir ce qui peut être utilisé pour prédire le vote du jury…

Il pourrait être intéressant de voir si certains pays ont systématiquement fait mieux ou moins bien que ce que le modèle dit. Cela pourrait donner des pistes pour inclure d’autres facteurs (peut-être liés à la proximité des pays en cliques régionales ?). Il faut de toute façon améliorer le modèle au delà d’une régression linéaire.

Enfin, il sera intéressant d’intégrer le calcul des prévisions à une page qui se mettrait automatiquement à jour, par exemple tous les jours ou tous les quelques heures !

À l’année prochaine pour l’Eurovision 2019 🙂

Finale de l’Eurovision 2018 – prédictions

La finale de l’Eurovision a lieu samedi 12 mai. Voici nos prédictions pour les 26 pays y participant :

PaysScore préditPlace prédite
Israël13771
Espagne9062
République Tchéque2133
Bulgarie1874
Suède1675
Norvège1456
France1347
Estonie1188
Australie1159
Danemark10510
Italie10011
Irlande9912
Chypre9313
Lituanie9214
Autriche9015
Serbie8216
Portugal8117
Ukraine7718
Moldavie7719
Royaume-Uni7520
Slovénie7321
Allemagne7322
Finlande7123
Hongrie7124
Albanie5725
Pays-Bas5326

Eurovision 2018 – prédictions – mise à jour

Un rapide article pour intégrer les données disponibles à une semaine de la finale du concours Eurovision 2018 ! Nous allons reprendre exactement la méthode décrite ici, mais en utilisant les données de Youtube au 5 mai 2018, soit une semaine avant la diffusion de la finale.

Voici le tableau avec les scores mis à jour :

PaysÉvolution au classementScore prédit (un mois avant)Score prédit (une semaine avant)
Israël15851377
Espagne+1375906
Russie-1393372
République Tchéque210213
Bulgarie207187
Suède189167
Norvège150145
France140134
Grèce140125
Estonie130118
Australie129115
Macédoine+2117107
Azerbaïdjan-1118106
Belgique+1119106
Danemark116105
Biélorussie109103
Italie106100
Irlande+110699
Chypre+49593
Lituanie10292
Arménie10092
Autriche9990
Malte-510685
Serbie9182
Portugal8981
Ukraine+18077
Moldavie+18077
Royaume-Uni-28275
Slovénie-28073
Allemagne+27673
Suisse7772
Finlande7471
Hongrie7471
Georgie7469
Roumanie7366
Pologne+16663
Croatie-16762
San Marin6158
Albanie+15757
Montenegro-16056
Pays-Bas-15653
Lettonie+15552
Islande5136

Il n’y a pas énormément de changements, mais il y a tout de même un échange de places entre la Russie (qui a peu de chances de se qualifier en finale selon le modèle, donc qui était déjà un résultat étonnant) et l’Espagne (qui est qualifié automatiquement, donc potentiellement un favori, même si les bookmakers ne les classent que 12èmes aujourd’hui), suite à une augmentation énorme du score prédit de l’Espagne. Pour information, voici la chanson de l’Espagne :

Plus loin dans le classement, on constate des remontées de Chypre (classée 6ème selon les bookmakers) et de la République de Macédoine, dans une moindre mesure. Peut-être des pays à suivre également ? Pour se faire un avis, voici ce que propose Chypre cette année :

Bon Eurovision à tous, et à dans une dizaine de jours pour faire le bilan sur ces prédictions !

Eurovision 2018 – prédictions

Aujourd’hui un rapide article pour donner des premières prédictions pour l’Eurovision 2018, avec un modèle très simplifié basé sur les statistiques des vidéos publiées sur Youtube pour l’intégralité des pays participants, en espérant trouver le temps pour l’améliorer dans les prochaines années !

Les données

Nous allons essayer de prédire les résultats (participation à la finale – ce point avait déjà été discuté sur le blog, puis score obtenu) à partir des informations disponibles sur les vidéos Youtube : nombre de vues, nombre de “Like” (pouces vers le haut, qui indiquent que la vidéo a été appréciée) et nombre de “Dislike” (pareil mais vers le bas, qui indiquent que la vidéo n’a pas été appréciée par le spectateur).

Nous récupérons ces informations grâce au package R tuber, qui permet d’aller faire des requêtes par l’API de Youtube et ainsi de récupérer pour chacune des vidéos d’une playlist les informations nécessaires pour le modèle. Nous récupérons alors les données pour les chansons des concours 2016, 2017 et 2018. Ces informations sont ensuite complétées avec le nombre de points obtenus et le rang du classement final pour les finalistes des éditions 2016 et 2017. Les données sont disponibles ici.

Évidemment, ces données ont leurs limites. Je n’ai pas trouvé comment rechercher des informations sur les vidéos Youtube à une autre date, ce qui fait que l’on va utiliser des données après la diffusion des concours 2016 et 2017 pour évaluer un modèle, que l’on appliquera à des données avant le concours pour 2018. Par ailleurs, le système de notation a évolué en 2016, ce qui explique pourquoi on se limite aux données sur les deux dernières années pour notre modèle. Par ailleurs, pour lisser les effets de taille (1 millions de vues en moyenne pour les vidéos 2018 contre 5 millions pour celles de 2016), nous travaillons sur des données standardisées en divisant par la moyenne du nombre de vues, de likes, etc.

Le modèle

Nous travaillons ensuite sur deux problèmes : estimer la probabilité qu’une chanson soit qualifiée en finale, puis estimer le score qu’elle va obtenir, pour évaluer son classement final. En ce qui concerne la probabilité de qualification en finale, nous réalisons une régression logistique. La seule variable qui ressort est le nombre de Dislike, qui influe légèrement négativement la chance d’être qualifié. C’est assez logique : moins la vidéo est appréciée, moins il y a de chances que le pays soit qualifié en finale.

En ce qui concerne le nombre de points obtenus, nous testons deux approches concurrentes :

  • Une régression linéaire sur les variables : dans ce cas, on observe que le nombre de vues ne joue pas significativement, le nombre de Likes de façon très mineure et le nombre de Dislikes très nettement, avec un lien positif : plus il y a de pouces baissés, plus le score est important. Ce résultat atypique peut s’expliquer par le fait que la vidéo ukrainienne en 2016, gagnante, a plus de 40 000 pouces baissés.
  • Un arbre de régression qui permet de séparer à chaque étape la population en deux et d’évaluer un score moyen. Cette méthode est moins efficace pour prédire le score exact, mais elle permet d’identifier les déterminants du score. L’arbre ci-dessous décrit la partition des vidéos :

Cet arbre se lit de la façon suivante :

  • Si l’on a plus de 2,216 fois le nombre de vues moyen des vidéos de l’année, alors le score prédit par la méthode est 425 (les vidéos populaires ont des scores importants). Sinon, on passe à l’étape suivante
  • Si l’on a moins de 89% du nombre de Likes moyen des vidéos de l’année, alors on part dans le sous-arbre encadré en bleu ; si c’est plus, dans celui encadré en vert.
  • L’opération se répète jusqu’à qu’on arrive à un carré en bas de l’arbre, où l’on lit le score prévu

Les résultats

Voici les prédictions obtenues, en utilisant la méthode de régression linéaire pour le score total :

PaysProba d'aller en finaleScore prédit
Israël99%1585
Russie25%393
Espagne100%375
République Tchéque99%210
Bulgarie99%207
Suède94%189
Norvège74%150
France100%140
Grèce97%140
Estonie71%130
Australie75%129
Belgique74%119
Azerbaïdjan83%118
Macédoine67%117
Danemark85%116
Biélorussie78%109
Italie100%106
Malte79%106
Irlande73%106
Lituanie77%102
Arménie62%100
Autriche70%99
Chypre62%95
Serbie42%91
Portugal100%89
Royaume-Uni100%82
Ukraine38%80
Moldavie29%80
Slovénie19%80
Suisse48%77
Allemagne100%76
Finlande31%74
Hongrie28%74
Georgie15%74
Roumanie31%73
Croatie19%67
Pologne34%66
San Marin10%61
Montenegro16%60
Albanie21%57
Pays-Bas15%56
Lettonie16%55
Islande9%51

Le grand gagnant est Israël, ce qui est plus ou moins la prédiction faite par tout le monde : voir ici ou ici. À noter que l’année dernière, l’Italie était grande favorite (et a fini 6ème), donc rien n’est encore fait… Si vous voulez vous faire une idée :

Un résultat plus étonnant concerne la Russie. Elle est classée deuxième par notre modèle, mais avec une faible chance d’être qualifiée en finale. Cela semble venir d’un très haut nombre de pouces baissés sur la vidéo, qui influencent énormément notre prédiction. La Russie est placée 25ème par les bookmakers, donc à voir si notre modèle a détecté quelque chose ou s’il s’agit d’un cas de surapprentissage. Pareil, pour se faire un avis :

Et enfin, soyons chauvins ! Nous serions dans le top 10 avec Mercy. C’est d’ailleurs cohérent avec les estimations des bookmakers. Tout est donc encore possible 😉

Chance et talent dans le sport

(Ce petit article est une reprise d’un fil twitter fait à l’occasion du Final Four de la NCAA)

Aujourd’hui on propose de prendre un peu de temps pour discuter des notions de “chance” (luck) et de “talent” (skill) dans le domaine du sport, en s’inspirant d’arguments exposés dans The Success Equation: Untangling Skill and Luck in Business, Sports, and Investing, sorti en 2012. La question qui se pose est la suivante : dans les résultats d’une équipe sportive ou d’un athlète, qu’est-ce qui vient de l’habileté et qu’est-ce qui relève uniquement de la chance ? Même si l’on faisait l’hypothèse que le déterminant principal d’un résultat est le talent de l’athlète, certaines sous-performances peuvent arriver.

C’est un sujet assez classique, qui est développé dans la plupart des études statistiques sur le sport. Pour ceux qui préfèrent le format vidéo, voici un résumé rapide de ce qu’explique le livre :

Mathématiquement, on considère que le skill et la chance sont deux variables indépendantes. On peut donc écrire une équation très simple sur leur variance :

Var(observations) = Var(skill) + Var(chance)

Cela nous donne donc une façon d’estimer la contribution du skill dans les résultats, c’est à dire une idée de l’importance du talent de l’athlète :

Var(skill) = Var(observations) – Var(chance)

Plus ce terme est important, plus les résultats obtenus proviennent du fait que le sport récompense les joueurs qui ont du talent. Dans un jeu complètement aléatoire (pile ou face…), c’est uniquement la chance qui amène au résultat final. On imagine alors que chaque sport va plus ou moins s’éloigner de ce modèle.

Nous avions discuté de cette question par rapport au badminton et au tennis ; on constatait alors que, grâce à la règle de l’écart des deux points, il y avait une plus grande stabilité des victoires (et donc une plus faible part de chance) au tennis qu’au badminton. Une même question se posait sur le tir à l’arc, avec le changement des règles qui permet plus facilement de rattraper une flèche ratée.

Comment faire pour estimer cette contribution ? Pour le premier terme, Var(observations), c’est facile. On considère les résultats (d’une saison par exemple) comme une variable aléatoire et on calcule sa variance. On constate que certains sports sont plus variables que d’autres, par exemple le basket par rapport au hockey :

Le seconde terme, Var(chance), est un peu plus complexe à estimer. Dans son son livre, Mauboussin prend chaque match comme une expérience de Bernoulli (avec une probabilité de victoire qui correspond au taux de victoire dans la saison). Il obtient donc, par sport, un pourcentage d’explication du skill dans le résultat final. Par exemple, pour la NBA il obtient 88% et pour la NHL 47%.

Une bonne part de la variance s’explique en fait par le nombre de matches joués, qui correspond dans la logique à la “taille d’échantillon”. La NFL (16 matches / saison) est donc logiquement plus aléatoire que la NBA (82 matches / saison) sur l’axe skill / chance représenté en haut de l’article. On peut aussi appliquer le même concept en considérant chaque “action” comme une expérience aléatoire. Par exemple, chaque possession au basket, comme une chance de marquer avec une certaine probabilité. C’est pour cela l’on s’attendait à ce que l’underdog Loyola-Chicago essaye de jouer le plus lentement possible.

L’idée derrière cette stratégie est que moins de possessions implique plus de variance et donc moins de chances de l’emporter pour le favori ; en effet, plus l’on joue, plus l’aléatoire doit s’équilibrer et donc le talent va s’imposer. La validité de cette stratégie est disputée : certaines analyses statistiques ont montré que les chances de victoires des équipes mal classées (underdogs) contre des équipes réputées bien meilleures n’était pas modifiées par le rythme du match.

Pour conclure, le même genre d’analyse a été appliqué récemment (avec plus ou moins de succès) à l’esport. Yauheni Hladki a présenté à la GDC une analyse dont le résultat situe tous les jeux (oui, tous, même Hearthstone) à la droite des échecs sur l’axe skill / chance. Ce qui signifierait que la chance aurait moins d’impact sur le résultat que dans la plupart des sports. En d’autres termes, qu’une équipe mal classée de CS:GO n’aurait que des chances infimes de remporter un match contre une équipe du top mondial… pas terrible pour le suspense si cela était vrai !

La “clé” derrière ce résultat est que l’auteur considère chaque action effectuée en esport comme une expérience aléatoire. Cela inclut par exemple chacun des tirs effectués dans une partie de CS:GO ! La taille d’échantillon “équivalent” considérée est énorme (la variance obtenue est donc très faible) et c’est ce qui le conduit à placer tous les esports au même endroit sur l’axe. À vous de juger de la pertinence de cette méthode !

 

On a tous en nous quelque chose…

Un petit article pour réagir à l’actualité très récente de ces derniers jours, c’est à dire la mort de Johnny Hallyday ; si vous n’êtes pas au courant, c’est que vous vivez dans une grotte (voir ici par exemple). Cet immense chanteur a fait une très grande carrière et fait partie du patrimoine musical français. Depuis son décès, les radios et les chaînes de télévision diffusent plus ou moins en boucle ses titres, en hommage. C’est d’ailleurs ce qui nous amène à la question du jour : combien de temps cela prendrait à diffuser la totalité de l’oeuvre de Johnny à la radio ?

Pour répondre à cette question, nous allons utiliser l’article Wikipedia sur sa discographie, très bien fourni. Il faut évidemment se limiter à un certain nombre d’albums : on va choisir les albums studios, en excluant ceux faits exclusivement pour l’étranger, qui ne seraient pas diffusés sur une radio française. Le jeu de données est disponible ici, si vous souhaitez l’utiliser.

Le résultat, sans plus attendre, est que la cinquantaine d’albums studio de Johnny demanderait 36 heures, 2 minutes et 22 secondes à être diffusée ! Soit, en sachant que sa mort a eu lieu aux environs de 2h du matin le mercredi 6 décembre 2017, cela veut dire que si une radio l’avait appris directement, elle aurait pu diffuser en boucle sans jamais se répéter des titres du chanteur jusqu’à jeudi 7 à 14h. Et encore, on ne compte pas les albums live !

On peut également utiliser ce jeu de données pour regarder la durée moyenne des chansons. Plusieurs études ont montré que la longueur des chansons a évolué dans les dernières décennies, avec un minimum dans les années 60 et un maximum dans les années 90. Un graphe animé est disponible ici :

On peut faire le même graphe pour les chansons de notre idole des jeunes, et on se rend compte que l’on retrouve quasiment la même courbe ! Il était donc bien un reflet de son époque.

Et enfin, est-ce que vous saviez que Johnny et Pasteur étaient morts dans la même ville ? Peut-être une idée pour un prochain article, d’ailleurs…

Reports de voix à la présidentielle 2017

La question du report des voix entre les deux tours des élections, souvent primordiale pour les politologues et les journalistes politiques, s’est posée de façon particulièrement cruciale pour l’élection présidentielle 2017. En effet, les deux candidats qualifiés étaient issues de nouvelles formations, ou du moins de formations qui n’ont pas l’habitude de participer au second tour de la présidentielle (une fois pour le Front National, et jamais pour En Marche !). Nous allons reprendre la même façon d’aborder cette question que ce que nous avions fait pour l’élection présidentielle de 2012, en décembre dernier.

Les analyses de “report de voix” utilisent des données de sondage mais nous allons reprendre ici l’approche basée sur l’analyse de l’évolution du vote pour chacune des villes entre les deux tours de l’élection. Les données relatives au vote pour chacune des villes sont disponibles ici (premier tour) et ici (second tour).

Nous réalisont alors un modèle de régression linéaire entre les deux tours, pour évaluer quelle partie des votes alloués à chaque candidat au premier tour se reporte sur l’un des deux challengers, ou n’est pas exprimée (abstentions, blancs). Les résultats sont les suivants :

Macron Le Pen
Le Pen < 1 % 112 %
Macron 116 % < 1 %
Fillon 58 % 19 %
Melenchon 48 % 10 %
Dupont-Aignan 39 % 36 %
Hamon 95 % < 1 %
Asselineau 22 % 32%
Arthaud 51% 41%
Poutou 56 % 13 %
Cheminade 44 % 21 %
Lassalle 48 % 23 %

ou sous forme de graphique :

Comme nous l’avions déjà indiqué la dernière fois, il ne s’agit que d’un petit modèle sans grande prétention, et cela ne veut pas dire que 23% des électeurs de Jean Lassalle ont voté pour Martine Le Pen au second tour, mais on peut en déduire quelques remarques :

  • La somme des pourcentages donne une idée des électeurs qui n’ont pas souhaité participer au second tour. On voit que les électeurs de Asselineau puis de Mélenchon sont ceux qui ont le plus souvent voté blanc ou qui se sont abstenus au second tour ;
  • Inversement, pour Macron et Le Pen on observe un score estimé supérieur à 100%, cela signifierait que la mobilisation des électeurs ayant ces deux candidats préférés au premier tour se sont plus mobilisés au second ;
  • Les électeurs insoumis qui ont souhaité exprimer un vote en faveur d’un des deux candidats ont majoritairement choisi Macron ;
  • L’accord électoral entre Marine le Pen et Nicolas Dupont-Aignan n’aurait pas convaincu son électorat, qui se partagerait en parts égales pour les deux candidats ;
  • Le vote Hamon s’est quasiment à 100 % reporté sur le vote Macron ; ce n’est pas le cas de celui Fillon, qui s’est reporté de façon non négligeable pour Marine le Pen, et qui a entraîné plus d’abstention ou de vote blanc.

En comparaison, les reports de voix à la présidentielle 2012 étaient les suivants :

A shiny app to convert sports scores

I’m a huge sports fan, but I certainly don’t have extended knowledge about all team sports. Sometimes when I hear about scores in a sports I’m not quite “fluent” in, I wonder how they would translate in a sports I know better. I guess many people ask the same question from time to time. For instance, three years ago, many americans started wondering how the 7-1 blowout that happened during the World Cup semifinals would translate in basketball, football or hockey. ESPN first came up with an absurd answer, and then Neil Paine of FiveThirtyEight wrote a much more sensible paper on the question.

I created a shiny app that finds a statistical equivalent of a game score in one sports in other sports:

The program is very simple, let me show you on an example how it works. Suppose you want to know how a 103 – 97 home win in basketball translates in other sports.

The program starts by computing the score difference between the two teams (103-97 = +6), and looks how many basketball games have ended with a home team win by 6 points or less. In this case, the number is 30.7% of games.

Histogram and density of score differences in basketball games

Then the program looks among the home wins in other sports what score difference corresponds to the same 30.7% (the 30.7% quantile). This corresponds to +1 in soccer and hockey and +6 in football.

Finally, it does the same operation by comparing the offensive score of the winning team. In 50.4% of basketball games, the home team scores 103 points or less when it wins, which corresponds to 2 scored goals in soccer, 4 in hockey and 28 points scored in football. The final result is thus:

The full code of the shiny app is available on the GitHub page of the project. The dataset is made of all NBA, NHL, NFL and Champions League games since the year 2000. If you want to see other sports, make a pull request or ping us on Twitter or Mastodon!