Skip to content

Exercice 2 : Simulation de variables aléatoires et loi des grands nombres

Problème : Modélisation stochastique de la dérive génétique et de la loi des grands nombres

Section titled “Problème : Modélisation stochastique de la dérive génétique et de la loi des grands nombres”

En biologie évolutive, la dérive génétique désigne la modification aléatoire de la fréquence des allèles d’une population au fil des générations, indépendamment de la sélection naturelle. Elle est particulièrement marquée dans les petites populations (effet fondateur, goulot d’étranglement).

Imaginons une population diploïde d’effectif constant NN individus. Concernant un gène donné possédant deux allèles AA et aa, on s’intéresse à la fréquence pp de l’allèle AA dans la population. Si la reproduction se fait selon le modèle de Wright-Fisher, le nombre de copies de l’allèle AA à la génération suivante suit une loi binomiale.

L’objectif de ce problème est d’utiliser Python pour simuler cette dérive génétique, d’illustrer la Loi des Grands Nombres à travers l’estimation de la fréquence allélique moyenne, et d’analyser les limites biologiques de ce modèle numérique simplifié.


Partie 1 : Outils de base et Génération aléatoire

Section titled “Partie 1 : Outils de base et Génération aléatoire”
  1. [Q1] Importer le module nécessaire pour manipuler des tableaux et générer des nombres aléatoires en Python. Écrire une fonction tirage_bernoulli(p) qui prend en argument une probabilité p∈[0,1]p \in [0, 1] et renvoie un booléen (True ou False) simulant une variable de Bernoulli de paramètre pp.
  2. [Q2] Écrire une fonction generation_wright_fisher(N, p) qui simule une génération. Elle prend en compte l’effectif de la population NN (nombre d’individus, soit 2N2N allèles) et la fréquence actuelle pp de l’allèle AA. Elle doit renvoyer la nouvelle fréquence p′p' de l’allèle AA à la génération suivante en utilisant un tirage binomial. (On pourra utiliser np.random.binomial).

Partie 2 : Simulation de trajectoires temporelles

Section titled “Partie 2 : Simulation de trajectoires temporelles”
  1. [Q3] Écrire une fonction trajectoire_derive(N, p_0, T) qui simule l’évolution de la fréquence de l’allèle AA sur TT générations.
    • Entrées : NN (effectif), p0p_0 (fréquence initiale), TT (nombre de générations).
    • Sortie : Un tableau numpy de taille T+1T+1 contenant les fréquences de AA de la génération 00 à la génération TT.
  2. [Q4] Que se passe-t-il biologiquement et mathématiquement lorsque la fréquence pp atteint 00 ou 11 ? Modifier la fonction précédente pour que la simulation s’arrête (ou que la fréquence reste bloquée) si l’allèle est fixé ou éliminé.

Partie 3 : Loi des Grands Nombres et Analyse Critique

Section titled “Partie 3 : Loi des Grands Nombres et Analyse Critique”
  1. [Q5] On souhaite estimer l’espérance de la fréquence allélique à la génération T=50T = 50 pour une population de taille N=50N = 50 avec une fréquence initiale p0=0.5p_0 = 0.5. Écrire un script utilisant une boucle ou une vectorisation pour simuler MM trajectoires indépendantes, et calculer la moyenne des fréquences obtenues à T=50T = 50.
  2. [Q6] Analyse critique et biométrique : En augmentant MM (par exemple de 1010 à 100 000100\,000), quelle loi mathématique observe-t-on sur l’estimation de la moyenne ? Discutez des limites biologiques du modèle de Wright-Fisher (générations non chevauchantes, panmixie, absence de mutation et de sélection).

  • Q1 : Pensez à np.random.rand() qui renvoie un float uniforme sur [0,1[[0, 1[.
  • Q2 : Un individu diploïde porte 2 allèles. Pour NN individus, il y a 2N2N tirages avec une probabilité de succès pp. La fonction np.random.binomial(n, p) renvoie le nombre de succès pour nn expériences.
  • Q4 : Si p=0p=0 ou p=1p=1, la loi binomiale donnera toujours 00 ou 2N2N, l’état devient un état absorbant.
  • Q6 : Pensez à relier la stabilité de la moyenne empirique à la Loi Faible (ou Forte) des Grands Nombres. Côté biologique, interrogez-vous sur la réalité d’une population à NN constant sans flux migratoire.

[Q1]

import numpy as np
def tirage_bernoulli(p):
# np.random.rand() renvoie un nombre dans [0, 1[
return np.random.rand() < p

[Q2]

def generation_wright_fisher(N, p):
# Il y a 2N allèles au total dans une population diploïde de taille N
# On tire le nombre de copies de l'allèle A selon une loi binomiale B(2N, p)
nb_alleles_A = np.random.binomial(2 * N, p)
return nb_alleles_A / (2 * N)

[Q3 & Q4]

def trajectoire_derive(N, p_0, T):
trajectoire = np.zeros(T + 1)
trajectoire[0] = p_0
p = p_0
for t in range(1, T + 1):
# Si l'allèle est fixé (1) ou éliminé (0), on bloque la fréquence (états absorbants)
if p == 0.0 or p == 1.0:
trajectoire[t] = p
else:
p = generation_wright_fisher(N, p)
trajectoire[t] = p
return trajectoire

[Q5]

def esperance_generation_T(N, p_0, T, M):
frequences_ finales = np.zeros(M)
for i in range(M):
traj = trajectoire_derive(N, p_0, T)
frequences_finales[i] = traj[-1]
# Estimation de l'espérance par la moyenne empirique
return np.mean(frequences_finales)
# Exemple d'appel :
# moyenne_estimee = esperance_generation_T(N=50, p_0=0.5, T=50, M=1000)

[Q6]

  • Interprétation mathématique (Loi des Grands Nombres) : Lorsque le nombre de simulations MM tend vers l’infini, la moyenne empirique des fréquences alléliques à la génération TT converge presque sûrement vers l’espérance mathématique de la variable aléatoire représentant la fréquence à la génération TT (en vertu de la Loi des Grands Nombres). On observe graphiquement que la variance de l’estimateur diminue en O(1/M)\mathcal{O}(1/\sqrt{M}).

  • Analyse critique des limites du modèle (Biologie) :

    1. Effectif constant (NN) : Dans la nature, les populations subissent des fluctuations démographiques (prédation, climat), NN est rarement constant.
    2. Panmixie (reproduction aléatoire) : Le modèle suppose que tout individu a une probabilité égale de se reproduire avec un autre. Or, en réalité, il existe une structure spatiale (distance, territorialité) et une sélection sexuelle.
    3. Absence de mutations et de flux géniques : Le modèle de Wright-Fisher pur ne crée pas de nouveaux allèles (pas de mutation) et s’affranchit des migrations extérieures, ce qui conduit inéluctablement à la fixation ou à la perte totale de l’allèle à long terme (monomorphisme de la population), ce que l’on observe rarement à grande échelle grâce aux forces combinées de la mutation et de la sélection.