Introduction à la modélisation statistique et aux simulations de données
INRAE UMR EcoSys
5/12/24
5 étapes pour simuler ses données
Définir la question biologique et la quantité à estimer
Convertir en modèle linéaire
Simuler les données depuis (2)
Valider le modèle
Appliquer aux données
Simulez des données sur la base du modèle suivant: \[y = N(\mu, \sigma)\] à l’aide de la fonction rnorm(n = , mean = , sd = )
mean()
) et l’écart type (sd()
)hist()
)n
Simulez des données avec deux groupes sur la base du modèle suivant: \[y_i = N(\mu_i, \sigma) \\ \mu_i = \beta_0 + \beta_1 \times x_i \\ x_i = \begin{cases} 0, & i = 1 \\ 1, & i = 2 \\ \end{cases} \]
mean()
) et l’écart type (sd()
) par groupelm()
et summary()
n
La variance d’échantillonage diminue avec la taille d’échantillon
Forte probabilité d’obtenir une valeure biaisée avec une faible taille d’échantillon
iter = 100
n = c(5:200)
b0 = 100
b1 = 10
sigma = 10
counter = 0 # compteur à incrémenter de 1 à chaque itération
out = matrix(NA, nrow = iter*length(n), ncol = 7)
colnames(out) = c("iter", # numéro de simulation
"n", # nombre de mesures par groupe
"b1_sim", # différence simulée
"b1_est", # différence estimée
"p", # p-value
"diff_est", # erreur de mesure (est - sim)
"perc_diff" # % erreur (est - sim) / sim * 100
)
# Barre de progression
pb <- progress_bar$new(
format = " downloading [:bar] :percent eta: :eta",
total = nrow(out), clear = FALSE, width= 60)
set.seed(42)
for (i in 1:iter) {
for (reps in 1:length(n)) {
pb$tick()
Sys.sleep(1 / nrow(out))
counter = counter + 1
# Génération du jeu de données simulées
dfsim = data.frame(Id = 1:(n[reps]*2),
groupe = c(rep("1", n[reps]),
rep("2", n[reps])))
dfsim$xi = ifelse(dfsim$groupe == "1", 0, 1)
dfsim = dfsim %>%
mutate(y = rnorm(n(), b0 + b1 * xi, sigma))
# modèle statistique
lm.sim = lm(y ~ groupe, dfsim)
b1_est = as.numeric(coef(lm.sim)[2]) # valeur de b1 estimée
p = p_value(lm.sim)$p[2] # p-value pour b1
diff_est = b1_est - b1
perc_diff = diff_est / b1 * 100
# stockage des données à la ième ligne de la matrice 'out'
out[counter, 1] = i # numéro de simulation
out[counter, 2] = n[reps] # nombre de mesures par groupe
out[counter, 3] = b1 # différence simulée
out[counter, 4] = b1_est # différence estimée
out[counter, 5] = p # p-value
out[counter, 6] = diff_est # erreur de mesure (est - sim)
out[counter, 7] = perc_diff # % erreur (est - sim) / sim * 100
}
}
out %>%
data.frame() %>%
ggplot(aes(x = n, y = b1_est, fill = n)) +
geom_point(alpha = .9, size = 2, shape = 21, color = "black") +
geom_hline(yintercept = b1, linetype = "dashed", size = 1.5) +
scale_fill_viridis(option = "H", direction = -1) +
xlab("Taille d'echantillon par groupe") +
ylab("b1")
Métrique | Définition |
---|---|
Puissance | Proportion des simulations avec des effets significatifs pour un \(\alpha\) donné |
Taux de faux positifs | Proportion des simulations avec des effets significatifs lorsque les données sont simulées sous l’hpothèse nulle |
Couverture statistique | % des simulations pour lesquelles l’intervalle de confiance inclue la valeure simulée |
Erreur de type M | moyenne de la valeure absolue des estimés significatifs pondérée par la taille d’effet |
Erreur de type S | % d’estimés du signe opposé à l’effet |
out = as.data.frame(out)
out = out %>%
mutate(S = ifelse(b1_est < 0, 1, 0),
M = ifelse(abs(b1_est - b1_sim) / b1_sim > .2,
1, 0))
p1 = out %>%
ggplot(aes(x = n, y = b1_est, fill = factor(M))) +
geom_point(alpha = .9, size = 2, shape = 21) +
geom_hline(yintercept = b1, linetype = "dashed", size = 1.5) +
scale_fill_manual(values = c("white", "red")) +
xlab("Taille d'echantillon par groupe") +
ylab("b1") +
theme(legend.position = "none") +
labs(title = "Erreur de type M",
subtitle = "Estimés > 20 % d'erreur")
p2 = out %>%
ggplot(aes(x = n, y = b1_est, fill = factor(S))) +
geom_point(alpha = .9, size = 2, shape = 21) +
geom_hline(yintercept = b1, linetype = "dashed", size = 1.5) +
scale_fill_manual(values = c("white", "red")) +
xlab("Taille d'echantillon par groupe") +
ylab("b1") +
theme(legend.position = "none") +
labs(title = "Erreur de type S")
p1 + p2
Question scientifique
???
Solution - Modèle \[ bill_i = N(\mu_i, \sigma) \\ \mu_i = \beta_0 + \\ \beta_1 \times (flipper - flipper_{\mu}) + \\ \beta_2 \times Sp_{[i = 2]} + \beta_3 \times Sp_{[i = 3]} +\\ \beta_4 \times (flipper - flipper_{\mu}) \times Sp_{[i = 2]} \\ \beta_5 \times (flipper - flipper_{\mu}) \times Sp_{[i = 3]} \]
n = 50
sigma_bill = 2.5
sigma_flipper = 5
Sp = c("Ad", "Ch", "Gen")
b0 = 40 # moyenne bec manchots d'Adélie
b1 = 0.1 # pente bec x aile Adélie
b2 = 10 # différence bec Chinstrap - Adélie
b3 = 2 # différence bec Gentoo - Adélie
b4 = .1 # différence de pente Chinstrap - Adélie
b5 = .2 # différence de pente Gentoo - Adélie
g0 = 190
g1 = 5
g2 = 30
df = crossing(n = 1:n, Sp)
df$xi_2 = ifelse(df$Sp == "Ch", 1, 0)
df$xi_3 = ifelse(df$Sp == "Gen", 1, 0)
set.seed(42)
df = df %>%
mutate(flipper_mu = 200,
flipper = rnorm(n(), g0 + g1 * xi_2 + g2 * xi_3, sigma_flipper)) %>%
mutate(flipper_cen = flipper - flipper_mu) %>%
mutate(bill = rnorm(n(),
b0 +
b1 * flipper_cen +
b2 * xi_2 +
b3 * xi_3 +
b4 * flipper_cen * xi_2 +
b5 * flipper_cen * xi_3,
sigma_bill))
Tester le modèle statistique avec les fonctions lm()
et summary()
Utilisez la fonction check_model()
pour évaluer la pertinence du modèle sur les données simulées
Code
Parameter | Coefficient | SE | 95% CI | t(144) | p
------------------------------------------------------------------------------
(Intercept) | 39.71 | 0.77 | [38.19, 41.24] | 51.44 | < .001
flipper cen | 0.06 | 0.07 | [-0.07, 0.20] | 0.97 | 0.335
Sp [Ch] | 10.81 | 0.93 | [ 8.97, 12.64] | 11.67 | < .001
Sp [Gen] | 1.98 | 1.63 | [-1.25, 5.21] | 1.21 | 0.228
flipper cen × Sp [Ch] | 0.28 | 0.10 | [ 0.09, 0.47] | 2.87 | 0.005
flipper cen × Sp [Gen] | 0.25 | 0.10 | [ 0.06, 0.44] | 2.65 | 0.009
Code
Code
Code
Hypothèses :
Une augmentation de température du sol modérée (~2°C) stimule la croissance
Les pics de températures sont très néfastes aux organismes du sol
La contamination au cuivre a un effet modéré sur la biomasse des organismes du sol
La présence de cuivre combinée lors d’un pic de température amplifie la perte de biomasse
Simuler un modèle à partir des informations suivantes Design expérimental
3 réplicats / conditions
2 niveaux de contamination : contrôles et 80 mg / kg
3 températures : 18°, 20° et 28°
Données connues
Biomasse à 18° : 500 mg
Biomasse à 20° : 550 mg
Biomasse à 28° : 350 mg
n = 10
sigma = 10
b0 = 100
b1 = 50
Eq = 5 # Région d'équivalence = +/- 5
groupe = c("1", "2")
df = data.frame(Rep = 1:(n[1]*2),
groupe = c(rep("1", n[1]),
rep("2", n[1])))
df$xi = ifelse(df$groupe == "1", 0, 1)
set.seed(42)
df = df %>%
mutate(y = rnorm(n(), b0 + b1 * xi, sigma))
lm.eq = lm(y ~ groupe, df)
# pred.b1 = avg_slopes(lm.eq, variables = "groupe")
hyp = hypotheses(lm.eq,
equivalence =
c(- Eq, Eq))
hyp[2]
Estimate Std. Error z Pr(>|z|) S 2.5 % 97.5 % p (NonSup) p (NonInf)
42.9 5.79 7.4 <0.001 42.8 31.5 54.2 1 <0.001
p (Equiv)
1
Term: groupe2
Columns: term, estimate, std.error, statistic, p.value, s.value, conf.low, conf.high, statistic.noninf, statistic.nonsup, p.value.noninf, p.value.nonsup, p.value.equiv
out %>%
mutate(sig = case_when(p < 0.05 ~ 1, p >= 0.05 ~ 0)) %>%
group_by(n) %>%
summarise(sig.prop = sum(sig)/n() * 100) %>%
ggplot(aes(x = n, y = sig.prop, fill = n)) +
geom_line() +
geom_point(alpha = .9, size = 3, shape = 21, color = "black") +
geom_hline(aes(yintercept=80),linetype="dashed") +
scale_fill_viridis(option = "H", direction = -1) +
xlab("Taille d'echantillon par groupe") +
ylab("Puissance statistique")