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 :

  1. Calculer P(maladie cardiovasculaire)
  2. Calculer P(maladie | fumeur)
  3. Calculer P(fumeur | maladie)
  4. Le tabagisme et la maladie cardiovasculaire sont-ils indépendants ?
# 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)

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 :

  1. Comment évolue la VPP avec la prévalence ?
  2. À partir de quelle prévalence la VPP dépasse-t-elle 50% ?
  3. 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"))
Avec SPSS
* 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 :

  1. Quelle mesure est la plus éloignée de la normale ?
  2. 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 :

  1. À partir de quelle taille d’échantillon la distribution des moyennes devient-elle approximativement normale ?
  2. Que se passe-t-il avec la variance des moyennes quand n augmente ?

7 Corrigé des questions

Exercice 1.1 :

  1. P(maladie) = 100/500 = 0.20
  2. P(maladie | fumeur) = 60/150 = 0.40
  3. P(fumeur | maladie) = 60/100 = 0.60
  4. 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 :

  1. La VPP augmente avec la prévalence.
  2. La VPP dépasse 50% quand la prévalence atteint environ 10%.
  3. 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 :

  1. La glycémie (Z = 1.75) est la plus éloignée.
  2. 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.