Le modèle SEIRD de l'Australie

In [1]:
from IPython.display import HTML
HTML('''<script>
code_show=true; 
function code_toggle() {
 if (code_show){
 $('div.input').hide();
 } else {
 $('div.input').show();
 }
 code_show = !code_show
} 
$( document ).ready(code_toggle);
</script>
Le code python est caché par défault.
Pour l'activer ou le désactiver cliquez <a href="javascript:code_toggle()">ici</a>.''')
Out[1]:
Le code python est caché par défault. Pour l'activer ou le désactiver cliquez ici.

ESTIMATION DE LA DUREE DE L'EPIDEMIE DU COVID 19 EN AUSTRALIE

SALL Serigne 28/05/2020

Plan:

1) Introduction

-Pourquoi l'Australie?

-Choix des variables.

2) Importation et Visualisation des données:

- En Australie:

3) Modèle

- Choix du modèle

- Méthode d'estimation des paramètres

4) Résultats:

- En Australie

5) Représenation du modèle SEIRD

6) Conclusion

Introduction

A la vue de l'épidémie actuelle, et de nos compétences en Statistiques, nous avons été amener à réaliser un projet de modélisation sur l'épidémie du Coronavirus dans différents pays. Je vous propose donc une petite analyse des données disponibles jusqu'au 28/05/2020 (amenée à etre réactualiser). Le but de cette étude est de modéliser, de visualiser, de prédire et enfin de communiquer. Je serai amené à estimer la date du pic de l'épidémie pour différentes variables en Australie.

Pourquoi l'Australie?

**La pensée nait de la contradiction** dixit un proverbe. Alors que mes collègues de projet ont fait le choix de travailler sur des pays ou la pandémie faisait le plus de ravages tels que la FRANCE, l'ITALIE..., j'ai naturellement porté mon étude sur des pays relativement moins "impactés" pour faire un peu naitre l'esprit de contradiction. Et il me semble pertinant d'observer l'évoluation du covid 19 dans ses multiples aspects afin de comprendre les facteurs de sa propagation dans le but de les limiter. Mon choix était dans un premier temps porté sur le Sénégal, mais au moment ou nous avons décidé de réaliser notre étude, le Sénégal enregistrait ses tous premiers cas de decès liés au covid et heuresement d'ailleurs, son évolution étant tres lente, il semble évident qu'il était difficile de travailer sur des données non-évolutives. J'ai donc choisi de porter mon étude sur l'Australie. L’Australie compte un peu plus de 25 millions d’habitants pour une surface 14 fois supérieure à celle de la France métropolitaine. Tout comme la Nouvelle-Zélande, le pays entouré d’océan, lui permet de contrôler assez facilement ses frontières. Par son isolement, sa faible densité de population, 3 habitants km² (en France nous sommes à plus de 100 habitants au km²), la lutte contre le Covid-19 est facilitée. Les mesures de quarantaine pour tous les produits organiques y compris les animaux vivants (domestiques ou non) étaient déjà largement pratiquées avant la crise sanitaire. Il sera donc interessant de vérifier que tous ces points sont d'un avantage pour la lutte contre a propagation.

Choix des variables d'étude

In [ ]:
Pour commencer, on doit choisir différentes variables sur lesquelles on concentrera l'analyse. J'ai choisi les variables suivantes:
    Décès par jours: dailydeath
    Infectés par jours: newinfected
Pourquoi choisir de faire une analyse sur le nombre de decès ?
Le nombre de décès est surement la donnée la plus fiable. Il est plus facile de vérifier si la mort est due au covid 19 que
de tester toute la population infectée. En effet, au moins 10% de la poupaltion porte la maladie
sans symptomes, et ces invidus ne sont pas détectés. De plus, un test est souvent réalisé à la mort pour détécter la cause du décès.
Pour effectuer l'étude en fonction des infectés, on pourra ensuite étudier le lien entre le nombre de décès et le nombre d'infetés.

Importation et Visualisation des données réelles

En AUSTRALIE

Importation

In [15]:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

data_australie = pd.read_excel("Classeur_1.xlsx", "Feuil1")
print(data_australie)
        Date  Total cas cumulés(infected) Total decès cumulés(dailydeath)  \
0  2020-03-15                         298                               5
1  2020-03-16                  376 (+26%)                        5 (+00%)
2  2020-03-17                  453 (+20%)                        5 (+00%)
3  2020-03-18                  566 (+25%)                        6 (+20%)
4  2020-03-19                  708 (+25%)                        7 (+17%)
..        ...                         ...                             ...
69 2020-05-23                7 106 (+00%)                      102 (+01%)
70 2020-05-24                7 109 (+00%)                      102 (+00%)
71 2020-05-25                7 118 (+00%)                      102 (+00%)
72 2020-05-26                7 133 (+00%)                      102 (+00%)
73 2020-05-27                7 133 (+00%)                      102 (+00%)

    Nombre de décès par jour(dailydeath)  Guérisons cumulées
0                                      0                  27
1                                      0                  27
2                                      0                  27
3                                      1                  43
4                                      1                  46
..                                   ...                 ...
69                                     1                6494
70                                     0                6506
71                                     0                6532
72                                     0                6553
73                                     0                6553

[74 rows x 5 columns]

Visualisation

Nombre de nouveaux décès par jour
In [28]:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy.integrate import odeint
from scipy.optimize import least_squares
import time
import datetime as dt


                    # Données : Reelles (Modifier selon besoin)



# CodePays = Identifiant du pays que l'on veut étudier, sous la forme "CODE"
CodePays = "AUS"


# On définit un jour du début des observations.

# Pour commencer à une date précise, on la définit. Sinon on laisse 0, 0, 0.
# Exemple : pour le 13 Mars 2020, on remplace 0, 0, 0 par 13, 3, 2020
DateDeb = 1, 3, 2020


# Ne pas modifier les commandes ci-dessous : dépendent de celles au dessus

data = pd.read_excel("https://www.ecdc.europa.eu/sites/default/files/documents/COVID-19-geographic-disbtribution-worldwide.xlsx")
data = data[data["countryterritoryCode"] == CodePays]
data = (np.array(data))[::-1]

i = 0
if (DateDeb == (0, 0, 0)):
    while (data[i][4]<NbIDeb):
        i = i+1
else :
    while ((data[i][1], data[i][2], data[i][3]) != (DateDeb)):
        i = i+1

data = data[i:,:]


MpJreel = data[:,5]


LJours = data[:, 0]
n = len(LJours)

            # Simulation et Graphes





fig = plt.figure(facecolor='w', figsize=(10,8), dpi=180)
plt.suptitle('Evolution du nombre de morts du Covid-19 en Australie',fontsize=18, color="red")
plt.subplot(221)
plt.tick_params(axis = 'both', labelsize = 8)
plt.xticks(rotation = 'vertical')
plt.plot(LJours, MpJreel, 'red', alpha=0.5, lw=2, label='Morts réels' )

plt.xlabel('Temps (jours)')
plt.ylabel('Nombre (individus)')
plt.grid(b=True, which='major', c='w', lw=2, ls='-')
legend = plt.legend()
legend.get_frame().set_alpha(0.5)


plt.show()

Afin de réaliser une étude relativement précise sur l'évolution du covid 19 en Australie et d'apromixer au maximum les paramètres d'étude, nous avons décidé d'implanter une fonction MoyMobile qui permet de lisser l'évolution réelle du nombre de décès par jours.

In [31]:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy.integrate import odeint
from scipy.optimize import least_squares
import time
import datetime as dt


def MoyMob(T, k):                            #Entier k : Nombre de valeurs prises
    l = len(T)                               #de chaque côté des éléments de T         
    L = np.zeros(l)

    if ((2*k+1)>l):
        return L

    else :
        for i in range(l):
            if ((i-k)<0):                           #Soit k < i
                m = i
                L[i] = np.mean( T[(i-m):(i+m+1)] )  #i-m = 0

            elif ((i+k)>(l-1)):                     #Soit k > l-1-i
                m = l-1-i
                L[i] = np.mean( T[(i-m):(i+m+1)] )  #i+m+1 = l

            else :
                L[i] = np.mean( T[(i-k):(i+k+1)] )

        return L









                    # Données : Reelles (Modifier selon besoin)



# CodePays = Identifiant du pays que l'on veut étudier, sous la forme "CODE"
CodePays = "AUS"


# On définit un jour du début des observations.

# Pour commencer à une date précise, on la définit. Sinon on laisse 0, 0, 0.
# Exemple : pour le 13 Mars 2020, on remplace 0, 0, 0 par 13, 3, 2020
DateDeb = 0, 0, 0

# Pour commencer à un certain nombre de morts / infectés, on les définit.
# Il faudra par ailleurs remettre DateDeb à 0, 0, 0 pour que cela marche.
NbIDeb = 1
NbMDeb = 1000


# On définit la plage k utilisée pour lisser les données réelles
kI = 2
kM = 2


#On définit la période p : durée de chaque phase (tq beta fixe) pour la simulation (jours)
p = 6



# Ne pas modifier les commandes ci-dessous : dépendent de celles au dessus

data = pd.read_excel("https://www.ecdc.europa.eu/sites/default/files/documents/COVID-19-geographic-disbtribution-worldwide.xlsx")
data = data[data["countryterritoryCode"] == CodePays]
data = (np.array(data))[::-1]

i = 0
if (DateDeb == (0, 0, 0)):
    while (data[i][4]<NbIDeb):
        i = i+1
else :
    while ((data[i][1], data[i][2], data[i][3]) != (DateDeb)):
        i = i+1

data = data[i:,:]

IpJreel = data[:,4]
IpJliss = MoyMob(IpJreel, kI)

MpJreel = data[:,5]
MpJliss = MoyMob(MpJreel, kM)

LJours = data[:, 0]
n = len(LJours)







fig = plt.figure(facecolor='w', figsize=(10,8), dpi=80)
plt.suptitle('Nombre de morts lissés du Covid-19 en Australie',fontsize=18, color="red")
plt.subplot(221)
plt.tick_params(axis = 'both', labelsize = 8)
plt.xticks(rotation = 'vertical')
plt.plot(LJours, MpJreel, 'blue', alpha=0.5, lw=2, label='Morts réels' )
plt.plot(LJours, MpJliss, 'black', alpha=0.5, lw=2, label='Morts lissés' )
#plt.axvline(x="2020-03-09",color='purple',linestyle='--', label = 'Confinement')
#plt.axvline(x="2020-05-04",color='purple',linestyle='--')
plt.xlabel('Temps (jours)')
plt.ylabel('Nombre (individus)')
plt.grid(b=True, which='major', c='w', lw=2, ls='-')
legend = plt.legend()
legend.get_frame().set_alpha(0.5)

plt.subplot(222)
plt.tick_params(axis = 'both', labelsize = 8)
plt.xticks(rotation = 'vertical')
plt.plot(LJours, MpJliss, 'black', alpha=0.5, lw=2, label='Morts lissés' )
#plt.plot(LJours, MpJtheo, 'green', alpha=0.5, lw=2, label='Morts théoriques')
#plt.axvline(x="2020-03-09",color='purple',linestyle='--', label = 'Confinement')
#plt.axvline(x="2020-05-04",color='purple',linestyle='--')
plt.xlabel('Temps (jours)')
plt.ylabel('Nombre (individus)')
plt.grid(b=True, which='major', c='w', lw=2, ls='-')
legend = plt.legend()
legend.get_frame().set_alpha(0.5)
plt.show()

Remarque: Le premier cas confirmé Covid-19 est apparu le 25 janvier 2020. Un homme revenant d’un voyage à Wuhan une semaine plus tôt. Le premier décès est survenu un peu plus d’un mois plus tard (le 1ᵉʳ mars), un homme de 78 ans, passager du Diamond Princess À ce jour, la propagation du virus semble marquer le pas avec 97 décès et seulement deux décès supplémentaires sur la semaine du 3/05 au 10/05.

En comparaison avec la France, 36,7 morts pour 100 000 habitants, l’Australie ne compte que 0,4 mort pour 100 000 habitants.

Modèle

Choix du modèle

Pour mieux comprendre l'évolution de l'épidémie du coronavirus en Australie, nous avons décidé d'utiliser le modèle SEIRD (Susceptibles, Exposés, Infectés, Rétablis, Décèdes) . car ce modèle est un des modèles de base des modélisations épidémiques. Il prend plus de paramètres donc est plus précis que le modèle SIR.

Repésentation mathématique à l'aide d'équations différentielles du modele
Ce modèle des épidémies consiste à partitionner la population (N) d'étude en 5 compartiments: N = Population totale étudiée D = Nombre de décédés R = Nombre de rétablis I = Nombre d'infectés E = Nombre d'exposés = infectés non infectieux / contaminés non contaminants (en général S = Nombre de sains / susceptibles d'êtres infectés (le reste de la population) L'effectif de chacune de ces populations est evidemment variable dans le temps à mesure que le virus progresse dans la population. On peut donc la modéliser avec de ce fait par une fonction de la variable temps t: S(t), I(t) ... S(t) = N(t) - E(t) - I(t) - R(t) - D(t) Pour modéliser la dynamique de l'épidémie, nous avons eu besoin d'établir des équations différentielles visible sur la chaine de code suivante.
Hypothèses et Procédure
HYPOTHESES: -> La taille de la population est fixe au cours de l'épidémie(N= constante); -> Les individus guéris sont immunisés et donc ne pourront plus contracter la maladie; -> dincub = Durée d'incubation : Temps avant d'être contaminant une fois contaminé (jours) dincub = 3 -> dret = Durée de rétablissement : Temps que l'on reste contaminant (jours) dret = 17 -> m = Taux de mortalité parmis les infectés en % m = 1 (ce faible taux s'explique car seulement 13% de la population algérienne a plus de 65 ans et cette tranche de la population est la plus impactée par l'épidémie) PROCEDURE: -> L'ajustement, par le modele, est basé sur la minimisation des écarts entre les valeurs observées réelles et et les valeurs prédites. En essayant de jouer sur les paramètres, on essaye de s'approcher au maximum de la courbe réelle.
Estimation du beta (beta = Taux de transmission à chaque contact (ne pas confondre avec R0))
On va définir la modélisation en plusieurs phases : Cela permet de faire varier beta, c'est à dire en quelque sorte la vitesse de propagation. En effet, beta = Taux de transmission à chaque contact (jours^(-1)) C'est la probabilité pour un S de passer à E après un contact avec un I Ainsi chaque phase dure un nombre de jours 'ni' avec un beta appelé 'betai' Ce paramètre nous permet de diviser l'évolution de l'épidemie en plusieurs phases et par ailleurs de voir si le confinement a un effet sur l'épidémie ou non.
In [26]:
from IPython.display import HTML
HTML('''<script>
code_show=true; 
function code_toggle() {
 if (code_show){
 $('div.input').hide();
 } else {
 $('div.input').show();
 }
 code_show = !code_show
} 
$( document ).ready(code_toggle);
</script>
Le code python est caché par défault.
Pour l'activer ou le désactiver cliquez <a href="javascript:code_toggle()">ici</a>.''')
Out[26]:
Le code python est caché par défault. Pour l'activer ou le désactiver cliquez ici.
In [24]:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy.integrate import odeint
from scipy.optimize import least_squares
import time
import datetime as dt

                    # Fonctions (Ne pas modifier)

def DerivSEIRD(y0, t, N, beta, sigma, gamma, mu):
    S, E, I, R, D = y0
    dSdt = -(beta/N)*I*S
    dEdt = (beta/N)*I*S - sigma*E
    dIdt = sigma*E - gamma*I - mu*I
    dRdt = gamma*I
    dDdt = mu*I
    return dSdt, dEdt, dIdt, dRdt, dDdt


def SEIRD(y0, n, N, beta, sigma, gamma, mu):
    t = np.linspace(1, n, n)
    sol = odeint(DerivSEIRD, y0, t, args=(N, beta, sigma, gamma, mu))
    return sol.T


def SEIRD_phases(y0, Tn, N, Tbeta, sigma, gamma, mu):
    n = 0
    y = y0

    n0, beta0 = Tn[0], Tbeta[0]
    S, E, I, R, D = SEIRD(y, n0, N, beta0, sigma, gamma, mu)
    n = n+n0
    y = S[n-1], E[n-1], I[n-1], R[n-1], D[n-1]
    t = np.linspace(1, n, n)

    for i in range (1, len(Tn)):
        ni, betai = Tn[i], Tbeta[i]
        Si, Ei, Ii, Ri, Di = SEIRD(y, ni+1, N, betai, sigma, gamma, mu)[:,1:]
        S, E, I, R, D = np.concatenate((S,Si)), np.concatenate((E,Ei)), np.concatenate((I,Ii)), np.concatenate((R,Ri)), np.concatenate((D,Di))
        n = n+ni
        y = S[n-1], E[n-1], I[n-1], R[n-1], D[n-1]

    return S, E, I, R, D, t



def MoyMob(T, k):                            #Entier k : Nombre de valeurs prises
    l = len(T)                               #de chaque côté des éléments de T         
    L = np.zeros(l)

    if ((2*k+1)>l):
        return L

    else :
        for i in range(l):
            if ((i-k)<0):                           #Soit k < i
                m = i
                L[i] = np.mean( T[(i-m):(i+m+1)] )  #i-m = 0

            elif ((i+k)>(l-1)):                     #Soit k > l-1-i
                m = l-1-i
                L[i] = np.mean( T[(i-m):(i+m+1)] )  #i+m+1 = l

            else :
                L[i] = np.mean( T[(i-k):(i+k+1)] )

        return L



def Periode(n, p):
    q, r = n//p, n%p
    Tnp = [p]*q
    if (r!=0):
        Tnp.append(r)
    return Tnp




                    # Données : Epidémie



# dincub = Durée d'incubation : Temps avant d'être contaminant une fois contaminé (jours)
dincub = 3

# dret = Durée de rétablissement : Temps que l'on reste contaminant (jours)
dret = 17

# m = Taux de mortalité parmis les infectés en %
m = 2


# Pas besoin de modifier celles-ci car elles dépendent des précédentes

# sigma = Inverse de la durée d'incubation (jours^(-1)) : Taux d'invidus qui passe de E à I par jour
sigma = 1/dincub

# gamma = Inverse de la durée de rétablissement (jour^(-1)) : Taux d'individus qui passe de I à R par jour
gamma = 1/dret

# mu = Taux de mortalité journalier parmis les infectés (jours^(-1)) : Taux d'individus qui passe de I à D par jour
mu = (m/100)*gamma





                    # Données : Reelles (Modifier selon besoin)



# CodePays = Identifiant du pays que l'on veut étudier, sous la forme "CODE"
CodePays = "AUS"


# On définit un jour du début des observations.

# Pour commencer à une date précise, on la définit. Sinon on laisse 0, 0, 0.
# Exemple : pour le 13 Mars 2020, on remplace 0, 0, 0 par 13, 3, 2020
DateDeb = 0, 0, 0

# Pour commencer à un certain nombre de morts / infectés, on les définit.
# Il faudra par ailleurs remettre DateDeb à 0, 0, 0 pour que cela marche.
NbIDeb = 1
NbMDeb = 1000


# On définit la plage k utilisée pour lisser les données réelles
kI = 2
kM = 2


#On définit la période p : durée de chaque phase (tq beta fixe) pour la simulation (jours)
p = 6



# Ne pas modifier les commandes ci-dessous : dépendent de celles au dessus

data = pd.read_excel("https://www.ecdc.europa.eu/sites/default/files/documents/COVID-19-geographic-disbtribution-worldwide.xlsx")
data = data[data["countryterritoryCode"] == CodePays]
data = (np.array(data))[::-1]

i = 0
if (DateDeb == (0, 0, 0)):
    while (data[i][4]<NbIDeb):
        i = i+1
else :
    while ((data[i][1], data[i][2], data[i][3]) != (DateDeb)):
        i = i+1

data = data[i:,:]

IpJreel = data[:,4]
IpJliss = MoyMob(IpJreel, kI)

MpJreel = data[:,5]
MpJliss = MoyMob(MpJreel, kM)

LJours = data[:, 0]
n = len(LJours)

                    # Données : Population

# N = Population totale étudiée
N = data[0,9]

# D0 = Nombre initial de décédés
D0 = data[0,5]

# R0 = Nombre initial de rétablis
R0 = 0

# I0 = Nombre initial d'infectés
I0 = data[0,4]

# E0 = Nombre initial d'exposés = infectés non infectieux / contaminés non contaminants (en général 0)
E0 = 0

# S0 = Nombre initial de sains / susceptibles d'êtres infectés (le reste de la population)
S0 = N - E0 - I0 - R0 - D0

# y0 = Vecteur comportant ces données initiales
y0 = S0, E0, I0, R0, D0


            # Simulation et Graphes

def Reste(Tbeta):
    S, E, I, R, D, t = SEIRD_phases(y0, Tn, N, Tbeta, sigma, gamma, mu)
    MpJtheo = I*mu
    Res = MpJtheo - MpJliss
    return np.linalg.norm(Res, 2)


Tn = Periode(n, p)
Tbetai = [1]*len(Tn)

Tbeta = least_squares(Reste, Tbetai, bounds=(0, 1)).x

S, E, I, R, D, t = SEIRD_phases(y0, Tn, N, Tbeta, sigma, gamma, mu)

MpJtheo = I*mu

fig = plt.figure(facecolor='w', figsize=(8,6), dpi=80)
plt.plot(Tbeta, color="red", label = 'Beta mis à jour tous les 6 jours')
axes = plt.gca()
axes.xaxis.set_ticks(range(n))
axes.xaxis.set_ticklabels(['2020-03-01', '2020-03-07', '2020-03-13', '2020-03-19', '2020-03-25','2020-03-31', '2020-04-06', '2020-04-12', '2020-04-18', '2020-04-24','2020-04-30','2020-05-06', '2020-05-12', '2020-05-18', '2020-05-24','2020-05-30','2020-06-05','2020-06-11','2020-06-17','2020-06-23','2020-06-29','2020-07-05','2020-07-11','2020-07-17','2020-07-23','2020-07-29'], rotation = 90, color = 'black', fontsize = 8)
u = [6.33,6.33]
v = [0,1]
#plt.plot(u, v, '--', color = "purple", lw = 1, label='Confinement')
a = [15.5,15.5]
b = [0,1]
plt.plot(a, b, '--', color = "purple", lw = 1)
plt.xlabel('Temps (/6jours)')
plt.ylabel('Beta')
legend = plt.legend()
plt.title("Evolution du Beta en fonction du temps",fontsize=18, color = "red")
plt.show()
Le gouvernement australien n'ayant pas adopté de mesures de confinement, l'instabilité de Beta se comprend donc bien. Beta n'est donc pas le meilleur paramètre sur lequel concentrer notre étude.

Résultats

Estimation du nombre de décès par jour
In [20]:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy.integrate import odeint
from scipy.optimize import least_squares
import time
import datetime as dt

                    # Fonctions (Ne pas modifier)

def DerivSEIRD(y0, t, N, beta, sigma, gamma, mu):
    S, E, I, R, D = y0
    dSdt = -(beta/N)*I*S
    dEdt = (beta/N)*I*S - sigma*E
    dIdt = sigma*E - gamma*I - mu*I
    dRdt = gamma*I
    dDdt = mu*I
    return dSdt, dEdt, dIdt, dRdt, dDdt


def SEIRD(y0, n, N, beta, sigma, gamma, mu):
    t = np.linspace(1, n, n)
    sol = odeint(DerivSEIRD, y0, t, args=(N, beta, sigma, gamma, mu))
    return sol.T


def SEIRD_phases(y0, Tn, N, Tbeta, sigma, gamma, mu):
    n = 0
    y = y0

    n0, beta0 = Tn[0], Tbeta[0]
    S, E, I, R, D = SEIRD(y, n0, N, beta0, sigma, gamma, mu)
    n = n+n0
    y = S[n-1], E[n-1], I[n-1], R[n-1], D[n-1]
    t = np.linspace(1, n, n)

    for i in range (1, len(Tn)):
        ni, betai = Tn[i], Tbeta[i]
        Si, Ei, Ii, Ri, Di = SEIRD(y, ni+1, N, betai, sigma, gamma, mu)[:,1:]
        S, E, I, R, D = np.concatenate((S,Si)), np.concatenate((E,Ei)), np.concatenate((I,Ii)), np.concatenate((R,Ri)), np.concatenate((D,Di))
        n = n+ni
        y = S[n-1], E[n-1], I[n-1], R[n-1], D[n-1]

    return S, E, I, R, D, t



def MoyMob(T, k):                            #Entier k : Nombre de valeurs prises
    l = len(T)                               #de chaque côté des éléments de T         
    L = np.zeros(l)

    if ((2*k+1)>l):
        return L

    else :
        for i in range(l):
            if ((i-k)<0):                           #Soit k < i
                m = i
                L[i] = np.mean( T[(i-m):(i+m+1)] )  #i-m = 0

            elif ((i+k)>(l-1)):                     #Soit k > l-1-i
                m = l-1-i
                L[i] = np.mean( T[(i-m):(i+m+1)] )  #i+m+1 = l

            else :
                L[i] = np.mean( T[(i-k):(i+k+1)] )

        return L



def Periode(n, p):
    q, r = n//p, n%p
    Tnp = [p]*q
    if (r!=0):
        Tnp.append(r)
    return Tnp




                    # Données : Epidémie



# dincub = Durée d'incubation : Temps avant d'être contaminant une fois contaminé (jours)
dincub = 3

# dret = Durée de rétablissement : Temps que l'on reste contaminant (jours)
dret = 17

# m = Taux de mortalité parmis les infectés en %
m = 1


# Pas besoin de modifier celles-ci car elles dépendent des précédentes

# sigma = Inverse de la durée d'incubation (jours^(-1)) : Taux d'invidus qui passe de E à I par jour
sigma = 1/dincub

# gamma = Inverse de la durée de rétablissement (jour^(-1)) : Taux d'individus qui passe de I à R par jour
gamma = 1/dret

# mu = Taux de mortalité journalier parmis les infectés (jours^(-1)) : Taux d'individus qui passe de I à D par jour
mu = (m/100)*gamma





                    # Données : Reelles (Modifier selon besoin)



# CodePays = Identifiant du pays que l'on veut étudier, sous la forme "CODE"
CodePays = "AUS"


# On définit un jour du début des observations.

# Pour commencer à une date précise, on la définit. Sinon on laisse 0, 0, 0.
# Exemple : pour le 13 Mars 2020, on remplace 0, 0, 0 par 13, 3, 2020
DateDeb = 1, 3, 2020

# Pour commencer à un certain nombre de morts / infectés, on les définit.
# Il faudra par ailleurs remettre DateDeb à 0, 0, 0 pour que cela marche.
NbIDeb = 1
NbMDeb = 1000


# On définit la plage k utilisée pour lisser les données réelles
kI = 2
kM = 2


#On définit la période p : durée de chaque phase (tq beta fixe) pour la simulation (jours)
p = 6



# Ne pas modifier les commandes ci-dessous : dépendent de celles au dessus

data = pd.read_excel("https://www.ecdc.europa.eu/sites/default/files/documents/COVID-19-geographic-disbtribution-worldwide.xlsx")
data = data[data["countryterritoryCode"] == CodePays]
data = (np.array(data))[::-1]

i = 0
if (DateDeb == (0, 0, 0)):
    while (data[i][4]<NbIDeb):
        i = i+1
else :
    while ((data[i][1], data[i][2], data[i][3]) != (DateDeb)):
        i = i+1

data = data[i:,:]

IpJreel = data[:,4]
IpJliss = MoyMob(IpJreel, kI)

MpJreel = data[:,5]
MpJliss = MoyMob(MpJreel, kM)

LJours = data[:, 0]
n = len(LJours)

                    # Données : Population

# N = Population totale étudiée
N = data[0,9]

# D0 = Nombre initial de décédés
D0 = data[0,5]

# R0 = Nombre initial de rétablis
R0 = 0

# I0 = Nombre initial d'infectés
I0 = data[0,4]

# E0 = Nombre initial d'exposés = infectés non infectieux / contaminés non contaminants (en général 0)
E0 = 0

# S0 = Nombre initial de sains / susceptibles d'êtres infectés (le reste de la population)
S0 = N - E0 - I0 - R0 - D0

# y0 = Vecteur comportant ces données initiales
y0 = S0, E0, I0, R0, D0


            # Simulation et Graphes

def Reste(Tbeta):
    S, E, I, R, D, t = SEIRD_phases(y0, Tn, N, Tbeta, sigma, gamma, mu)
    MpJtheo = I*mu
    Res = MpJtheo - MpJliss
    return np.linalg.norm(Res, 2)


Tn = Periode(n, p)
Tbetai = [1]*len(Tn)

Tbeta = least_squares(Reste, Tbetai, bounds=(0, 1)).x

S, E, I, R, D, t = SEIRD_phases(y0, Tn, N, Tbeta, sigma, gamma, mu)

MpJtheo = I*mu

fig = plt.figure(facecolor='w', figsize=(22,20), dpi=80)
plt.subplot(222)
plt.tick_params(axis = 'both', labelsize = 18)
plt.xticks(rotation = 'vertical')
plt.plot(LJours, MpJliss, 'black', alpha=0.5, lw=2, label='Morts lissés' )
plt.plot(LJours, MpJtheo, 'green', alpha=0.5, lw=2, label='Morts théoriques')

plt.xlabel('Temps (jours)')
plt.ylabel('Nombre (individus)')
plt.grid(b=True, which='major', c='w', lw=2, ls='-')
legend = plt.legend()
legend.get_frame().set_alpha(0.5)
plt.show()
Notre modèle s'approche donc bien de la courbe réelle lissée avec les parametres estimés.
Prédictions
Notre étude nous permet de dire que le pic des décès est déjà atteint en Australie à la date du 07/04/2020 . Nous prédisons que l'évolution des décès est ammenée à s'atténuer et à tendre vers 0 à partir du 1er juin. Ayant tous les paramètres nécessaires et optimés, nous pouvons ainsi tracer le modèle SEIRD.

Modèle SEIRD

In [22]:
t = LJours

fig = plt.figure(facecolor='w', figsize=(10,14), dpi=80)
plt.suptitle("Représentation du modèle SEIRD de l'Australie",fontsize=18, color="red")
plt.subplot(211)
plt.xticks(rotation = 50)
plt.tick_params(axis = 'both', labelsize = 8)
plt.plot(t, S, 'b', alpha=0.5, lw=2, label='Susceptibles')
plt.plot(t, E, 'g', alpha=0.5, lw=2, label='Exposés')
plt.plot(t, I, 'r', alpha=0.5, lw=2, label='Infectés')
plt.plot(t, R, 'y', alpha=0.5, lw=2, label='Rétablis avec immunité')
plt.plot(t, D, 'black', alpha=0.5, lw=2, label='Morts')
plt.axvline(x="2020-05-04",color='purple', linestyle='--')
plt.xlabel('Temps /Jours')
plt.ylabel('Population')
plt.grid(b=True, which='major', c='w', lw=2, ls='-')
legend = plt.legend()
legend.get_frame().set_alpha(0.5)

plt.subplot(212)
plt.xticks(rotation = 50)
plt.tick_params(axis = 'both', labelsize = 8)
plt.plot(t, E, 'g', alpha=0.5, lw=2, label='Exposés')
plt.plot(t, I, 'r', alpha=0.5, lw=2, label='Infectés')
plt.plot(t, R, 'y', alpha=0.5, lw=2, label='Rétablis avec immunité')
plt.plot(t, D, 'black', alpha=0.5, lw=2, label='Morts')
plt.axvline(x="2020-05-04",color='purple', linestyle='--')
plt.xlabel('Temps /Jours')
plt.ylabel('Population')
plt.grid(b=True, which='major', c='w', lw=2, ls='-')
legend = plt.legend()
legend.get_frame().set_alpha(0.5)

plt.show()
En australie, j'estime que le pic de l'épidémie est atteint autour de la date du 05-04-2020, meme si j'emets quelques réserves. Cette méthode d'estimation étant très sensible.

Conclusion

Avec l'observation de ces estimations, nous pouvons conclure que le pic de l'épidémie en australie serait déjà atteint à la date du 05-04-2020. Nous avons pu voir que sans confinement, comme comparée à la france, l'australie n'a pas été vraiment impactée par la pandémie. Les raisons sont peut etre à chercher sur la faible densité de sa population, oubien sur son aspect géograpique et climatographique. La question à se poser semble etre doit on redouter une deuxième vague ? les individus seront les acteurs de la réussite d'une non-nouvelle vague en espérant que la société aura pris grande conscience et tiré leçon de cette épidémie. Pour aller plus loin, on pourrait étudier la relation entre le nombre de contaminés et le nombre de décès afin d'obtenir une meilleure estimation de la proportion de la population infectée. On pourrait aussi estimer ces courbes de façon plus locale afin d'etre encore plus précis.
                                      "Science sans consience est égale à science de l'inconscience"
                                                                    Etude réalisée par SALL Serigne cheikhouna