GLM Poisson avec R : Tutoriel Complet
GLM Poisson avec R : Tutoriel Complet
Rappels
Les modèles linéaires classiques ne sont pas adaptés pour analyser des
variables à expliquer (ou réponses) de type “comptage”, notamment parce qu’ils supposent
que celles-ci sont distribuées selon une loi Normale. Cette hypothèse conduit alors à
considérer que la variance des résidus est homogène, autrement dit constante, quelle que
soit la valeur des comptages moyens prédits par le modèle. Or, les données de type
comptage ne sont pas distribuées selon une loi Normale, mais selon une loi de Poisson. Et
compte tenu de cette loi de distribution, la variance des résidus n’est pas constante mais
proportionnelle aux comptages moyens prédits par le modèle.
Cette différence n’est pas une nuance, elle est capitale ! Utiliser un modèle linéaire classique
pour traiter des réponses de type “comptage” peut entraîner, entre autres, une estimation
biaisée de l’erreur standard des paramètres du modèle, ce qui peut conduire à une
estimation erronée de la p-value, et à une conclusion inexacte.
De plus, l’utilisation de modèles linéaires classiques pour analyser des données de type
comptage peut conduire à des prédictions négatives. Voir un exemple ici .
La distribution de Poisson
On dit qu’une variable aléatoire Y suit une distribution de Poisson de paramètre Lambda,
si elle prend pour valeur y = 0 ,1,2,3,… avec une probabilité P définie par :
Pr(Y=y)=e−λλyy!
La distribution de Poisson est ainsi définie par un seul paramètre : Lambda. Pour fixer
les idées, voici quelques exemples de distribution, pour des valeurs de Lambda variant entre
0.1 et 30.
E(y)=λ
La variance d’une variable aléatoire distribuée selon une loi de poisson est aussi égale
à Lambda :
Var(y)=λ
Comme expliqué dans l’article d’introduction aux GLM, ces modèles sont constitués de trois
éléments :
un prédicteur linéaire,
une fonction de lien Log
une structure d’erreur de Poisson
Le prédicteur linéaire du GLM suppose simplement que les réponses prédites par le modèle
linéaire généralisé vont l’être à partir d’une combinaison linéaire des variables prédictives.
µy=∑j=1pβjXij
η=∑j=1pβjXij
Cependant, contrairement aux modèles linéaires classiques, les valeurs prédites par le
prédicteur linéaire du GLM ne correspondent pas à la prédiction moyenne d’une
observation, mais à la transformation (par une fonction mathématique) de celle-ci. Dans
le cas de la régression de Poisson il s’agit de la transformation log. Ce lien est défini par
l’équation suivante :
log(µy)=∑j=1pβjXij
En pratique, cela signifie que les valeurs du prédicteur linéaire sont obtenues en transformant
préalablement les valeurs observées par la fonction de lien. Autrement dit, les beta sont
estimés après transformation des réponses par la fonction Log.
Pour obtenir la prédiction moyenne, il est alors nécessaire d’appliquer la fonction inverse
du Log, c’est à dire la fonction exponentielle :
µy=e∑pj=1βjXij
Les modèles de régression de Poisson ont une structure d’erreur de Poisson. Cette structure
d’erreur, permet notamment de spécifier correctement la relation entre la moyenne et la
variance. Cette relation est utilisée par l’approche de maximum de vraisemblance pour
estimer les coefficients et les erreurs standard des paramètres du modèle GLM.
Les résultats issus des modèles de régression de Poisson sont valides si:
L’indépendance des réponses signifie qu’elles ne doivent pas être corrélées entre elles. Par
exemple, il ne doit pas avoir de lien entre une réponse et celle de la ligne suivante, ou
précédente, dans le jeu de données. On voit cela, lorsque des données sont répétées sur des
sujets, ou des unités expérimentales identiques.
L’indépendance des réponses se valide par l’étude du plan expérimental : pour réaliser une
régression de Poisson, il ne doit pas avoir de données répétées. Si c’est le cas, il faut utiliser
un autre type de modèle, comme un modèle linéaire généralisé à effet mixte (Generalized
Linear
Mixed Models, ou GLMM).
Cliquez ici pour accéder à l'article dédié aux GLMM avec des données de proportions
La distribution des réponses (selon une loi de Poisson) est généralement supposée.
Néanmoins, cette hypothèse peut être explorée en comparant la distribution des
comptages observés à la distribution théorique des comptages sous une loi de poisson de
paramètre Lamda, estimé par la moyenne des comptages observés. Si cette hypothèse est
rejetée, un autre structure d’erreur devra être utilisée dans le GLM.
Absence de surdispersion
La variance des réponses est, selon la théorie, c’est à dire selon la loi de Poisson, égale à la
moyenne des réponses. On dit qu’il y a surdispersion lorsque la variance réelle est
supérieure à cette variance théorique. Cela est problématique car dans cette
situation, l’erreur standard des paramètres des modèles de régression de Poisson sera
sous estimée. Ceci peut conduire à une p-value excessivement faible, et donc aboutir à
une conclusion erronée sur la significativité de la liaison entre les comptages observés et la
ou les variables explicatives.
Le paramètre phi permet d’estimer si la variance réelle des observations n’est pas trop
éloignée de la variance théorique :
En pratique, phi est estimé par le ratio de la déviance résiduelle sur le nombre de degrés de
libertés du modèle :
ϕˆ=devianceresiduellenddl
Si ce ratio est supérieur à 1, alors il y a surdispersion. Mais cette supériorité à 1 est un peu
subjective, dans le sens ou il n’existe pas de seuil (1.5, 2 ?) à partir duquel on considère qu’il
y a surdispersion. En réalité ce seuil dépend aussi du nombre de données considérées.
Certains packages, notamment `AER`, propose un test statistique pour aider à la prise de
décision.
Les principales cause des surdispersion sont :
En cas de surdispersion, il est nécessaire d’utiliser d’autres structures d’erreur, telles que
les structures “quasi Poisson” ou “négative binomiale“.Celle-ci vont conduire à une
augmentation de l’erreur standard des paramètres du modèle, par un facteur :
(√ϕˆ)
Pour plus d’informations sur la surdispersion, vous pouvez consulter ces diapositives crées
par Arthur Charpentier.
Les data
Dans la suite de cet article, je vais vous montrer comment réaliser une régression linéaire
simple lorsque la variable réponse est de type comptage. Puis dans un second temps, je vous
montrerai, dans la même situation, comment réaliser une analyse de type ANOVA à un
facteur.
Pour illustrer ces deux types d’analyse, je vais utiliser le jeu de données “Orstein” du
package “car”.
library(car)
data(Ornstein)
Ce jeu de données concerne les 248 compagnies les plus importantes du Canada dans les
années 70. Il comporte 4 variables :
Expliquer
str(Ornstein)
## $ assets : int 147670 133000 113230 85418 75477 40742 40140 26866 24500 23700
Dans cette analyse, nous allons étudier la relation entre la variable réponse “interlocks” et
la variable explicative “assets”.
log(μy)=β0+β1∗log10(assets)i
Visualisation de la relation
geom_point()
La variable assets est extrêmement étendue, nous allons alors utiliser une transformation
log10.
geom_point()
La transformation log10 permet également de linéariser la relation, elle est donc
nécessaire.
mean(Ornstein$interlocks)
## [1] 13.58065
Puis on simule des comptages selon une distribution de Poisson de paramètres Lambda =
13.58.
Expliquer
theoretic_count <-rpois(248,13.58)
tc_df <-[Link](theoretic_count)
library(ggplot2)
ggplot(Ornstein,aes(interlocks))+
geom_bar(fill="#1E90FF")+
theme_classic()+
theme([Link]="none")
Les comptages observés (variable interlock) sont en bleu et les comptages théoriques en
[Link] peut voir que les deux distributions sont très différentes. La variable interlock ne
suit donc pas une distribution de Poisson de paramètre lambda = 13.58. On peut
également voir une sur-représentation des valeurs zéro dans les comptages observés ; il est
donc très probable qu’une surdispersion soit mise en évidence.
Evaluation de la surdispersion
Expliquer
summary(mod.pois1)
##
## Call:
##
## Deviance Residuals:
##
## Coefficients:
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
##
## AIC: 2806.7
##
Le ratio residual deviance / ddl est égal à 1904.7 /246, soit 7.74. Ce ratio est très largement
supérieur à 1 et permet de mettre en évidence la présence d’une surdispersion. Il est donc
nécessaire d’utiliser une autre structure d’erreur dans le modèle de régression.
Comme expliqué précédemment, l’utilisation d’une structure d’erreur “quasi poisson” à pour
conséquence d’augmenter l’erreur standard des paramètres.
Expliquer
summary(mod.quasipois1)
##
## Call:
## data = Ornstein)
##
## Deviance Residuals:
##
## Coefficients:
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
##
##
Ici l’erreur standard associé à log10(assets) est égale à 0.07, alors qu’elle était estimée à 0.02
avec la structure d’erreur de Poisson (cf la sortie ci dessous):
Expliquer
summary(mod.pois1)
##
## Call:
## data = Ornstein)
##
## Deviance Residuals:
##
## Coefficients:
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
##
## Null deviance: 3737.0 on 247 degrees of freedom
## AIC: 2806.7
##
En cas de surdispersion, il est également possible d’utiliser une structure d’erreur quasi
binomiale. Pour cela, on utilise la fonction [Link]() du package MASS. Par défaut, la
fonction de lien utilisée est également la fonction log :
Expliquer
library(MASS)
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
##
## AIC: 1694.8
##
##
## Theta: 1.301
##
## 2 x log-likelihood: -1688.811
Avec cette structure d’erreur, l’erreur standard associée à log10(assets) est estimée à
0.09. Cette correction entraîne une modification très importante de la z value, qui passe
de 44.22 avec une structure d’erreur de Poisson à 11.257 ici. Dans d’autres situations, cela
pourrait également avoir un impact très important sur la p-value, et donc sur les conclusions.
En reprenant les résultats obtenus avec la structure d’erreur “quasi poisson”, les résultats sont
obtenus à l’aide de la fonction summary() :
Expliquer
summary(mod.quasipois1)
##
## Call:
## data = Ornstein)
##
## Deviance Residuals:
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
##
## AIC: NA
##
Comme rappelé précédemment, dans une régression de poisson, c’est le log de la moyenne
des comptages qui est modélisé :
log(μy)=β0+β1∗log10(assets)i
Pour exprimer le coefficient de régression dans l’échelle originale, c’est à dire en nombre
d’interlocks, plutôt qu’en log du nombre d’interlocks, il est nécessaire d’appliquer
la transformation inverse du log, c’est à dire la transformation exponentielle.
e1.05=2.86
Au final, en exprimant également les actifs dans leur échelle originale, on peut dire que le
nombre de postes d’administrateurs partagés augmente en moyenne de 2,86 lorsque les actifs
de la compagnie sont multipliés par 10 (puisqu’un unité en log10, correspond à un facteur 10).
Prédictions
Pour cela, on crée un data frame nommé “mydf” (par exemple) contenant les niveaux
d’actifs pour lesquels on souhaite obtenir une estimation, ici par exemple,
100,1000,5000,10000, 50000,et 100000. Il est très important d’utiliser le même nom de
variable que dans le fichier de données utilisé lors de l’ajustement du modèle.
[Link](mod.quasipois1,newdata = mydf,type="response")
## 1 2 3 4 5 6
Par défaut, la fonction [Link]() utilise l’argument type=”link”, ce qui renvoi des
prédictions dans l’échelle log :
[Link](mod.quasipois1,newdata = mydf)
## 1 2 3 4 5 6
Visualisation du modèle
Le principe est de créer un vecteur de valeurs de assets compris entre les valeurs min et
max observées, puis de le passer dans un data frame.
Dans un second temps, la fonction [Link]() est employée pour prédire le nombre
moyen d’interlock pour chaque valeurs du vecteur créé précédemment. Ces prédictions
sont ajoutées au data frame.
Expliquer
head(predicted)
## assets interlocks
## 1 62.0000 2.337324
## 2 209.7558 4.084994
## 3 357.5115 5.215213
## 4 505.2673 6.110688
## 5 653.0230 6.872642
## 6 800.7788 7.545750
Enfin le plot est réalisé :
library(ggplot2)
Pour illustrer ce cas de figure, nous allons comparer le nombre moyen de postes
d’administrateurs, en fonction de la nation contrôlant la compagnie. Cette analyse n’est
pas particulièrement judicieuse, car, ici, seule la variable explicative nation est inclue. Cette
analyse sert seulement d’[Link] plus d’information sur l’ANOVA à un facteur,
consultez cet article d’introduction à l’ANOVA à un facteur.
Visualisation
Une première visualisation permet d’appréhender les données :
geom_boxplot(alpha=0.5, [Link]=0)+
geom_jitter()
Les moyennes peuvent être facilement calculées en couplant les fonctions group_by() et
summarise() du package dplyr.
Expliquer
group_by(nation) %>%
summarise(avg=mean(interlocks))
avg
## # A tibble: 4 x 2
## nation avg
##
## 1 CAN 19.6
## 2 OTH 14.2
## 3 UK 8.71
## 4 US 7.04
Les intervalles de confiance peuvent être obtenus en employant une approche bootstrap par
l’intermédiaire de la fonction slipper() du package slipper.
Expliquer
library(slipper)
[Link](1234)
Ornstein %>%
filter(nation == "CAN")%>%
slipper(mean(interlocks),B=1000) %>%
filter(type=="bootstrap") %>%
summarize(ci_low = quantile(value,0.025),
ci_high = quantile(value,0.975))
## ci_low ci_high
## 1 15.98996 23.41944
[Link](1234)
Ornstein %>%
filter(nation == "OTH")%>%
slipper(mean(interlocks),B=1000) %>%
filter(type=="bootstrap") %>%
summarize(ci_low = quantile(value,0.025),
ci_high = quantile(value,0.975))
## ci_low ci_high
## 1 9.333333 19.05556
C’est un peu fastidieux de le faire pour chaque nation, mais au final on obtient :
Expliquer
avg=c(19.6,14.2,8.71,7.04),
binf=c(15.99,9.33,5.65,5.59),
bsup=c(23.42,19.05,11.95,8.49))
avg_ci
Evaluation de la surdispersion
Expliquer
summary(fit_p)
##
## Call:
##
## Deviance Residuals:
##
## Coefficients:
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
##
## AIC: 3970.5
##
Le ratio residual deviance / ddl est égal à 3064.5 /244, soit 12.56. Ce ratio est très
largement supérieur à 1 et permet de mettre en évidence la présence d’une surdispersion.
Expliquer
library(AER)
dispersiontest(fit_p)
Overdispersion test
data: fit_p
sample estimates:
dispersion
13.6299
Au final, il est donc nécessaire d’utiliser une autre structure d’erreur dans le modèle de
régression.
Comme précédemment, nous allons pouvoir utiliser les structures d’erreur de type “quasi
Poisson” et “negative binomial“
Expliquer
summary(fit_qp)
##
## Call:
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
##
## AIC: NA
##
Expliquer
##
## Call:
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
##
## AIC: 1767.1
##
##
##
## Theta: 0.9312
##
## 2 x log-likelihood: -1757.148
Comme attendu, dans les deux cas, les erreurs standard des paramètres ont été largement
augmentées.
Expliquer
library(car)
Anova(fit_qp, test="F")
Response: interlocks
Error estimate based on Pearson residuals
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Il est nécessaire de spécifier test=”F” afin d’obtenir un test F et non pas un test du Chi2,
réalisé par défaut. Le test F étant le test à utiliser en cas de surdispersion.
Ici, les résultats montrent que deux moyennes, au moins, sont différentes.
Comparaisons multiples
Afin d‘identifier qu’elles sont les différences, nous pouvons réaliser toutes les comparaisons
deux à deux à l’aide du package multcomp et de sa fonction glht(). Pour plus de détails,
consultez cet article.
Expliquer
library(multcomp)
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
par(mar=c(3,7,3,3))
plot(mc_tukey)
Le package multcomp, contient également une fonction cld() qui permet, dans le cadre du test
de Tukey, d’indiquer par des lettres la significativité des comparaisons. Lorsque deux
modalités partagent une même lettre, cela signifie que leurs différences ne sont pas
significativement différentes. A l’inverse, lorsque deux modalités ne partagent pas de lettres
en commun, alors cela signifie que leurs moyennes sont significativement différentes.
Expliquer
[Link]
## CAN OTH UK US
Comme expliqué dans un de mes précédents articles, on peut alors utiliser ces lettres pour les
ajouter sur un graph réalisé avec ggplot2.
Accéder à l'article "Comment indiquer les résultats des comparaisons sur une graph"
Expliquer
myletters_df
## nation letters
## CAN CAN c
## OTH OTH bc
## UK UK ab
## US US a
geom_boxplot([Link] = 0, alpha=0.25)+
geom_jitter(width=0.25)+
theme_classic()+
theme([Link]="none")+
theme([Link].x = element_text(angle=30, hjust=1, vjust=1))+
On peut également obtenir les intervalles de confiance des niveaux moyens, comme ceci:
Expliquer
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
##
## AIC: NA
##
Le modèle ayant été ajusté sans intercept (grâce au -1), les coefficients fournis pas la fonction
summary() correspondent au log des niveaux moyens de chaque nation. On peut également
les obtenir par :
coef(fit_qp2)
Pour les obtenir dans l’échelle originale, c’est à dire en nombre de postes partagés, il est
nécessaire d’utiliser la transformation exponentielle :
exp(coef(fit_qp2))
Expliquer
exp(confint(fit_qp2))
## 2.5 % 97.5 %
Ils sont légèrement différents de ceux obtenus par bootstrap, cela n’est pas étonnant, car
l’approche par bootstrap est basée sur des tirages aléatoires.
J’espère que cet article aura répondu à un grand nombre de questions que vous vous
posiez au sujet des GLM pour données de comptage, qu’elles soient d’ordre théorique
ou pratique. Si certaines interrogations subsistent, indiquez-les-moi en commentaire, et
j’essaierai de vous apporter une réponse.
Si cet article vous a plu, ou vous a été utile, et si vous le souhaitez, vous pouvez soutenir
19 Responses
1. Dany OTRON dit :
Répondre
2. Basso dit :
Répondre
Bonjour Claire. Félicitations et merci pour cet article très bien élaboré qui, à coup sûr,
améliorera la compréhension de beaucoup sur les G LM.
Répondre
merci
Répondre
5. Stéphane dit :
28 février 2019 à 9 h 03 min
Répondre
6. Anomyne dit :
Allo ! Merci beaucoup pour cet article ! Enfin je comprends la logique de ce que je fais !
J’aurais néanmoins besoin d’une petite aide: je me suis rendu à la fin de ton article où on peut
utiliser les lettres de des comparaisons multiples pour les ajouter sur un graphique réalisé avec
ggplot2.
J’ai générée mes lettres sans problèmes mais pour le graphique, j’ai ce message d’erreur :
> myletters_df str(monochamus)
‘[Link]’: 240 obs. of 3 variables:
$ test_de_choix: Factor w/ 6 levels “leg-mod”,”leg-mort”,..: 1 1 1 1 1 1 1 1 1 1 …
$ buche : Factor w/ 4 levels “leg”,”mod”,”mort”,..: 1 2 1 2 1 2 1 2 1 2 …
$ larves : int 0 0 0 0 0 0 18 0 0 0 …
> head(monochamus)
test_de_choix buche larves
1 leg-mod leg 0
2 leg-mod mod 0
3 leg-mod leg 0
4 leg-mod mod 0
5 leg-mod leg 0
6 leg-mod mod 0
Peux-tu m’aider ?
Répondre
7. ATTIYA dit :
Bonjour
Je vous remercie infiniment pour votre effort de partage. Cet article m’a été d’une aide
inestimable sauf que la surdispertion dans mon cas est surtout due à un excès des valeurs zero
et j’aimerai réaliser une régression zero-inflated. Si vous avez un article pratique le détaillant
je vous serai très reconnaissant car j’admire votre façon très didactique de présenter les
choses.
Cordialement et grand merci
Répondre
8. Sarr dit :
Répondre
9. Yapoto dit :
Répondre
Répondre
Merci Mme
j’aimerais savoir pourquoi vous n’avez pas utilisé toutes les variables explicatives ensemble
pour voir les effets?
merci de m’apporter des reponses
Répondre
Bonjour,
parce que je voulais seulement traiter un exemple simple, alors une seule variable explicative
me paraissait suffisant ! Mais vous pouvez en inclure plusieurs.
Bonne continuation.