Un cours en R et Stan avec brms
Ladislas Nalborczyk (LPC, LNC, CNRS, Aix-Marseille Univ)
Cours n°01 : Introduction à l’inférence bayésienne
Cours n°02 : Modèle Beta-Binomial
Cours n°03 : Introduction à brms, modèle de régression linéaire
Cours n°04 : Modèle de régression linéaire (suite)
Cours n°05 : Markov Chain Monte Carlo
Cours n°06 : Modèle linéaire généralisé
Cours n°07 : Comparaison de modèles
Cours n°08 : Modèles multi-niveaux
Cours n°09 : Modèles multi-niveaux généralisés
Cours n°10 : Data Hackathon
\[\newcommand\given[1][]{\:#1\vert\:}\]
Le but est de construire un modèle qui puisse apprendre à plusieurs niveaux, qui puisse produire des estimations qui seront informées par les différents groupes présents dans les données. Nous allons suivre l’exemple suivant tout au long de ce cours.
Imaginons que nous ayons construit un robot visiteur de cafés, et que celui-ci s’amuse à mesurer le temps d’attente après avoir commandé. Ce robot visite 20 cafés différents, 5 fois le matin et 5 fois l’après-midi, et mesure le temps (en minutes) de service d’un café.
cafe afternoon wait
1 1 0 4.9989926
2 1 1 2.2133944
3 1 0 4.1866730
4 1 1 3.5624399
5 1 0 3.9956779
6 1 1 2.8957176
7 1 0 3.7804582
8 1 1 2.3844837
9 1 0 3.8617982
10 1 1 2.5800004
11 2 0 2.7421223
12 2 1 1.3525907
13 2 0 2.5215095
14 2 1 0.9628102
15 2 0 1.9543977
df %>%
ggplot(aes(x = factor(cafe), y = wait, fill = factor(afternoon) ) ) +
geom_dotplot(
stackdir = "center", binaxis = "y",
dotsize = 1, show.legend = FALSE
) +
geom_hline(yintercept = mean(df$wait), linetype = 3) +
facet_wrap(~afternoon, ncol = 2) +
labs(x = "Café", y = "Temps d'attente (en minutes)")
On peut construire un premier modèle, qui estime le temps moyen (sur tous les bistrots confondus) pour être servi.
\[ \begin{align} \color{orangered}{w_{i}} \ &\color{orangered}{\sim \mathrm{Normal}(\mu_{i}, \sigma)} \\ \color{black}{\mu_{i}} \ &\color{black}{= \alpha} \\ \color{steelblue}{\alpha} \ &\color{steelblue}{\sim \mathrm{Normal}(5, 10)} \\ \color{steelblue}{\sigma} \ &\color{steelblue}{\sim \mathrm{HalfCauchy}(0, 2)} \\ \end{align} \]
\[ p(x \given x_{0}, \gamma) = \left(\pi \gamma \left[1 + \left(\frac{x-x_{0}}{\gamma}\right)^{2}\right] \right)^{-1} \]
Deuxième modèle qui estime un intercept par café. Équivalent à construire 20 dummy variables.
\[ \begin{align} \color{orangered}{w_{i}} \ &\color{orangered}{\sim \mathrm{Normal}(\mu_{i}, \sigma)} \\ \color{black}{\mu_{i}} \ &\color{black}{= \alpha_{\text{café}[i]}} \\ \color{steelblue}{\alpha_{\text{café}[i]}} \ &\color{steelblue}{\sim \mathrm{Normal}(5, 10)} \\ \color{steelblue}{\sigma} \ &\color{steelblue}{\sim \mathrm{HalfCauchy}(0, 2)} \\ \end{align} \]
Estimate Est.Error Q2.5 Q97.5
b_factorcafe1 3.446205 0.2645303 2.9313403 3.954503
b_factorcafe2 1.728562 0.2519766 1.2333122 2.229070
b_factorcafe3 3.317633 0.2546584 2.8298730 3.809318
b_factorcafe4 2.799464 0.2537309 2.3120310 3.295132
b_factorcafe5 1.465384 0.2663197 0.9487625 1.973528
b_factorcafe6 3.635864 0.2583575 3.1241016 4.148555
b_factorcafe7 2.940702 0.2538981 2.4470846 3.439896
b_factorcafe8 3.179737 0.2579619 2.6878408 3.679906
b_factorcafe9 3.335391 0.2616709 2.8338354 3.850855
b_factorcafe10 3.101582 0.2570983 2.5966855 3.607365
b_factorcafe11 1.914888 0.2563538 1.4076090 2.415308
b_factorcafe12 3.490106 0.2576796 2.9853369 4.005503
b_factorcafe13 3.220218 0.2607201 2.7211301 3.735910
b_factorcafe14 2.630154 0.2554882 2.1134215 3.148689
b_factorcafe15 3.480625 0.2563819 2.9866802 3.983956
b_factorcafe16 3.000218 0.2700380 2.4678319 3.521794
b_factorcafe17 3.874953 0.2614359 3.3764925 4.390826
b_factorcafe18 5.530325 0.2635470 5.0243866 6.032981
b_factorcafe19 2.974775 0.2660832 2.4568977 3.489795
b_factorcafe20 3.364509 0.2594216 2.8460383 3.872511
Est-ce qu’on ne pourrait pas faire en sorte que le temps mesuré au café 1 informe la mesure réalisée au café 2, et au café 3 ? Ainsi que le temps moyen pour être servi ? Nous allons apprendre le prior à partir des données…
\[ \begin{align} \text{Niveau 1}: \color{orangered}{w_{i}} \ &\color{orangered}{\sim \mathrm{Normal}(\mu_{i}, \sigma)} \\ \color{black}{\mu_{i}} \ &\color{black}{= \alpha_{\text{café}[i]}} \\ \text{Niveau 2}: \color{steelblue}{\alpha_{\text{café}}} \ &\color{steelblue}{\sim \mathrm{Normal}(\alpha,\sigma_{\text{café}})} \\ \color{steelblue}{\alpha} \ &\color{steelblue}{\sim \mathrm{Normal}(5, 10)} \\ \color{steelblue}{\sigma_{\text{café}}} \ &\color{steelblue}{\sim \mathrm{HalfCauchy}(0, 2)} \\ \color{steelblue}{\sigma} \ &\color{steelblue}{\sim \mathrm{HalfCauchy}(0, 2)} \\ \end{align} \]
Le prior de l’intercept pour chaque café (\(\alpha_{\text{café}}\)) est maintenant fonction de deux paramètres (\(\alpha\) et \(\sigma_{\text{café}}\)). \(\alpha\) et \(\sigma_{\text{café}}\) sont appelés des hyper-paramètres, ce sont des paramètres pour des paramètres, et leurs priors sont appelés des hyperpriors. Il y a deux niveaux dans le modèle…
\[ \begin{align} \color{orangered}{w_{i}} \ &\color{orangered}{\sim \mathrm{Normal}(\mu_{i}, \sigma)} \\ \color{black}{\mu_{i}} \ &\color{black}{= \alpha_{\text{café}[i]}} \\ \color{steelblue}{\alpha_{\text{café}}} \ &\color{steelblue}{\sim \mathrm{Normal}(\alpha,\sigma_{\text{café}})} \\ \end{align} \]
NB : \(\alpha\) est ici défini dans le prior de \(\alpha_{\text{café}}\) mais on pourrait, de la même manière, le définir dans le modèle linéaire :
\[ \begin{align} \color{orangered}{w_{i}} \ &\color{orangered}{\sim \mathrm{Normal}(\mu_{i}, \sigma)} \\ \color{black}{\mu_{i}} \ &\color{black}{= \alpha + \alpha_{\text{café}[i]}} \\ \color{steelblue}{\alpha_{\text{café}}} \ &\color{steelblue}{\sim \mathrm{Normal}(0,\sigma_{\text{café}})} \\ \end{align} \]
On peut toujours “enlever” la moyenne d’une distribution gaussienne et la considérer comme une constante plus une gaussienne centrée sur zéro.
NB : quand \(\alpha\) est défini dans le modèle linéaire, les \(\alpha_{\text{café}}\) représentent des déviations de l’intercept moyen. Il faut donc ajouter \(\alpha\) et \(\alpha_{\text{café}}\) pour obtenir le temps d’attente moyen par café…
Ce modèle a 23 paramètres, l’intercept général \(\alpha\), la variabilité résiduelle \(\sigma\), la variabilité entre les cafés \(\sigma_{\text{café}}\), et un intercept par café.
L’estimateur James-Stein est défini comme \(z = \bar{y} + c(y - \bar{y})\), où \(\bar{y}\) désigne la moyenne de l’échantillon, \(y\) une observation individuelle, et \(c\) une constante, le shrinking factor (Efron & Morris, 1977).
Le shrinking factor est déterminé à la fois par la variabilité (imprécision) de la mesure (e.g., son écart-type) et par la distance à l’estimation moyenne (i.e., \(y - \bar{y}\)). En d’autres termes, cet estimateur fait moins “confiance” (i.e., accorde moins de poids) aux observations imprécises et/ou extrêmes. En pratique, le shrinkage agit comme une protection contre le sur-apprentissage (overfitting).
Le shrinkage observé slide précédente est dû à des phénomènes de partage (pooling) de l’information entre les cafés. L’estimation de l’intercept pour chaque café informe l’estimation de l’intercept des autres cafés, ainsi que l’estimation de l’intercept général (i.e., la moyenne générale).
On distingue en général trois perspectives (ou stratégies) :
Complete pooling : on suppose que le temps d’attente est invariant, on estime un intercept commun (mod1
).
No pooling : on suppose que les temps d’attente de chaque café sont uniques et indépendants : on estime un intercept par café, mais sans informer le niveau supérieur (mod2
).
Partial pooling : on utilise un prior adaptatif, comme dans l’exemple précédent (mod3
).
La stratégie complete pooling en général underfitte les données (faibles capacités de prédiction) tandis que le stratégie no pooling revient à overfitter les données (faibles capacités de prédiction ici aussi). La stratégie partial pooling (i.e., celle des modèles multi-niveaux) permet d’’équilibrer underfitting et overfitting.
On peut comparer ces trois modèles en utilisant le WAIC (discuté au Cours n°07).
# calcul du WAIC et ajout du WAIC à chaque modèle
mod1 <- add_criterion(mod1, "waic")
mod2 <- add_criterion(mod2, "waic")
mod3 <- add_criterion(mod3, "waic")
# comparaison des WAIC de chaque modèle
w <- loo_compare(mod1, mod2, mod3, criterion = "waic")
print(w, simplify = FALSE)
elpd_diff se_diff elpd_waic se_elpd_waic p_waic se_p_waic waic se_waic
mod3 0.0 0.0 -253.8 8.3 18.1 1.5 507.6 16.6
mod2 -0.6 1.3 -254.4 8.4 19.4 1.6 508.7 16.7
mod1 -57.3 10.6 -311.1 10.6 2.0 0.3 622.1 21.1
On remarque que le modèle 3 a seulement 18 “effective parameters” (pWAIC) et moins de paramètres que le modèle 2, alors qu’il en a en réalité 2 de plus… posterior_summary(mod3)[3, 1]
nous donne le sigma du prior adaptatif des \(\alpha_{\text{café}}\) (\(\sigma_{\text{café}} = 0.82\)). On remarque que ce sigma est très faible et correspond à assigner un prior très contraignant, ou régularisateur.
On compare les estimations du premier modèle (complete pooling model) et du troisième modèle (partial pooling model).
Estimate Est.Error Q2.5 Q97.5
b_Intercept 3.118824 0.07953888 2.963235 3.274122
sigma 1.141772 0.05642862 1.038975 1.256931
Estimate Est.Error Q2.5 Q97.5
b_Intercept 3.1224462 0.20548659 2.7134453 3.5301519
sigma 0.8219151 0.04328802 0.7430558 0.9108058
Les deux modèles font la même prédiction (en moyenne) pour \(\alpha\), mais le modèle 3 est plus incertain de sa prédiction que le modèle 1 (voir l’erreur standard pour \(\alpha\))…
L’estimation de \(\sigma\) du modèle 3 est plus petite que celle du modèle 1 car le modèle 3 décompose la variabilité non expliquée en deux sources : la variabilité du temps d’attente entre les cafés \(\sigma_{\text{café}}\) et la variabilité résiduelle \(\sigma\).
Imaginons que notre robot ne visite pas tous les cafés le même nombre de fois (comme dans le cas précédent) mais qu’il visite plus souvent les cafés proches de chez lui…
On observe que les cafés qui sont souvent visités (à droite) subissent moins l’effet du shrinkage. Leur estimation est moins “tirée” vers la moyenne générale que les estimations des cafés les moins souvent visités (à gauche).
Cinq définitions (contradictoires) relevées par Gelman (2005).
Gelman & Hill (2006) suggèrent plutôt l’utilisation des termes de constant effects et varying effects, et de toujours utiliser la modélisation multi-niveaux, en considérant que ce qu’on appelle effet fixe peut simplement être considéré comme un effet aléatoire dont la variance serait égale à \(0\).
Le fait de faire varier les intercepts de chaque café est simplement une autre manière de régulariser (de manière adaptative), c’est à dire de diminuer le poids accordé aux données dans l’estimation. Le modèle devient à même d’estimer à quel point les groupes (ici les cafés) sont différents, tout en estimant les caractéristiques de chaque café…
Différence entre les cross-classified (ou “crossed”) multilevel models et nested or hierarchical multilevel models. Le premier type de modèle concerne des données structurées selon deux (ou plus) facteurs aléatoires non “nichés”. Le deuxième type de modèles concerne des données structurées de manière hiérarchique (e.g., un élève dans une classe dans une école dans une ville…). Voir cette discussion pour plus de détails.
Les deux types de modèles s’écrivent cependant de manière similaire, sur plusieurs “niveaux”. Le terme “multi-niveaux” (dans notre terminologie) fait donc référence à la structure du modèle, à sa spécification. À distinguer de la structure des données.
On pourrait se poser la question de savoir si la récence des cafés (leur âge) ne serait pas une source de variabilité non contrôlée ? Il suffit d’ajouter un intercept qui varie par âge, et de lui attribuer un prior adaptatif.
\[ \begin{align} \color{orangered}{w_{i}} \ &\color{orangered}{\sim \mathrm{Normal}(\mu_{i}, \sigma)} \\ \color{black}{\mu_{i}} \ &\color{black}{= \alpha + \alpha_{\text{café}[i]} + \alpha_{\text{âge}[i]}} \\ \color{steelblue}{\alpha_{\text{café}}} \ &\color{steelblue}{\sim \mathrm{Normal}(5, \sigma_{\text{café}})} \\ \color{steelblue}{\alpha_{\text{âge}}} \ &\color{steelblue}{\sim \mathrm{Normal}(5, \sigma_{\text{âge}})} \\ \color{steelblue}{\alpha} \ &\color{steelblue}{\sim \mathrm{Normal}(0, 10)} \\ \color{steelblue}{\sigma_{\text{café}}} \ &\color{steelblue}{\sim \mathrm{HalfCauchy}(0, 2)} \\ \color{steelblue}{\sigma_{\text{âge}}} \ &\color{steelblue}{\sim \mathrm{HalfCauchy}(0, 2)} \\ \color{steelblue}{\sigma} \ &\color{steelblue}{\sim \mathrm{HalfCauchy}(0, 2)} \\ \end{align} \]
On s’intéresse maintenant à l’effet du moment de la journée sur le temps d’attente. Attend-on plus le matin, ou l’après-midi ?
\[ \begin{align} \color{orangered}{w_{i}} \ &\color{orangered}{\sim \mathrm{Normal}(\mu_{i}, \sigma)} \\ \color{black}{\mu_{i}} \ &\color{black}{= \alpha_{\text{café}[i]} + \beta_{\text{café}[i]} \times A_{i}} \\ \end{align} \]
Où \(A_{i}\) est une dummy variable codée 0/1 pour le matin et l’après-midi et où \(\beta_{\text{café}}\) est donc un paramètre de différence (i.e., une pente) entre le matin et l’après-midi.
Remarque : on sait que les cafés ont des intercepts et des pentes qui co-varient… Les cafés populaires seront surchargés le matin et beaucoup moins l’après-midi, résultant en une pente importante. Ces cafés auront aussi un temps d’attente moyen plus long (i.e., un intercept plus grand). Dans ces cafés, \(\alpha\) est grand et \(\beta\) est loin de zéro. À l’inverse, dans un café peu populaire, le temps d’attente sera faible, ainsi que la différence entre matin et après-midi.
On pourrait donc utiliser la co-variation entre intercept et pente pour faire de meilleures inférences. Autrement dit, faire en sorte que l’estimation de l’intercept informe celle de la pente, et réciproquement.
On s’intéresse maintenant à l’effet du moment de la journée sur le temps d’attente. Attend-on plus le matin, ou l’après-midi ?
\[ \begin{align} \color{orangered}{w_{i}} \ &\color{orangered}{\sim \mathrm{Normal}(\mu_{i}, \sigma)} \\ \color{black}{\mu_{i}} \ &\color{black}{= \alpha_{\text{café}[i]} + \beta_{\text{café}[i]} \times A_{i}} \\ \color{steelblue}{\begin{bmatrix} \alpha_{\text{café}} \\ \beta_{\text{café}} \\ \end{bmatrix}} \ &\color{steelblue}{\sim \mathrm{MVNormal}\bigg(\begin{bmatrix} \alpha \\ \beta \end{bmatrix}, \textbf{S}\bigg)} \\ \end{align} \]
La troisième ligne postule que chaque café a un intercept \(\alpha_{\text{café}}\) et une pente \(\beta_{\text{café}}\), définis par un prior Gaussien bivarié (i.e., à deux dimensions) ayant comme moyennes \(\alpha\) et \(\beta\) et comme matrice de covariance \(\textbf{S}\).
\[\mathbf{x} \sim \mathcal{N}(\boldsymbol{\mu}, \boldsymbol{\Sigma})\]
Où \(\boldsymbol{\mu}\) est un vecteur (à \(k\) dimensions) de moyennes, par exemple: mu <- c(a, b)
.
\(\boldsymbol{\Sigma}\) est une matrice de covariance de \(k \times k\) dimensions, et qui correspond à la matrice donnée par la fonction vcov()
.
\[ \begin{align} \boldsymbol{\Sigma} &= \begin{pmatrix} \sigma_{\alpha}^{2} & \sigma_{\alpha} \sigma_{\beta} \rho \\ \sigma_{\alpha} \sigma_{\beta} \rho & \sigma_{\beta}^{2} \\ \end{pmatrix} \\ \end{align} \]
\[ \begin{align} \boldsymbol{\Sigma} &= \begin{pmatrix} \sigma_{\alpha}^{2} & \sigma_{\alpha} \sigma_{\beta} \rho \\ \sigma_{\alpha} \sigma_{\beta} \rho & \sigma_{\beta}^{2} \\ \end{pmatrix} \\ \end{align} \]
Cette matrice peut se construire de deux manières différentes, strictement équivalentes.
\[ \begin{align} \boldsymbol{\Sigma} &= \begin{pmatrix} \sigma_{\alpha}^{2} & \sigma_{\alpha} \sigma_{\beta} \rho \\ \sigma_{\alpha} \sigma_{\beta} \rho & \sigma_{\beta}^{2} \\ \end{pmatrix} \\ \end{align} \]
La deuxième méthode est pratique car elle considère séparément les écart-types et les corrélations.
\[ \begin{align} \color{orangered}{w_{i}} \ &\color{orangered}{\sim \mathrm{Normal}(\mu_{i}, \sigma)} \\ \color{black}{\mu_{i}} \ &\color{black}{= \alpha_{\text{café}[i]} + \beta_{\text{café}[i]} \times A_{i}} \\ \color{steelblue}{\begin{bmatrix} \alpha_{\text{café}} \\ \beta_{\text{café}} \\ \end{bmatrix}} \ &\color{steelblue}{\sim \mathrm{MVNormal}\bigg(\begin{bmatrix} \alpha \\ \beta \end{bmatrix}, \textbf{S}\bigg)} \\ \color{black}{\textbf{S}} \ &\color{black}{= \begin{pmatrix} \sigma_{\alpha} & 0 \\ 0 & \sigma_{\beta} \\ \end{pmatrix} \ \textbf{R} \begin{pmatrix} \sigma_{\alpha} & 0 \\ 0 & \sigma_{\beta} \\ \end{pmatrix}} \\ \color{steelblue}{\alpha} \ &\color{steelblue}{\sim \mathrm{Normal} (0, 10)} \\ \color{steelblue}{\beta} \ &\color{steelblue}{\sim \mathrm{Normal} (0, 10)} \\ \color{steelblue}{\sigma_{\alpha}} \ &\color{steelblue}{\sim \mathrm{HalfCauchy} (0, 2)} \\ \color{steelblue}{\sigma_{\beta}} \ &\color{steelblue}{\sim \mathrm{HalfCauchy} (0, 2)} \\ \color{steelblue}{\sigma} \ &\color{steelblue}{\sim \mathrm{HalfCauchy} (0, 2)} \\ \color{steelblue}{\textbf{R}} \ &\color{steelblue}{\sim \mathrm{LKJ}(2)} \\ \end{align} \]
\(\textbf{S}\) est définie en factorisant \(\sigma_{\alpha}\), \(\sigma_{\beta}\), et la matrice de corrélation \(\textbf{R}\). La suite du modèle définit simplement les priors pour les effets constants. La dernière ligne spécifie le prior pour \(\textbf{R}\).
Prior proposé par Lewandowski et al. (2009). Un seul paramètre \(\zeta\) (zeta) spécifie la concentration de la distribution du coefficient de corrélation. Le prior \(\mathrm{LKJ}(2)\) définit un prior peu informatif pour \(\rho\) (rho) qui est sceptique des corrélations extrêmes (i.e., des valeurs proches de \(-1\) ou \(1\)).
Le paquet brms
utilise la même syntaxe que les fonctions de base R (comme lm
) ou que le paquet lme4
.
La partie gauche représente notre variable dépendante (ou “outcome”, i.e., ce qu’on essaye de prédire).
La première partie de la partie droite de la formule représente les effets constants (effets fixes), tandis que la seconde partie (entre parenthèses) représente les effets “variants” ou “variables” (effets aléatoires).
Le premier modèle ci-dessus contient seulement un intercept variable, qui varie par Subject
. Le deuxième modèle contient également un intercept variable, mais aussi une pente variable pour l’effet de Days
.
Lorsqu’on inclut plusieurs effets variants (e.g., un intercept et une pente variables), brms
postule qu’on souhaite aussi estimer la corrélation entre ces deux effets. Dans le cas contraire, on peut supprimer cette corrélation (i.e., la fixer à 0) en utilisant ||
.
On spécifie un intercept et une pente (pour l’effet d’afternoon
) qui varient par cafe
.
post <- as_draws_df(x = mod5) # extracts posterior samples
R <- rethinking::rlkjcorr(n = 16000, K = 2, eta = 2) # samples from prior
data.frame(prior = R[, 1, 2], posterior = post$cor_cafe__Intercept__afternoon) %>%
gather(type, value, prior:posterior) %>%
ggplot(aes(x = value, color = type, fill = type) ) +
geom_histogram(position = "identity", alpha = 0.2) +
labs(x = expression(rho), y = "Nombre d'échantillons")
On compare le premier modèle (complete pooling model), le troisième modèle (partial pooling model), et le dernier modèle (avec intercept et pente variable).
# comparaison des WAIC de chaque modèle
mod5 <- add_criterion(mod5, "waic")
w <- loo_compare(mod1, mod2, mod3, mod5, criterion = "waic")
print(w, simplify = FALSE)
elpd_diff se_diff elpd_waic se_elpd_waic p_waic se_p_waic waic se_waic
mod5 0.0 0.0 -155.0 10.1 26.6 2.6 310.0 20.1
mod3 -98.8 8.3 -253.8 8.3 18.1 1.5 507.6 16.6
mod2 -99.4 8.3 -254.4 8.4 19.4 1.6 508.7 16.7
mod1 -156.1 13.7 -311.1 10.6 2.0 0.3 622.1 21.1
mod1 mod2 mod3 mod5
1.648031e-68 6.938094e-44 1.221044e-43 1.000000e+00
L’estimation du temps d’attente moyen est plus incertaine lorsqu’on prend en compte de nouvelles sources d’erreur. Cependant, l’erreur du modèle (i.e., ce qui n’est pas expliqué), la variation résiduelle \(\sigma\), diminue…
Estimate Est.Error Q2.5 Q97.5
b_Intercept 3.118824 0.07953888 2.963235 3.274122
sigma 1.141772 0.05642862 1.038975 1.256931
Estimate Est.Error Q2.5 Q97.5
b_Intercept 3.1224462 0.20548659 2.7134453 3.5301519
sigma 0.8219151 0.04328802 0.7430558 0.9108058
Estimate Est.Error Q2.5 Q97.5
b_Intercept 3.7397979 0.21646428 3.305611 4.1743387
b_afternoon -1.2317902 0.08691248 -1.405042 -1.0591450
sigma 0.4892566 0.02748533 0.438913 0.5466079
Les modèles multi-niveaux (ou “modèles mixtes”) sont des extensions naturelles des modèles de régression classiques, où les paramètres de ces derniers se voient eux-même attribués des “modèles”, gouvernés par des hyper-paramètres.
Cette extension permet de faire des prédictions plus précises en prenant en compte la variabilité liée aux groupes ou structures (clusters) présent(e)s dans les données. Autrement dit, en modélisant les populations d’où sont tirés les effets aléatoires (e.g., la population de participants ou de stimuli).
Un modèle de régression classique est équivalent à un modèle multi-niveaux où la variabilité des effets aléatoires serait fixée à \(0\).
La cadre bayésien permet une interprétation naturelle des distributions desquelles proviennent les effets aléatoires (varying effects). En effet, ces distributions peuvent être interprétées comme des distributions a priori, dont les paramètres sont estimés à partir des données.
Reaction Days Subject
1 249.5600 0 308
2 258.7047 1 308
3 250.8006 2 308
4 321.4398 3 308
5 356.8519 4 308
6 414.6901 5 308
7 382.2038 6 308
8 290.1486 7 308
9 430.5853 8 308
10 466.3535 9 308
11 222.7339 0 309
12 205.2658 1 309
13 202.9778 2 309
14 204.7070 3 309
15 207.7161 4 309
16 215.9618 5 309
17 213.6303 6 309
18 217.7272 7 309
19 224.2957 8 309
20 237.3142 9 309
À vous de construire les modèles mathématiques et les modèles brms
correspondant aux modèles suivants :
Days
.Days
+ un effet aléatoire de Subject
(varying intercept).Days
+ un effet aléatoire de Subject
. (varying intercept) + un effet aléatoire de Days
(varying slope).Comparez ensuite ces modèles en utilisant les outils discutés aux cours précédents (e.g., WAIC) et concluez.
fmod0 <- lm(Reaction ~ Days, sleepstudy)
fmod1 <- lmer(Reaction ~ Days + (1 | Subject), sleepstudy)
fmod2 <- lmer(Reaction ~ Days + (1 + Days | Subject), sleepstudy)
anova(fmod1, fmod2)
Data: sleepstudy
Models:
fmod1: Reaction ~ Days + (1 | Subject)
fmod2: Reaction ~ Days + (1 + Days | Subject)
npar AIC BIC logLik deviance Chisq Df Pr(>Chisq)
fmod1 4 1802.1 1814.8 -897.04 1794.1
fmod2 6 1763.9 1783.1 -875.97 1751.9 42.139 2 7.072e-10 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# calcul du WAIC et ajout du WAIC à chaque modèle
mod6 <- add_criterion(mod6, "waic")
mod7 <- add_criterion(mod7, "waic")
mod8 <- add_criterion(mod8, "waic")
# comparaison des WAIC de chaque modèle
w <- loo_compare(mod6, mod7, mod8, criterion = "waic")
print(w, simplify = FALSE)
elpd_diff se_diff elpd_waic se_elpd_waic p_waic se_p_waic waic se_waic
mod8 0.0 0.0 -860.2 22.3 32.7 8.3 1720.5 44.6
mod7 -24.4 11.5 -884.6 14.4 19.1 3.3 1769.2 28.8
mod6 -93.1 20.9 -953.3 10.6 3.2 0.5 1906.6 21.2
mod6 mod7 mod8
3.798293e-41 2.647074e-11 1.000000e+00
Ladislas Nalborczyk - IMSB2022