You are on page 1of 36

Les mathématiques des maladies infectieuses.

Modèles épidémiologiques et calcul des taux de reproduction.

Victor GRUSON - 2021/2022 - n° 11515 1/12


Comment obtenir le taux de reproduction d'une
maladie infectieuse à l'aide d'une simulation
informatique pour prévoir son évolution?

I. Les modèles épidémiologiques.

II. Calcul de R0 et Re.

III. Conclusion.
2/12
I.
Les modèles compartimentaux

S I R

S E I R

S E I R S
3/12
I.
Les modèles compartimentaux

S I R

S E I R

S E I R S
3/12
I.
Les modèles compartimentaux

S I R

S E I R

S E I R S
3/12
I.
Les modèles compartimentaux

S I R

S E I R

S E I R S
3/12
I.
Les modèles compartimentaux

S I R

S E I R

S E I R S
3/12
I. Exemples sur Python:
Implémentés à l’aide d’un système différentiel
(modèle déterministe)

dS - γ*β*I*S
=
dt population

dI γ*β*I*S - I
dt = population α

dR I
=
dt α

4/12
I. Exemples sur Python:
Implémentés à l’aide d’un système différentiel
(modèle déterministe)

SIR SEIR SEIRDS

production production production


personnelle personnelle personnelle

4/12
I.
Le modèle automate cellulaire
(modèle probabiliste)

Infecté

● Visualisation Infecté (plus contagieux)


matricielle
Rétablie
● Evolution au
cours du temps
Décédé
et des voisins

Susceptible

production
personnelle
5/12
I.
Le modèle automate cellulaire
(modèle probabiliste)
3 étapes pour l'implémenter:

et

5/12
II.
Le R0
C’est le nombre d’humains contaminés par un seul infecté durant sa
période de contagiosité et cela au début de l’épidémie.

● Dépend de trois facteurs:

- la durée de la contagiosité de la maladie;

- la probabilité d’infection après un contact entre une


personne infectée et une personne susceptible;

- la fréquence des contacts humains.

6/12
II.
CAS 1: Modèle compartimental simple.

R0 =

=7j production
personnelle

= 0.05

= 15 contacts/j

R0 = 5.25
7/12
II.
CAS 2: Modèle automate cellulaire.

R0 =

=7j production
production
personnelle
personnelle

= 0.05

= 8 contacts/j

R0 = 2.8
8/12
II. R0 Re(t):
C’est le nombre d’humains contaminés par un seul
infecté durant sa période de contagiosité à un instant t.

Modèle compartimental

production
personnelle
S(t)
SIR Re(t) = R0 *
population

9/12
II. R0 Re(t):
C’est le nombre d’humains contaminés par un seul
infecté durant sa période de contagiosité à un instant t.

Modèle compartimental

production
personnelle
S(t)
SEIRDS Re(t) = R0 *
population

9/12
II. R0 Re(t):
C’est le nombre d’humains contaminés par un seul
infecté durant sa période de contagiosité à un instant t.

Modèle automate cellulaire

S(t) I(t)
Re(t) = R0 * Re(t) =
population I(t - tempsinfection)

10/12
II. R0 Re(t):
C’est le nombre d’humains contaminés par un seul
infecté durant sa période de contagiosité à un instant t.

Modèle automate cellulaire

production
personnelle
I(t)
Re(t) =
I(t - tempsinfection)

10/12
II. R0 Re(t):
C’est le nombre d’humains contaminés par un seul
infecté durant sa période de contagiosité à un instant t.

Modèle automate cellulaire

production
personnelle
I(t)
Re(t) =
I(t - tempsinfection)
Croissance exponentielle des cas

Décroissance des cas

10/12
III. Situation du coronavirus en France
(1 an)

Re(t)

Re=2

Re=1

production
covidtracker.fr
personnelle

11/12
III.
CONCLUSION:

● La modélisation informatique des épidémies est limitée mais


se trouve être intéressante, en particulier le modèle
probabiliste qui se rapproche beaucoup de ce qui arrive
réellement dans le monde.

● Grâce à ces modèles, on peut évaluer - en ayant les données


nécessaires - la contagiosité de la maladie.

● Il est donc possible d’évaluer l’impact des contraintes


sanitaires (confinements, port du masque) avec nos
simulations et évaluer leur efficacité.

12/12
Annexe
Re(t) sur le SEIRDS avec la méthode 2

production
personnelle
Annexe
Personne infectée T T ou P

T T
Personne infectée mais plus contagieuse T P , P ou P

T: temps

P: hasard Personne décédée

V: voisins

Personne immunisée après T T ou P


infection

V V
Personne saine P P ou P
Annexe

production
personnelle
# Compartimental vf.py

001| ##TIPE 2021 2022 / DIFFUSION D UNE MALADIE


002|
003| #Aspect théorique de la diffusion d une maladie.
004|
005| #Utilisation des équations différentielles
006| ##Importation
007|
008|
009| import matplotlib.pyplot as plt
010| import math
011| import scipy.integrate as sp
012| import numpy as np
013|
014|
015| ##Code
016|
017|
018| # def calculint(f,a,b,n):
019| # res=0
020| # pas=(b-a)/n
021| # for i in range (n):
022| # res+=f(a+i*pas)
023| # return(res*pas)
024|
025|
026|
027| def calculreproductionprime(S,E,I,R,D,tempsincubation,periodeinfection):
028| res=[]
029| n=len(S)
030| for i in range (n):
031| res.append(5.25*S[i]/(S[i]+I[i]+E[i]+R[i]))
032| return res
033|
034|
035|
036| def calculreproduction(S,I,E,R,D,tempsincubation,periodeinfection):
037| res=[]
038| n=len(S)
039|
040| for i in range (n-periodeinfection):
041| dif=I[i+periodeinfection]/I[i]
042| res.append(dif)
043|
044| return res
045|
046|
047| # def calculintliste(x,y):

1
048| # res=0
049| # n=(x)
050| # for i in range (n):
051| # res+=y[i]
052| # return(res*(1/7))
053|
054| def programme(temps,population,val_B,val_y,val_u,val_s,val_d,val_a,init_infect,init_repos,modele="SIR"): #modele compartimentaux
055| #val_B=proba d etre infecté * fréquence des contacts= 15*0.05
056| #val_y=1/temps de contagion
057| #val_u= proba de mourir
058| #val_a=1/temps d incubatioin
059|
060| def sys_dif_sir(SIR,te): #modèle classique SIR
061| S,I,R=SIR
062| res= [-(val_B*I*S)/population ,(val_B*I*S)/population -val_y*I ,val_y*I]
063| return res
064|
065|
066|
067| def sys_dif_seir(SEIR,te):#modèle classique SEIR
068| S,E,I,R=SEIR
069| res= [-(val_B*I*S)/population ,(val_B*I*S)/population -val_a*E,val_a*E -val_y*I, val_y*I]
070| return res
071|
072| def sys_dif_seird(SEIRD,te):#modèle SEIR avec décès
073| S,E,I,R,D=SEIRD
074| res= [-(val_B*I*S)/population ,(val_B*I*S)/population -val_a*E,val_a*E -val_y*I-val_u*I, val_y*I,val_u*I]
075| return res
076|
077| def sys_dif_final(SEIDRS,te):
078| S,E,I,D,R=SEIDRS
079| res=[val_s*R-(val_B*I*S)/population ,(val_B*I*S)/population -val_a*E, val_a*E -val_y*I-val_u*I,val_u*I, val_y*I-val_s*R]
080| return res
081| #utilisation de odeint pour résoudre le sys_dif
082|
083|
084| t=[i for i in range (temps)]
085|
086|
087|
088| if modele=="SIR" :
089|
090| val_init=[population-init_infect-init_repos,init_infect,init_repos]
091|
092|
093|
094| arg=sp.odeint(sys_dif_sir,val_init,t)
095| sain,infecte,repos=arg[:,0],arg[:,1],arg[:,2]
096|

2
097| print(calculintliste(t,infecte))
098|
099| plt.title("Courbes de situation")
100| # plt.plot(t,sain,label="Personnes saines")
101| plt.plot(t,repos,label="Personnes immunisées")
102| plt.plot(t,infecte,label="Personnes inféctées")
103| plt.legend()
104| plt.show()
105| return(sain,infecte,repos)
106|
107|
108|
109|
110|
111| elif modele=="SEIR":
112|
113| init_expo= val_B*(population-init_infect-init_repos)*init_infect//population
114| val_init=[population-init_infect-init_repos,init_expo,init_infect,init_repos]
115|
116|
117|
118| arg=sp.odeint(sys_dif_seir,val_init,t)
119| sain,expose,infecte,repos=arg[:,0],arg[:,1],arg[:,2], arg[:,3]
120|
121| plt.title("Courbes de situation")
122| # plt.plot(t,sain,label="Personnes saines")
123| plt.plot(t,expose,label="Personnes exposées")
124| plt.plot(t,repos,label="Personnes immunisées")
125| plt.plot(t,infecte,label="Personnes inféctées")
126| plt.legend()
127| plt.show()
128|
129| elif modele=="SEIRD":
130|
131| # init_expo= val_B*(population-init_infect-init_repos)*init_infect//population
132| init_expo= 0
133| val_init=[population-init_infect-init_repos,init_expo,init_infect,init_repos,0]
134|
135|
136|
137| arg=sp.odeint(sys_dif_seird,val_init,t)
138| sain,expose,infecte,repos,deces=arg[:,0],arg[:,1],arg[:,2], arg[:,3],arg[:,4]
139|
140| # inff1=[5.25**(i/3) for i in range (20)]
141| # inff2=[0 for i in range (20,temps)]
142| # infection=inff1+inff2
143| #
144|
145| plt.title("Courbes de situation")

3
146| # plt.plot(t,sain,label="Personnes saines")
147| plt.plot(t,expose,label="Personnes exposées")
148| plt.plot(t,repos,label="Personnes immunisées")
149| plt.plot(t,infecte,label="Personnes inféctées")
150| plt.plot(t,deces,label="Personnes décédés")
151| # plt.plot(t,infection,label="test")
152|
153| plt.legend()
154| plt.show()
155|
156| return(sain,infecte,expose,repos,deces)
157|
158|
159|
160|
161|
162| elif modele=="SEIRDS":
163|
164| init_expo= 0
165| init_morts=0
166| val_init=[population-init_infect-init_repos-init_expo,init_expo,init_infect,init_morts,init_repos]
167| arg=sp.odeint(sys_dif_final,val_init,t)
168|
169| sain,expose,infecte,morts,repos=arg[:,0],arg[:,1],arg[:,2], arg[:,3],arg[:,4]
170|
171|
172|
173|
174|
175| #R0= tauxdetransmission*contacts*durée d'infection.
176|
177|
178|
179|
180| plt.title("Courbes de situation")
181| plt.plot(t,sain,label="Personnes saines")
182|
183| plt.plot(t,expose,label="Personnes exposées")
184| plt.plot(t,morts,label="Personnnes décèdés")
185| plt.plot(t,repos,label="Personnes immunisées")
186| plt.plot(t,infecte,label="Personnes inféctées")
187| plt.legend()
188| plt.show()
189|
190| return(sain,infecte,expose,repos,morts)
191|
192|
193|
194|

4
195| test=programme(600,100000,1.25,0.15,0.01,0.0125,0.001,0.3,1,0,"SEIRDS")
196| test=np.array(test)
197| S1,E1,I1,R1,D1=test[0],test[1],test[2],test[3],test[4]

5
# re stats auto.py

001| ##TIPE 2021 2022 / DIFFUSION D UNE MALADIE RE


002|
003|
004|
005|
006|
007| ##Importation
008|
009| from copy import *
010| import numpy as np
011| import matplotlib.pyplot as plt
012| import time
013| import matplotlib.animation as anim
014| import random
015| import csv
016|
017| ##Code
018|
019| A=1
020|
021| C=1
022|
023| R=[]
024|
025| #
026| #
027| with open(r"C:\Users\victo\OneDrive\Documents\Python Scripts\Stats.csv",'w',newline='') as me:
028| reader=csv.writer(me,delimiter=',' )
029|
030|
031| # plus infection est elevé; moins le virus se diffuse
032|
033|
034|
035|
036| def
programme(population=100,infection=30,deces=0,tempsinfection=14,tempscontagion=7,preinf=0.9,tempsimmunisation=15,interval=100,jourvaccin=2,propvacc
in=0.005,confinement=[[1,41],[42,81],[82,161],[162,245],[246,285],[286,381],[382,405],
[406,440]],incidenceconf=[1.4,1.48,1.10,0.82,1.25,0.95,0.90,1]):
037|
038| global C
039| global A
040| global R
041| A=1
042| repetition=0
043| def compte_infecte(liste):
044| n=len(liste)

1
045| listefinale=[(n+2)*[('a',0)]]
046| for k in range (n):
047| listefinale=listefinale+[[('a',0)]+liste[k]+[('a',0)]]
048| listefinale=listefinale+[(n+2)*[('a',0)]]
049| nprime=len(listefinale)
050| compteur=0
051| resultat=[]
052| for i in range (1,nprime-1):
053| res=[0]*n
054| for j in range (1,nprime-1):
055| compteur= listefinale[i-1][j-1][0]+listefinale[i-1][j][0]+listefinale[i-1][j+1][0]+listefinale[i][j-1][0]+listefinale[i][j+1]
[0]+listefinale[i+1][j-1][0]+listefinale[i+1][j][0]+listefinale[i+1][j+1][0]
056|
057| res[j-1]=compteur
058| resultat=resultat+[res]
059|
060|
061| return (resultat)
062|
063|
064|
065|
066|
067| def creation_listevide(n):
068| liste=n*[n*[(0,0)]]
069| return (liste)
070|
071|
072|
073|
074| def creation_listealeatoire(n,h=0.2):
075| liste=[]
076| for j in range (n):
077| listel=n*[('a',0)]
078| for i in range(n):
079| c=random.random()
080| if c<=h:
081| listel[i]=('b',0)
082| liste=liste+[listel]
083| return (liste)
084|
085| def occurence(x,mot):
086| compteur=0
087| for i in (mot):
088| if i==x:
089| compteur+=1
090| return compteur
091|
092|

2
093| #ici on va definir les differentes variables de l'experience
094| def etat_cellule (voisins,liste,i,j):
095| w=random.random()
096| if C==2 and (w<=(propvaccin) or liste[i][j][0]=='v') and liste[i][j][0]!='d':
097|
098|
099| return ('v',0)
100| elif liste[i][j][0]=='b' and liste[i][j][1]<=tempscontagion:
101| h=liste[i][j][1]
102| return ('b',h+1)
103| elif liste[i][j][1]>=tempscontagion and liste[i][j][0]!='a' and liste[i][j][0]!='v' :
104| a=liste[i][j][1]
105| c=random.random()
106| h=liste[i][j][1]
107| if (c<deces or liste[i][j][0]=='d') and liste[i][j][0]!='c'and liste[i][j][0]!='g' :
108| return ('d',99)
109| else:
110|
111|
112|
113| if liste[i][j][1]>tempsinfection:
114| if liste[i][j][1]>=(tempsinfection+tempsimmunisation) and liste[i][j][0]!='d':
115|
116|
117| return ('a',0) #ici l'etat revient à l'inital
118| else:
119|
120| return('g',h+1)
121| else:
122| return ('c',a+1)
123| elif liste[i][j][0]!='b' and occurence('b',voisins[i][j])>0 and (liste[i][j][1]==0): #temps d immunisation
124| a=occurence('b',voisins[i][j])/(infection)
125| for jours in range (len(confinement)): #on simule ici une situation de confinement
126| if confinement[jours][0]<=repetition<=confinement[jours][1]:
127|
128| a=a/(incidenceconf[jours])
129| c=random.random()
130| if c<=a:
131| return ('b',0)
132| else:
133| return ('a',0)
134|
135| else:
136| return('a',0)
137|
138|
139|
140|
141|

3
142|
143|
144|
145|
146|
147|
148|
149|
150|
151| def calcul_cellule (liste):
152| voisinsmatrice=compte_infecte(liste)
153| n=len(liste)
154| for i in range (n):
155| for j in range (n):
156| liste[i][j]=etat_cellule(voisinsmatrice,liste,i,j)
157| return liste
158|
159|
160|
161| K=creation_listealeatoire(population,preinf/100)
162|
163|
164|
165| def auto_cellulaire(liste,nombre):
166|
167| global A
168| global R
169| h=0
170| infecte=0
171| mort=0
172| imunise=0
173| guerison=0
174| rien=0
175| vaccin=0
176| R=calcul_cellule(liste)
177|
178| for i in (R):
179| for etat, temps in (i):
180| if etat=='a':
181|
182| rien+=1
183| elif etat=='b':
184|
185| infecte+=1
186| elif etat=='c':
187|
188| guerison+=1
189| elif etat=='g':
190|

4
191| imunise+=1
192| elif etat=='d':
193|
194| mort+=1
195| elif etat=='v':
196|
197| vaccin+=1
198|
199| if (infecte,guerison,imunise)==(0,0,0) and A==1:
200|
201|
202| A=2
203| # print ('morts=',mort,'imunises=',imunise,'rien=',rien,'sur',len(liste)**2)
204| # return (mort,imunise,rien,len(liste)**2)
205| # else:
206| return (mort,imunise,rien,infecte,vaccin,len(liste)**2)
207|
208|
209|
210|
211|
212| re=[[] for i in range (30)]
213|
214|
215| #ici on utilise les simulations pour créer des csv et avoir des résultats statistiques
216|
217| for j in range (30):
218| print(j)
219| repetition=0
220| while repetition<120: #pour avoir des cas valables
221| ress=[]
222|
223|
224| repetition=0
225| A=1
226|
227| R=[]
228|
229| while A==1 and repetition<500:
230|
231| if R==[]:
232|
233| (a,b,c,d,e,f)=auto_cellulaire(creation_listealeatoire(population,preinf/100),repetition)
234| repetition+=1
235|
236| else:
237| (a,b,c,d,e,f)=auto_cellulaire(R,repetition)
238|
239| repetition+=1

5
240| if repetition==jourvaccin:
241| C=2
242|
243|
244| ress.append([a,b,c,d,e,f])
245|
246|
247| t=[i for i in range (len(ress))]
248| ress=np.array(ress)
249|
250| S,I,R,D=ress[:,2],ress[:,3],ress[:,1],ress[:,0]
251| for i in range (repetition-8):
252|
253| re[j].append(I[i+7]/I[i])
254|
255|
256|
257| with open(r"C:\Users\victo\OneDrive\Documents\Python Scripts\Stats.csv",'a',newline='') as me:
258| reader=csv.writer(me,delimiter=',')
259| # (a,morts,b,immunises,c,rien,d,total
260| reader.writerows(re)
261|
262|

You might also like