# Tableau de contingence
tab <- matrix(c(60, 90, 40, 310), nrow = 2,
dimnames = list(
Maladie = c("Oui", "Non"),
Tabac = c("Fumeur", "Non-fumeur")))
tab
# Probabilités marginales et conditionnelles
p_maladie <- sum(tab["Oui", ]) / sum(tab)
p_maladie_fumeur <- tab["Oui", "Fumeur"] / sum(tab[, "Fumeur"])
p_fumeur_maladie <- tab["Oui", "Fumeur"] / sum(tab["Oui", ])
cat("P(maladie) =", p_maladie, "\n")
cat("P(maladie | fumeur) =", p_maladie_fumeur, "\n")
cat("P(fumeur | maladie) =", p_fumeur_maladie, "\n")
# Test d'indépendance
chisq.test(tab)Module 2
Concepts de probabilités
Lois de probabilités appliquées à la biostatistique
2h Débutant Prérequis : Module 1
1 Objectifs du TP
- Calculer des probabilités conditionnelles en contexte médical
- Appliquer le théorème de Bayes aux tests diagnostiques
- Simuler et visualiser les distributions binomiale, normale et de Poisson
2 Partie 1 : Probabilités conditionnelles et Bayes
2.1 Exercice 1.1 : Tableau de contingence
Dans un hôpital, on recueille les données suivantes sur 500 patients :
| Fumeur | Non-fumeur | Total | |
|---|---|---|---|
| Maladie cardiovasculaire | 60 | 40 | 100 |
| Pas de maladie | 90 | 310 | 400 |
| Total | 150 | 350 | 500 |
Questions :
- Calculer P(maladie cardiovasculaire)
- Calculer P(maladie | fumeur)
- Calculer P(fumeur | maladie)
- Le tabagisme et la maladie cardiovasculaire sont-ils indépendants ?
2.2 Exercice 1.2 : Tests diagnostiques et théorème de Bayes
Un nouveau test rapide pour le paludisme a les caractéristiques suivantes :
- Sensibilité : 92%
- Spécificité : 85%
Calculer la VPP et la VPN pour trois scénarios de prévalence.
Se <- 0.92
Sp <- 0.85
prevalences <- c(0.05, 0.20, 0.50)
resultats <- data.frame(
Prevalence = prevalences,
VPP = NA,
VPN = NA
)
for (i in seq_along(prevalences)) {
prev <- prevalences[i]
resultats$VPP[i] <- (Se * prev) / (Se * prev + (1 - Sp) * (1 - prev))
resultats$VPN[i] <- (Sp * (1 - prev)) / (Sp * (1 - prev) + (1 - Se) * prev)
}
resultats$VPP <- round(resultats$VPP * 100, 1)
resultats$VPN <- round(resultats$VPN * 100, 1)
print(resultats)Questions :
- Comment évolue la VPP avec la prévalence ?
- À partir de quelle prévalence la VPP dépasse-t-elle 50% ?
- Quelles implications pour le dépistage de masse vs le diagnostic ciblé ?
3 Partie 2 : Distribution binomiale
3.1 Exercice 2.1 : Efficacité d’un vaccin
Un vaccin a une efficacité de 80% (probabilité de protection). On vaccine 20 personnes.
n <- 20
p <- 0.80
# a) P(exactement 16 personnes protégées)
dbinom(16, size = n, prob = p)
# b) P(au moins 18 personnes protégées)
1 - pbinom(17, size = n, prob = p)
# c) P(moins de 14 personnes protégées) → échec du programme
pbinom(13, size = n, prob = p)
# d) Nombre attendu de personnes protégées
n * p
# Visualisation
x <- 0:20
probs <- dbinom(x, size = n, prob = p)
couleurs <- ifelse(x >= 18, "red", ifelse(x < 14, "orange", "steelblue"))
barplot(probs, names.arg = x,
col = couleurs,
main = "Distribution B(20, 0.8)",
xlab = "Nombre de protégés",
ylab = "Probabilité")
legend("topleft",
c("Succès attendu", "Seuil d'alerte", "Excellent"),
fill = c("steelblue", "orange", "red"))* Distribution binomiale.
INPUT PROGRAM.
LOOP k = 0 TO 20.
COMPUTE x = k.
END CASE.
END LOOP.
END FILE.
END INPUT PROGRAM.
COMPUTE prob = PDF.BINOM(x, 20, 0.8).
EXECUTE.
GRAPH /BAR(SIMPLE)=VALUE(prob) BY x.
4 Partie 3 : Distribution normale
4.1 Exercice 3.1 : Pression artérielle
La pression artérielle systolique dans une population adulte suit une loi \(\mathcal{N}(125, 18)\) mmHg.
mu <- 125
sigma <- 18
# a) Proportion de sujets hypertendus (PAS >= 140)
prop_hta <- 1 - pnorm(140, mean = mu, sd = sigma)
cat("Proportion HTA :", round(prop_hta * 100, 1), "%\n")
# b) Proportion avec PAS entre 110 et 130
prop_normal <- pnorm(130, mu, sigma) - pnorm(110, mu, sigma)
cat("Proportion normale :", round(prop_normal * 100, 1), "%\n")
# c) Valeur en dessous de laquelle se trouvent 95% des sujets
seuil_95 <- qnorm(0.95, mean = mu, sd = sigma)
cat("Seuil 95% :", round(seuil_95, 1), "mmHg\n")
# d) Visualisation
curve(dnorm(x, mu, sigma), from = 60, to = 190, lwd = 2,
main = "Distribution de la PAS",
xlab = "PAS (mmHg)", ylab = "Densité")
# Zone d'hypertension
x_hta <- seq(140, 190, length.out = 100)
polygon(c(140, x_hta, 190),
c(0, dnorm(x_hta, mu, sigma), 0),
col = rgb(1, 0, 0, 0.3), border = NA)
abline(v = 140, col = "red", lty = 2)
text(155, 0.015, "HTA", col = "red", cex = 1.2)4.2 Exercice 3.2 : Z-scores et comparaisons
Un patient présente les résultats suivants :
| Mesure | Valeur | Moyenne pop. | Écart-type pop. |
|---|---|---|---|
| Glycémie (g/L) | 1.35 | 1.00 | 0.20 |
| Cholestérol total (g/L) | 2.50 | 2.00 | 0.40 |
| IMC (kg/m²) | 28.5 | 25.0 | 3.5 |
valeurs <- c(1.35, 2.50, 28.5)
moyennes <- c(1.00, 2.00, 25.0)
ecarts_types <- c(0.20, 0.40, 3.5)
noms <- c("Glycémie", "Cholestérol", "IMC")
z_scores <- (valeurs - moyennes) / ecarts_types
percentiles <- pnorm(z_scores) * 100
data.frame(
Mesure = noms,
Valeur = valeurs,
Z_score = round(z_scores, 2),
Percentile = round(percentiles, 1)
)Questions :
- Quelle mesure est la plus éloignée de la normale ?
- Pour quelle mesure le patient se situe-t-il au-dessus du 95e percentile ?
5 Partie 4 : Distribution de Poisson
5.1 Exercice 4.1 : Surveillance épidémiologique
Le nombre moyen de cas de dengue par semaine dans un district est de 4 (λ = 4).
lambda <- 4
# a) P(exactement 6 cas cette semaine)
dpois(6, lambda)
# b) P(aucun cas cette semaine)
dpois(0, lambda)
# c) P(plus de 8 cas → seuil d'alerte)
1 - ppois(8, lambda)
# d) Quel seuil pour une alerte à 5% ?
qpois(0.95, lambda)
# Visualisation avec seuil d'alerte
x <- 0:15
probs <- dpois(x, lambda)
seuil <- qpois(0.95, lambda)
couleurs <- ifelse(x > seuil, "red", "steelblue")
barplot(probs, names.arg = x,
col = couleurs,
main = paste("Poisson(λ=4) — Seuil d'alerte :", seuil, "cas"),
xlab = "Nombre de cas", ylab = "Probabilité")6 Partie 5 : Théorème central limite (démonstration)
6.1 Exercice 5.1 : Simulation
set.seed(123)
# Distribution très asymétrique : durée de séjour hospitalier (exponentielle)
duree_sejour <- rexp(10000, rate = 1/5) # moyenne = 5 jours
par(mfrow = c(2, 2))
# Distribution originale
hist(duree_sejour, breaks = 50, main = "Distribution originale\n(exponentielle)",
xlab = "Durée de séjour (jours)", col = "lightgray")
# Moyennes d'échantillons de taille 5
moy_5 <- replicate(5000, mean(sample(duree_sejour, 5)))
hist(moy_5, breaks = 50, main = "Moyennes n=5",
xlab = "Moyenne", col = "lightblue")
# Moyennes d'échantillons de taille 30
moy_30 <- replicate(5000, mean(sample(duree_sejour, 30)))
hist(moy_30, breaks = 50, main = "Moyennes n=30",
xlab = "Moyenne", col = "steelblue")
# Moyennes d'échantillons de taille 100
moy_100 <- replicate(5000, mean(sample(duree_sejour, 100)))
hist(moy_100, breaks = 50, main = "Moyennes n=100",
xlab = "Moyenne", col = "darkblue")
par(mfrow = c(1, 1))Questions :
- À partir de quelle taille d’échantillon la distribution des moyennes devient-elle approximativement normale ?
- Que se passe-t-il avec la variance des moyennes quand n augmente ?
7 Corrigé des questions
Exercice 1.1 :
- P(maladie) = 100/500 = 0.20
- P(maladie | fumeur) = 60/150 = 0.40
- P(fumeur | maladie) = 60/100 = 0.60
- Si indépendants : P(maladie) × P(fumeur) = 0.20 × 0.30 = 0.06, or P(maladie ∩ fumeur) = 60/500 = 0.12 ≠ 0.06. Ils ne sont pas indépendants.
Exercice 1.2 :
- La VPP augmente avec la prévalence.
- La VPP dépasse 50% quand la prévalence atteint environ 10%.
- En dépistage de masse (faible prévalence), beaucoup de faux positifs → test de confirmation nécessaire. En diagnostic ciblé (forte prévalence), le test est plus fiable.
Exercice 3.2 :
- La glycémie (Z = 1.75) est la plus éloignée.
- Z > 1.645 correspond au 95e percentile. La glycémie (Z = 1.75) dépasse ce seuil.
Exercice 4.1 :
Le seuil d’alerte à 5% est de 7 ou 8 cas selon la distribution. Au-delà, on déclenche une investigation épidémiologique.