ggplot(df, aes(sex, fill=survived)) + geom_bar(position="fill") + labs(y="Proportion", title="Survie par sexe")
\[ {\log\frac{p}{1-p}}= \beta_0 + \beta_1 x_1 + \cdots + \beta_p x_p \]
glm(y ~ x, family=binomial, data=...)summary() fournit les coefficients (log-odds)broom::tidy(..., exponentiate=TRUE) donne les OR et ICm <- glm(survived ~ sex + pclass + age + fare, data=df %>% tidyr::drop_na(), family=binomial())
summary(m)
Call:
glm(formula = survived ~ sex + pclass + age + fare, family = binomial(),
data = df %>% tidyr::drop_na())
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) 3.7225052 0.4645113 8.014 1.11e-15 ***
sexmale -2.5185052 0.2082017 -12.096 < 2e-16 ***
pclass2 -1.2765903 0.3126370 -4.083 4.44e-05 ***
pclass3 -2.5415762 0.3277677 -7.754 8.89e-15 ***
age -0.0367302 0.0077325 -4.750 2.03e-06 ***
fare 0.0005226 0.0022579 0.231 0.817
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 964.52 on 713 degrees of freedom
Residual deviance: 647.23 on 708 degrees of freedom
AIC: 659.23
Number of Fisher Scoring iterations: 5
broom::tidy(m, exponentiate=TRUE, conf.int=TRUE) %>%
dplyr::mutate(across(c(estimate, conf.low, conf.high), round, 3))# A tibble: 6 × 7
term estimate std.error statistic p.value conf.low conf.high
<chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 (Intercept) 41.4 0.465 8.01 1.11e-15 16.9 105.
2 sexmale 0.081 0.208 -12.1 1.10e-33 0.053 0.12
3 pclass2 0.279 0.313 -4.08 4.44e- 5 0.15 0.512
4 pclass3 0.079 0.328 -7.75 8.89e-15 0.041 0.148
5 age 0.964 0.00773 -4.75 2.03e- 6 0.949 0.978
6 fare 1.00 0.00226 0.231 8.17e- 1 0.996 1.00
Note
Réflexion : - Que signifie un OR supérieur à 1 ? inférieur à 1 ? - Pourquoi présenter des OR plutôt que des coefficients bruts ?
Objectifs pédagogiques :
- Construire un premier modèle logistique sur Titanic
- Lire et interpréter des odds ratios
- Tester un seuil simple (0.5) et discuter ses limites
👉 Ouvrir missions/M1_titanic.qmd
df_fit <- df %>% tidyr::drop_na()
prob <- predict(m, newdata = df_fit, type = "response")
pred <- factor(ifelse(prob >= 0.5, "Yes", "No"), levels = c("No","Yes"))
table(Truth = df_fit$survived, Pred = pred) Pred
Truth No Yes
No 357 67
Yes 81 209
Note
Réflexion :
- Que se passe-t-il si l’on prend un seuil très bas (0.1) ? Très haut (0.9) ?
- Quels types d’erreurs (FP/FN) cela favorise-t-il ?
Accuracy (exactitude)
= proportion de prédictions correctes ((TP + TN) / Total)
→ Globalement utile, mais trompeuse si les classes sont déséquilibrées.
Sensibilité (Recall / TPR)
= proportion de positifs bien détectés (TP / (TP + FN))
→ “Parmi les passagers qui ont survécu, combien le modèle a-t-il bien prédits ?”
Spécificité (TNR)
= proportion de négatifs bien détectés (TN / (TN + FP))
→ “Parmi ceux qui n’ont pas survécu, combien le modèle a-t-il bien classés ?”
Précision (PPV) (utile si classes déséquilibrées)
= proportion de prédictions positives correctes (TP / (TP + FP))
→ “Quand le modèle dit Yes, quelle est la confiance ?”
Courbe ROC
= trace la sensibilité (TPR) vs 1-spécificité (FPR) pour tous les seuils possibles.
AUC (Area Under the Curve)
= probabilité qu’un positif ait une proba prédite plus élevée qu’un négatif.
→ 0.5 = hasard complet, 1 = discrimination parfaite.
Objectifs pédagogiques :
- Tracer une courbe ROC et calculer l’AUC
- Choisir un seuil adapté au contexte (coûts FP/FN)
- Explorer la calibration du modèle
👉 Ouvrir missions/M2_roc_seuils.qmd
Ateliers EIOM — Université Laval