---
title: "Modèles pour d'autres variables dépendantes"
---
```{r}
#| label: setup-analyse
#| include: false
source("R/04-initialiser-analyse.R")
suppressPackageStartupMessages(library(gtsummary))
```
::: {.callout-important title="Question de départ"}
Que faire lorsque la variable que l'on souhaite expliquer n'est ni continue ni binaire : un état de santé ordonné, un statut professionnel à plusieurs catégories, ou encore un nombre de livres lus ?
:::
## Objectifs d'apprentissage
À la fin de ce chapitre, vous saurez :
- choisir une famille de modèles à partir de la nature de la variable dépendante et de la question de recherche ;
- distinguer variable nominale, ordinale et de comptage dans un contexte de modélisation ;
- ajuster et interpréter une régression ordinale tenant compte du plan d'enquête ;
- comprendre l'hypothèse d'odds proportionnelles sans la traiter comme un détail logiciel ;
- comprendre la logique d'une régression multinomiale sans la remplacer automatiquement par plusieurs logistiques binaires ;
- reconnaître quand un modèle de comptage est préférable à une régression linéaire ;
- distinguer surdispersion du résultat et variance liée au plan ;
- différencier grappes d'échantillonnage et niveaux d'un modèle multiniveau ;
- choisir une restitution interprétable : coefficient, ratio, probabilité ou nombre attendu.
## Le modèle part de la variable dépendante, pas de la fonction R
Avant de choisir une commande, posons six questions :
1. quelles valeurs la variable dépendante peut-elle prendre ?
2. ces valeurs sont-elles **ordonnées** ?
3. les écarts entre valeurs ont-ils un sens quantitatif ?
4. existe-t-il une borne naturelle, par exemple zéro ?
5. quelle information serait perdue par une dichotomisation ?
6. quel résultat final voulons-nous communiquer ?
Dans `enqueter` :
- `sante` comporte cinq catégories ordonnées ;
- `statut_emploi` distingue des situations sans ordre unique ;
- `livres_12m` compte des événements sur douze mois.
Les transformer toutes en 0/1 simplifierait parfois le code, mais changerait la question scientifique.
## Une carte de choix minimale
| Variable dépendante | Exemple | Point de départ | Quantité facile à communiquer |
|---|---|---|---|
| quantitative continue | satisfaction | `svyglm(..., gaussian())` | différence moyenne / prédiction |
| binaire | en emploi | `svyglm(..., quasibinomial())` | probabilité prédite |
| ordinale | santé 1–5 | `svyolr()` | probabilités par catégorie |
| nominale, >2 catégories | statut d'emploi | modèle multinomial compatible design | probabilités des catégories |
| comptage | livres lus | `svyglm(..., quasipoisson())` | ratio de moyennes / nombre attendu |
| répétée / emboîtée | satisfaction à plusieurs vagues | modèle longitudinal / hiérarchique | changement / trajectoire |
Ce tableau n'est pas un algorithme. La distribution observée, l'univers, le design et les hypothèses du modèle restent déterminants.
::: {.callout-note title="Principe général"}
Le modèle doit respecter autant que possible **l'échelle de mesure** et la structure substantive du résultat. Recoder une variable uniquement parce qu'une fonction est plus familière constitue rarement une justification suffisante.
:::
## Régression ordinale
### Pourquoi ne pas traiter automatiquement une échelle ordinale comme quantitative ?
Si `sante` est codée 1 à 5, une régression linéaire suppose implicitement que l'écart entre « très bonne » et « bonne » est comparable à celui entre « mauvaise » et « très mauvaise ». Cette hypothèse n'est pas contenue dans le simple ordre des modalités.
Une régression ordinale conserve l'ordre sans imposer des distances égales.
### Préparer l'ordre des catégories
Dans le jeu, la santé est codée de **très bonne** à **très mauvaise**. L'ordre doit être explicite avant estimation.
```{r}
#| label: ch20-ordinal-prepare
design_ord <- update(
design,
sante_ord = factor(
sante,
levels = 1:5,
labels = c(
"Très bonne", "Bonne", "Moyenne",
"Mauvaise", "Très mauvaise"
),
ordered = TRUE
)
)
prop.table(survey::svytable(~sante_ord, design_ord)) |>
as.data.frame() |>
transmute(
`État de santé` = sante_ord,
`Part pondérée` = fmt_pct(Freq, .1)
) |>
knitr::kable()
```
La table est une étape méthodologique : elle vérifie que l'ordre et les catégories utilisées par le modèle correspondent bien au sens du questionnaire.
### Ajuster le modèle ordinal
```{r}
#| label: ch20-ordinal-fit
mod_ord <- survey::svyolr(
sante_ord ~ age + sexe_f + diplome_4,
design = design_ord,
method = "logistic"
)
coef_ord <- tibble::tibble(
Terme = names(stats::coef(mod_ord)),
Coefficient = as.numeric(stats::coef(mod_ord)),
`Erreur standard` = sqrt(diag(stats::vcov(mod_ord)))[names(stats::coef(mod_ord))]
) |>
mutate(across(where(is.numeric), ~round(.x, 3)))
knitr::kable(coef_ord, align = c("l", "r", "r"))
```
Le modèle à odds proportionnelles suppose qu'une même série de coefficients régit les différents seuils cumulatifs de la réponse. Cette hypothèse est forte : elle signifie que le contraste entre deux profils a une structure commune lorsque l'on déplace la frontière entre catégories de santé.
::: {.callout-warning title="L'hypothèse d'odds proportionnelles est une hypothèse substantive"}
Elle ne doit pas être considérée comme vraie parce que `svyolr()` a produit des coefficients. Si les contrastes semblent radicalement différents selon le seuil de santé, une description plus souple ou un modèle alternatif peut être nécessaire. Dans un cours de M2, le premier réflexe consiste à comparer les distributions observées et les probabilités prédites avant de multiplier les diagnostics spécialisés.
:::
### Les signes des coefficients sont moins sûrs à communiquer que les probabilités
L'orientation des coefficients dépend du codage de la réponse et de la convention du logiciel. Pour éviter des formulations inversées, produisons des probabilités pour deux profils.
```{r}
#| label: ch20-ordinal-pred
profils_sante <- tidyr::expand_grid(
age = c(30, 60),
diplome_4 = factor(
c("Inférieur au bac", "Supérieur long"),
levels = levels(enqueter$diplome_4)
)
) |>
mutate(
sexe_f = factor("Femme", levels = levels(enqueter$sexe_f))
)
probs_sante <- predict(
mod_ord,
newdata = profils_sante,
type = "probs"
)
probs_sante_df <- bind_cols(
profils_sante,
as.data.frame(probs_sante)
) |>
mutate(
Profil = paste0(age, " ans · ", diplome_4)
) |>
select(-age, -diplome_4, -sexe_f) |>
pivot_longer(
cols = -Profil,
names_to = "sante_predite",
values_to = "probabilite"
)
```
```{r}
#| label: plot-ch20-sante-pred
#| fig-alt: "Petits multiples montrant les probabilités prédites des cinq états de santé pour quatre profils d'âge et de diplôme."
ggplot(
probs_sante_df,
aes(x = sante_predite, y = probabilite)
) +
geom_col(fill = couleurs_enqueter[["principal"]], width = .72) +
facet_wrap(~Profil, ncol = 2) +
scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
labs(
x = "État de santé déclaré",
y = "Probabilité prédite",
title = "Le modèle ordinal décrit un déplacement de toute la distribution",
subtitle = "Profils fixés à sexe = femme",
caption = "Prédictions ponctuelles ; la figure sert à l'interprétation de l'ordre des catégories."
) +
theme_enqueter() +
theme(axis.text.x = element_text(angle = 20, hjust = 1))
```
::: {.callout-note title="Lecture sociologique"}
L'intérêt de conserver l'ordinalité est de voir comment les profils se redistribuent entre **toute la gamme des états de santé déclarés**. Une dichotomisation « bonne / mauvaise santé » ferait disparaître une partie de cette information et pourrait modifier les contrastes observés.
:::
## Régression multinomiale
### Quand les catégories ne sont pas ordonnées
Le statut d'emploi distingue emploi, chômage, études, retraite, foyer et autres formes d'inactivité. Il n'existe pas d'ordre substantiel unique entre ces catégories. Un modèle ordinal serait donc mal posé.
```{r}
#| label: tab-ch20-statut
enqueter |>
filter(!is.na(statut_emploi_f)) |>
count(statut_emploi_f, name = "n") |>
mutate(part = n / sum(n)) |>
transmute(
`Situation d'emploi` = statut_emploi_f,
`N observé` = n,
`Part brute` = fmt_pct(part, .1)
) |>
knitr::kable()
```
Une régression multinomiale choisit une catégorie de référence puis estime plusieurs contrastes dans un système commun. Les probabilités prédites des catégories se rattachent au même modèle et se somment à 1.
Le package `{survey}` ne couvre pas directement toutes les familles multinomiales. Des extensions telles que `{svyVGAM}` peuvent être nécessaires pour combiner certaines familles de `{VGAM}` avec un design complexe [@svyVGAM2026].
```{r, eval=FALSE}
# Exemple avancé — nécessite svyVGAM et VGAM
# library(svyVGAM)
# library(VGAM)
#
# design_multi <- subset(design, !is.na(statut_emploi_f))
# mod_multi <- svyVGAM::svy_vglm(
# statut_emploi_f ~ age + sexe_f + diplome_4,
# design = design_multi,
# family = VGAM::multinomial(refLevel = "En emploi")
# )
```
::: {.callout-tip title="Ce qu'il faut retenir au niveau M2"}
L'enjeu prioritaire n'est pas de mémoriser une extension logicielle. Il est de reconnaître qu'une réponse nominale à plusieurs catégories exige une logique différente d'une réponse binaire ou ordinale, puis de vérifier que la méthode choisie respecte aussi le plan d'enquête.
:::
### Pourquoi plusieurs logistiques binaires ne sont pas équivalentes
Estimer séparément « chômage vs reste », « études vs reste » et « retraite vs reste » répond à trois questions différentes. Ces modèles peuvent être utiles pour des comparaisons ciblées, mais ils ne remplacent pas automatiquement un modèle multinomial :
- les dénominateurs ne sont pas les mêmes ;
- les probabilités estimées ne forment pas nécessairement un système cohérent ;
- la référence substantive change d'une équation à l'autre.
La simplicité informatique ne doit pas masquer ce changement de question.
## Modèles de comptage
### Une variable de comptage possède sa propre structure
`livres_12m` prend des valeurs entières positives ou nulles. Avant tout modèle, regardons moyenne, variance et fréquence des zéros.
```{r}
#| label: tab-ch20-count-descriptif
count_diag <- enqueter |>
summarise(
`N disponible` = sum(!is.na(livres_12m)),
Moyenne = mean(livres_12m, na.rm = TRUE),
Médiane = median(livres_12m, na.rm = TRUE),
Variance = var(livres_12m, na.rm = TRUE),
`Part de zéros` = mean(livres_12m == 0, na.rm = TRUE)
)
count_diag |>
mutate(
across(c(Moyenne, Médiane, Variance), ~round(.x, 2)),
`Part de zéros` = fmt_pct(`Part de zéros`, .1)
) |>
knitr::kable()
```
Un comptage est borné à zéro, souvent asymétrique et susceptible d'avoir une variance qui augmente avec son niveau moyen. Une régression linéaire peut parfois servir d'approximation descriptive, mais elle n'encode pas ces propriétés.
### Quasi-Poisson : un point de départ compatible avec le design
```{r}
#| label: ch20-count-fit
mod_count <- survey::svyglm(
livres_12m ~ age + sexe_f + diplome_4,
design = design,
family = quasipoisson(link = "log")
)
```
Le lien logarithmique implique :
$$
\log\{E(Y\mid X)\}=\beta_0 + \beta_1X_1+\cdots+\beta_pX_p.
$$
En exponentiant un coefficient, on obtient un **ratio de moyennes conditionnelles**. Un ratio de 1,20 correspond à une moyenne attendue 20 % plus élevée, conditionnellement aux autres variables et au modèle.
```{r}
#| label: tab-ch20-count
tbl_regression(
mod_count,
exponentiate = TRUE,
label = list(
age ~ "Âge (années)",
sexe_f ~ "Sexe / genre",
diplome_4 ~ "Niveau de diplôme"
)
) |>
bold_labels()
```
### Surdispersion : ne pas confondre deux variances
Dans un Poisson classique, la variance conditionnelle est égale à la moyenne conditionnelle. Le quasi-Poisson autorise une dispersion différente. Cette question est distincte de la variance d'échantillonnage due au plan complexe.
```{r}
#| label: tab-ch20-dispersion
disp_count <- summary(mod_count)$dispersion
tibble::tibble(
`Moyenne brute` = count_diag$Moyenne,
`Variance brute` = count_diag$Variance,
`Dispersion estimée du modèle` = disp_count
) |>
mutate(across(everything(), ~round(.x, 2))) |>
knitr::kable()
```
La comparaison moyenne/variance brute donne une première alerte descriptive ; la dispersion du modèle est plus directement liée à la spécification conditionnelle. Ni l'une ni l'autre n'est « corrigée » par le simple fait d'utiliser des poids.
### Revenir au nombre attendu de livres
```{r}
#| label: ch20-count-pred
profils_livres <- tibble(
age = 45,
sexe_f = factor("Femme", levels = levels(enqueter$sexe_f)),
diplome_4 = factor(
levels(enqueter$diplome_4),
levels = levels(enqueter$diplome_4)
)
)
pred_livres <- predict(
mod_count,
newdata = profils_livres,
type = "response",
se.fit = TRUE
)
ci_livres <- ci_estimation(
coef(pred_livres),
SE(pred_livres),
design,
lower = 0
)
profils_livres <- bind_cols(
profils_livres,
ci_livres |>
transmute(
livres_attendus = estimation,
se,
bas,
haut
)
)
```
```{r}
#| label: plot-ch20-count
#| fig-alt: "Le nombre attendu de livres lus à 45 ans augmente avec le niveau de diplôme ; les points sont accompagnés d'intervalles d'incertitude."
ggplot(profils_livres, aes(x = livres_attendus, y = diplome_4)) +
geom_errorbarh(
aes(xmin = bas, xmax = haut),
height = .12,
colour = couleurs_enqueter[["gris"]]
) +
geom_point(size = 3.2, colour = couleurs_enqueter[["principal"]]) +
labs(
x = "Nombre attendu de livres lus en 12 mois",
y = NULL,
title = "Le gradient scolaire est plus lisible sur l'échelle du comptage",
subtitle = "Prédictions à 45 ans, sexe = femme",
caption = "Jeu synthétique ; modèle quasi-Poisson tenant compte du design."
) +
theme_enqueter()
```
::: {.callout-note title="Lecture sociologique"}
Le nombre de livres lus est ici fortement structuré par le diplôme. Le modèle de comptage permet de conserver l'information contenue dans la distribution plutôt que de réduire la pratique à « lecteur / non-lecteur ». Dans une enquête réelle, ce gradient pourrait renvoyer à socialisation culturelle, ressources, pratiques familiales, âge et offre culturelle ; le modèle ne distingue pas ces mécanismes à lui seul.
:::
::: {.callout-warning title="Beaucoup de zéros ≠ automatiquement modèle zéro-inflaté"}
Une forte proportion de zéros ne prouve pas l'existence de deux mécanismes générateurs distincts. Un modèle zéro-inflaté doit être justifié substantiellement et diagnostiqué, pas choisi parce qu'un histogramme contient une grande barre à zéro.
:::
## Modèles multiniveaux : ne pas confondre structure scientifique et plan de sondage
### Deux sens différents du mot « grappe »
Le fichier `enqueter` contient `psu`, unité primaire d'échantillonnage. Elle intervient dans le **plan de sondage** et donc dans l'estimation des variances.
Un modèle multiniveau introduit des niveaux parce que la **question scientifique** porte sur des observations emboîtées : élèves dans des classes, salariés dans des établissements, personnes observées à plusieurs dates.
::: {.callout-note title="À retenir"}
`ids = ~psu` dans `svydesign()` et `(1 | psu)` dans un modèle mixte ne sont pas deux écritures équivalentes. La première décrit un mécanisme d'échantillonnage ; la seconde spécifie une structure probabiliste pour l'hétérogénéité entre groupes.
:::
Un modèle mixte simple pour des mesures répétées pourrait être écrit :
```{r, eval=FALSE}
# Exemple conceptuel ; la logique longitudinale est développée au chapitre 23.
# library(lme4)
# mod_mixte <- lmer(
# satisfaction_vie ~ vague + (1 | id),
# data = panel_long
# )
```
Les poids d'un plan d'enquête et les pondérations d'un modèle hiérarchique ne s'articulent pas automatiquement dans tous les logiciels. Une option `weights =` générique n'est pas nécessairement un substitut à une méthode conçue pour le design.
## Choisir le modèle : un raisonnement en sept questions
Avant d'estimer :
1. quelle est la variable dépendante et son échelle ?
2. quel est l'univers de la question ?
3. quelle comparaison substantive voulons-nous faire ?
4. quelle information serait perdue par un recodage ?
5. quelle hypothèse est introduite par la famille de modèle ?
6. comment le plan d'enquête entre-t-il dans l'inférence ?
7. quelle sortie sera réellement interprétable : coefficient, ratio, probabilité, différence ou nombre attendu ?
La dernière question est souvent sous-estimée. Un modèle techniquement correct mais impossible à expliquer n'est pas encore une analyse aboutie.
## Erreurs fréquentes
::: {.callout-warning title="Dichotomiser systématiquement"}
Transformer une variable ordinale ou multinomiale en 0/1 facilite parfois le code mais peut supprimer une part importante de l'information et modifier la question de recherche.
:::
::: {.callout-warning title="Choisir un modèle par habitude"}
La présence de nombres dans une colonne ne justifie pas `lm()`. Les nombres peuvent coder des catégories, des rangs ou des comptages.
:::
::: {.callout-warning title="Confondre sophistication et qualité"}
Un modèle plus complexe n'est pas automatiquement plus approprié. La complexité doit acheter quelque chose : une hypothèse plus réaliste, une question mieux posée ou une restitution plus fidèle de la variable.
:::
## Mini-exercice
Pour chacune des variables suivantes, proposez un modèle de départ et justifiez-le en une phrase :
1. `sante` ;
2. `statut_emploi` ;
3. `livres_12m` ;
4. `en_emploi`.
::: {.callout-caution collapse="true" title="Correction"}
1. Régression ordinale : les modalités sont ordonnées sans supposer des distances égales.
2. Régression multinomiale : réponse nominale à plusieurs catégories.
3. Modèle de comptage, par exemple quasi-Poisson comme point de départ.
4. Régression logistique : réponse binaire.
:::
## Exercice de synthèse
### Niveau A — Appliquer
Ajustez le modèle ordinal de santé puis produisez des probabilités prédites pour deux profils. Vérifiez l'ordre des modalités avant toute interprétation.
### Niveau B — Choisir
Comparez trois stratégies pour `livres_12m` : régression linéaire, dichotomisation en « au moins un livre » et quasi-Poisson. Expliquez ce que chaque choix fait perdre ou gagner.
### Niveau C — Analyser
Choisissez une variable dépendante qui n'est ni continue ni binaire. Rédigez un mini-protocole comprenant : univers, échelle de mesure, modèle, hypothèse structurelle principale, design, sortie à présenter et deux limites d'interprétation.
## À retenir
- La variable dépendante et la question scientifique déterminent d'abord la famille de modèles à envisager.
- Une échelle ordinale n'est pas automatiquement une variable quantitative continue.
- L'hypothèse d'odds proportionnelles doit être pensée, pas seulement acceptée par défaut.
- Une réponse nominale à plusieurs catégories n'est pas une collection automatique de logistiques binaires.
- Un comptage possède des contraintes qui justifient souvent un modèle spécifique.
- Surdispersion du résultat et variance du plan sont deux problèmes distincts.
- Les prédictions sont souvent plus interprétables que les coefficients des modèles non linéaires.
- Un modèle plus sophistiqué n'est meilleur que s'il répond mieux à la question et reste défendable.
## Pour aller plus loin
Les modèles ordinaux tenant compte d'un plan d'enquête sont documentés dans `{survey}` [@survey2026]. Certaines familles multinomiales ou vectorielles peuvent nécessiter des extensions dédiées comme `{svyVGAM}` [@svyVGAM2026]. Le chapitre 23 reviendra sur les données répétées et le raisonnement longitudinal.