4.2 Applications en R
Utilisons la base de données du cours pour estimer un modèle de régression Poisson, et voir les différents estimés de variance des paramètres.
Par contre au lieu d’utiliser la totalité de la base de données pour faire l’estimation des paramètres du modèle, on divisera cette base de données en 2 parties: la partie TRAIN et la partie TEST. Les paramètres et l’analyse statistique se fera sur la partie TRAIN alors que la comparaison de la qualité de prédiction des modèles se fera sur la partie TEST. Nous élaborerons davantage sur la qualité de prédiction dans un prochain chapitre.
<- db.fictif %>% filter(Type=='TRAIN')
db.train <- db.fictif %>% filter(Type=='TEST') db.test
4.2.1 Algorithme Newton-Raphson
Un algorithme de type Newton-Rapshon peut être programmé pour estimer les paramètres de la régression Poisson. Remarquez l’utilisation de la variable expo dans l’évaluation du paramètre \(\lambda\).
### Algorithme Newton-Raphson maison
## Initialisation
# Generer la matrice des X
<- as.formula(nb.sin ~ couleur + myopie + type_territoire + langue + alimentation)
score.glm <- model.matrix(score.glm, db.train)
Matrix.X # Generer le vecteur des Y
<- as.matrix(db.train$nb.sin)
Vect.Y <- as.matrix(db.train$expo)
Vect.expo # Valeur initiale des beta
<- rep(0, ncol(Matrix.X))
Beta 1] <- log(mean(Vect.Y))
Beta[
## Loops Newton-Raphson
<- 1
max.U <- 0
arret <- 0
loop while (arret < 1){
<- loop + 1
loop ## lambda
<- Vect.expo*exp(Matrix.X %*% Beta)
lambda ## Vecteur U
<- t(Matrix.X) %*% (Vect.Y - lambda)
U ## Matrice H
<- -t(Matrix.X) %*% (Matrix.X*as.vector(lambda))
H ## Update beta
<- Beta - solve(H)%*%U
Beta ## Criteres d'arret
<- ifelse(abs(max(U) - max.U) > 0.0001 & loop < 30, 0, 1)
arret <- max(U)
max.U
}
## Print Results
print(loop)
## [1] 6
print(abs(max(U) - max.U))
## [1] 0
print(Beta)
## [,1]
## (Intercept) -1.21214965
## couleurRouge -0.02101820
## myopieOui 0.07587350
## type_territoireSemi-urbain -0.09550161
## type_territoireUrbain -0.14857717
## langueF 0.25028395
## alimentationVégétalien -0.24305663
## alimentationVégétarien -0.42802787
Un critère d’arrêt de l’algorithme a été placé, autant par rapport à l’amélioration de la fonction de premier ordre, que du nombre d’itérations maximum.
On peut comparer les valeurs estimés de \(\beta\) par rapport à la fonction glm() de R. Remarquez l’introduction du paramètre offset utiliser pour inclure le logarithme de l’exposition au risque.
### Compare avec fonction glm()
<- as.formula(nb.sin ~ couleur + myopie + type_territoire + langue + alimentation + offset(log(expo)))
score.glm <- glm(score.glm, family=poisson(link=log), data=db.train)
Poisson1 cbind(Beta, Poisson1$coefficients)
## [,1] [,2]
## (Intercept) -1.21214965 -1.21214965
## couleurRouge -0.02101820 -0.02101820
## myopieOui 0.07587350 0.07587350
## type_territoireSemi-urbain -0.09550161 -0.09550161
## type_territoireUrbain -0.14857717 -0.14857717
## langueF 0.25028395 0.25028395
## alimentationVégétalien -0.24305663 -0.24305663
## alimentationVégétarien -0.42802787 -0.42802787
4.2.2 Variance des estimateurs
4.2.2.1 MLE
On peut utiliser l’estimation hessienne, équivalente à l’estimation par l’information de Fisher et l’estimateur par produit-croisé. Comparons ces valeurs avec celles obtenues par la fonction glm()
<- -t(Matrix.X) %*% (Matrix.X*as.vector(lambda))
H <- sqrt(diag(solve(-H)))
stderrH <- t(Matrix.X) %*% (Matrix.X*as.vector((Vect.Y - lambda)*(Vect.Y - lambda)))
OP <- sqrt(diag(solve(OP)))
stderrOP cbind(stderrH, stderrOP, summary(Poisson1)$coefficients[, 2])
## stderrH stderrOP
## (Intercept) 0.02557011 0.023783653 0.02557011
## couleurRouge 0.01886640 0.017790074 0.01886639
## myopieOui 0.01354869 0.012869358 0.01354869
## type_territoireSemi-urbain 0.01260514 0.011903342 0.01260514
## type_territoireUrbain 0.01221177 0.011439321 0.01221177
## langueF 0.01021171 0.009572906 0.01021171
## alimentationVégétalien 0.01770594 0.016518954 0.01770594
## alimentationVégétarien 0.01683327 0.015712435 0.01683327
On peut voir une différence entre l’estimateur par produit-croisé et l’estimateur hessien (ou par l’information de Fisher). On voit que la fonction glm() de R utilise l’estimateur hessien pour le calcul de la variance des estimateurs (ici, l’écart-type est affiché).
4.2.2.2 QMLE
On peut supposer une variance de forme \(\omega_i\) pour l’estimation par quasi-MLE.
Nous avons développé deux estimateurs pour le paramètre \(\phi\) de la NB1.
<- sum((Vect.Y - lambda)*(Vect.Y - lambda)/lambda)/(nrow(db.train) - length(Beta))
phi1 <- sum((Vect.Y - lambda)*(Vect.Y - lambda))/sum(lambda)
phi2 print(c(phi1, phi2))
## [1] 1.236228 1.122992
.1 <- sqrt(phi1)*stderrH
stderr.nb1.2 <- sqrt(phi2)*stderrH
stderr.nb1<- glm(score.glm, family=quasipoisson(link=log), data=db.train)
Poisson2 summary(Poisson2)
##
## Call:
## glm(formula = score.glm, family = quasipoisson(link = log), data = db.train)
##
## Deviance Residuals:
## Min 1Q Median 3Q Max
## -0.9081 -0.6650 -0.5868 -0.4208 5.6607
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -1.21215 0.02843 -42.636 < 2e-16 ***
## couleurRouge -0.02102 0.02098 -1.002 0.316
## myopieOui 0.07587 0.01506 5.037 4.74e-07 ***
## type_territoireSemi-urbain -0.09550 0.01402 -6.814 9.50e-12 ***
## type_territoireUrbain -0.14858 0.01358 -10.943 < 2e-16 ***
## langueF 0.25028 0.01135 22.044 < 2e-16 ***
## alimentationVégétalien -0.24306 0.01969 -12.346 < 2e-16 ***
## alimentationVégétarien -0.42803 0.01872 -22.869 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for quasipoisson family taken to be 1.236228)
##
## Null deviance: 193888 on 270714 degrees of freedom
## Residual deviance: 191556 on 270707 degrees of freedom
## AIC: NA
##
## Number of Fisher Scoring iterations: 6
On peut voir que le modèle quasipoisson de la fonction glm() utilise l’estimateur phi1. Bien que la fonction glm() utilise phi1, nous recommandons plutôt d’utiliser phi2 dans l’estimation de la variance d’un modèle QMLE avec variance de forme NB1. En effet, phi1 est plutôt instable lorsqu’il y a présence d’une variable offset.
Au final, nous obtenons les estimés suivants pour la variance des estimateurs, sous la forme d’une variance de type NB1, \(\omega_i = \phi \mu_i\).
cbind(stderr.nb1.1, stderr.nb1.2, summary(Poisson2)$coefficients[, 2])
## stderr.nb1.1 stderr.nb1.2
## (Intercept) 0.02843033 0.02709698 0.02843033
## couleurRouge 0.02097675 0.01999297 0.02097675
## myopieOui 0.01506422 0.01435773 0.01506422
## type_territoireSemi-urbain 0.01401513 0.01335784 0.01401513
## type_territoireUrbain 0.01357776 0.01294098 0.01357776
## langueF 0.01135397 0.01082148 0.01135397
## alimentationVégétalien 0.01968649 0.01876322 0.01968649
## alimentationVégétarien 0.01871621 0.01783844 0.01871621
Nous avons aussi développé deux estimateurs pour le paramètre \(\alpha\) lorsque nous supposons une forme NB2 de la variance.
<- sum(((Vect.Y - lambda)*(Vect.Y - lambda) - lambda)/(lambda*lambda))/(nrow(db.train) - length(Beta))
alpha1 <- sum((Vect.Y - lambda)*(Vect.Y - lambda) - lambda)/sum(lambda*lambda)
alpha2 print(c(alpha1, alpha2))
## [1] 3.7556585 0.5757296
La fonction glm() de R ne produit pas d’estimé pour une forme de variance NB2. Comme pour l’estimé de \(\phi\) de la NB1 de la variance, nous recommandons d’utiliser alpha2 dans l’estimation de la variance d’un modèle QMLE avec variance de forme NB2. C’Est encore plus évident ici, mais alpha1 est instable lorsqu’il y a présence d’une variable offset.
Nous obtenons les estimés suivants pour la variance des estimateurs, sous la forme d’une variance de type NB2, \(\omega_i = \mu_i + \alpha \mu_i^2\).
<- t(Matrix.X) %*% (Matrix.X*as.vector((lambda + alpha1*(lambda*lambda))))
Middle <- solve(-H)%*%(Middle%*%solve(-H))
Var1 .1 <- sqrt(diag(Var1))
stderr.nb2<- t(Matrix.X) %*% (Matrix.X*as.vector((lambda + alpha2*(lambda*lambda))))
Middle <- solve(-H)%*%(Middle%*%solve(-H))
Var1 .2 <- sqrt(diag(Var1))
stderr.nb2
cbind(stderr.nb2.1, stderr.nb2.2)
## stderr.nb2.1 stderr.nb2.2
## (Intercept) 0.03562849 0.02735313
## couleurRouge 0.02554596 0.02003540
## myopieOui 0.01817110 0.01435422
## type_territoireSemi-urbain 0.01736035 0.01344370
## type_territoireUrbain 0.01669169 0.01299912
## langueF 0.01345915 0.01077325
## alimentationVégétalien 0.02549256 0.01910667
## alimentationVégétarien 0.02422435 0.01816256
Pour terminer, nous avons vu une modèle QMLE qui ne supposait aucune forme particulière de la variance. On peut comparer tous les estimés des écart-types.
<- t(Matrix.X) %*% (Matrix.X*as.vector(( (Vect.Y - lambda)*(Vect.Y - lambda) )))
Middle <- solve(-H)%*%(Middle%*%solve(-H))
Var1 <- sqrt(diag(Var1))
std.unstr
cbind(stderrH, stderrOP, stderr.nb1.1, stderr.nb1.2, stderr.nb2.1, stderr.nb2.2, std.unstr)
## stderrH stderrOP stderr.nb1.1 stderr.nb1.2 stderr.nb2.1 stderr.nb2.2 std.unstr
## (Intercept) 0.02557011 0.023783653 0.02843033 0.02709698 0.03562849 0.02735313 0.02750569
## couleurRouge 0.01886640 0.017790074 0.02097675 0.01999297 0.02554596 0.02003540 0.02000922
## myopieOui 0.01354869 0.012869358 0.01506422 0.01435773 0.01817110 0.01435422 0.01426520
## type_territoireSemi-urbain 0.01260514 0.011903342 0.01401513 0.01335784 0.01736035 0.01344370 0.01335507
## type_territoireUrbain 0.01221177 0.011439321 0.01357776 0.01294098 0.01669169 0.01299912 0.01304602
## langueF 0.01021171 0.009572906 0.01135397 0.01082148 0.01345915 0.01077325 0.01089809
## alimentationVégétalien 0.01770594 0.016518954 0.01968649 0.01876322 0.02549256 0.01910667 0.01899002
## alimentationVégétarien 0.01683327 0.015712435 0.01871621 0.01783844 0.02422435 0.01816256 0.01804869
La variance non-structurée ne suppose aucune forme particulière de la variance. En ce sens, elle est la forme la plus robuste pour l’estimation de la variance des estimateurs. En comparant avec les autres résultats, on peut faire quelques observations:
Les deux formes de variance de la Poisson MLE, comparativement au résultat obtenu par la variance non-structurée, semble sous-estimer l’écart-type des estimateurs;
On peut voir que les écart-types de la forme NB1, en utilisant phi1, surestime les écart-types. L’écart est encore plus évident avec alpha1 pour la forme NB2.
Entre la forme NB1 et la forme NB2, avec phi2 et alpha2, on voit que la forme NB2 se rapproche peut-être davantage de la forme non-structurée.
On peut voir graphiquement la différence entre les différentes formes de variance.
library(ggplot2)
$lambda <- lambda
db.train$varPoisson <- lambda
db.train$varNB1 <- lambda*phi2
db.train$varNB2 <- lambda + alpha2*lambda^2
db.train
ggplot()+
geom_line(aes(x=lambda, y=varPoisson, color='Poisson'), data=db.train) +
geom_line(aes(x=lambda, y=varNB1, color='NB1'), data=db.train) +
geom_line(aes(x=lambda, y=varNB2, color='NB2'), data=db.train) +
scale_color_manual(values=c('blue','red','black')) +
xlab("Espérance") +
ylab("Variance") +
theme(legend.title=element_blank())
Au lieu de supposer une forme NB1 ou NB2, à l’image de ce que nous avons fait pour la forme non-structuré de la variance des estimateurs, il pourrait être intéressant de développer des méthodes non-paramétriques pour mieux estimer le lien entre la variance et l’espérance.
On peut profiter du fait que \(\hat{\beta}_{MLE}\) soit un estimateur convergent pour faire quelques analyses.
<- 2000
nb.voisin
$ind.var <- (db.train$lambda - db.train$nb.sin)^2
db.train<- c(seq(from=0.01, to = 0.4, by=0.01))
lambda.vec
<- data.frame()
nonpar.var for(i in 1:length(lambda.vec)){
<- lambda.vec[i]
sel.lambda <- db.train %>%
bd mutate(diff = abs(lambda- sel.lambda)) %>%
arrange(diff) %>%
slice(1:nb.voisin)
<- sum(bd$ind.var)/(nb.voisin-length(Beta))
var <- cbind(sel.lambda, var)
result <- rbind(nonpar.var, result)
nonpar.var
}colnames(nonpar.var) <- c('lambda', 'varUNSTR')
ggplot()+
geom_line(aes(x=lambda, y=varPoisson, color='Poisson'), data=db.train) +
geom_line(aes(x=lambda, y=varNB1, color='NB1'), data=db.train) +
geom_line(aes(x=lambda, y=varNB2, color='NB2'), data=db.train) +
geom_line(aes(x=lambda, y=varUNSTR, color='UNS'), size=1.2, data=nonpar.var) +
scale_color_manual(values=c('blue','red','black', 'darkgreen')) +
xlab("Espérance") +
ylab("Variance") +
theme(legend.title=element_blank())
Ceci n’est qu’une première analyse, mais nous pouvons voir que ni la forme paramétrique de la NB1, ou de la NB2, ne semble convenir aux données. Si on voulait aller plus loin et trouver non seulement une meilleure estimation de la variance des paramètres, mais aussi de meilleurs paramètres, on devrait se rabbatre sur une approche appelée Poisson EE (estimating equations).
4.2.3 Poisson EE
On commence la méthode d’estimation en retournant à la condition de premier ordre des modèles GLM:
\[\begin{eqnarray*} \sum_{i=1}^n \frac{(y_i - \mu_i)}{g'(\mu_i) Var[Y_i]} \boldsymbol{X}_{i} &=& \boldsymbol{0}\\ \sum_{i=1}^n \frac{(y_i - \mu_i)}{g'(\mu_i) \omega_i} \boldsymbol{X}_{i} &=& \boldsymbol{0} \end{eqnarray*}\]
On suppose une variance de type \(\omega_i = \omega(\mu_i, \alpha)\), avec un estimateur convergent pour \(\alpha\). Pour une moyenne de forme log-linéaire (i.e. \(\boldsymbol{X}_{i}' \boldsymbol{\beta} = \ln(\mu_i)\)), nous avons ainsi:
\[\begin{eqnarray*} \sum_{i=1}^n \frac{1}{\omega(\mu_i, \alpha)} (y_i - \mu_i) \mu_i \boldsymbol{x_i} = 0\\ \end{eqnarray*}\]
et donc:
\[Var_{EE}[\hat{\beta}_{EE}] = \Big[ \sum_{i=1}^n \frac{1}{\omega(\mu_i, \alpha)} \mu_i^2 \boldsymbol{X}_{i} \boldsymbol{X}_{i}^T \Big]^{-1}\]
Parce que l’estimateur est basé sur les deux premiers moments, on pourrait voir cette approche comme une méthode des moments généralisés (GMM).