<jupyter_start><jupyter_text>___ Simulación de escenarios de desescalada con el modelo SIR-D___En este notebook se realiza una simulación de desescalada por edades utilizando el modelo SIR-D para epidemias.  Importo librerías:<jupyter_code>from funcs import *
# Semilla aleatoria
np.random.seed(2019)
# Pandas
pd.set_option("display.max_colwidth", 1000)
# Matplotlib
plt.style.use("seaborn-ticks")
plt.rcParams["xtick.direction"] = "in"
plt.rcParams["ytick.direction"] = "in"
plt.rcParams["font.size"] = 11.0
plt.rcParams["figure.figsize"] = (12, 6)<jupyter_output><empty_output><jupyter_text>Concepto teórico: Modelo SIR-DDebido a que estamos midiendo el número de casos fatales y de casos recuperados por separado, podemos utilizar dos variables ("Recuperados" y "Muertes") en lugar de "Recuperados + Muertes" en el modelo matemático.   ¿Qué es el modelo SIR-D?* S: Susceptible* I: Infectado* R: Recuperado* D: MuertesModelo:  \begin{align*}\mathrm{S} \overset{\beta  I}{\longrightarrow}\ & \mathrm{I} \overset{\gamma}{\longrightarrow} \mathrm{R}  \\& \mathrm{I} \overset{\alpha}{\longrightarrow} \mathrm{D}  \\\end{align*}$\alpha$: Tasa de mortalidad [1/min]  $\beta$: Tasa de contacto efectiva [1/min]  $\gamma$: Tasa de recuperación [1/min]  Ecuación diferencial ordinaria:\begin{align*}& \frac{\mathrm{d}S}{\mathrm{d}T}= - N^{-1}\beta S I  \\& \frac{\mathrm{d}I}{\mathrm{d}T}= N^{-1}\beta S I - (\gamma + \alpha) I  \\& \frac{\mathrm{d}R}{\mathrm{d}T}= \gamma I  \\& \frac{\mathrm{d}D}{\mathrm{d}T}= \alpha I  \\\end{align*}Donde $N=S+I+R+D$ es la población total, $T$ es el tiempo transcurrido desde la fecha de inicio.  Modelo SIR-D no dimensional Set $(S, I, R, D) = N \times (x, y, z, w)$ and $(T, \alpha, \beta, \gamma) = (\tau t, \tau^{-1} \kappa, \tau^{-1} \rho, \tau^{-1} \sigma)$.  Esto resulta en que las ecuaciones diferenciales son:  \begin{align*}& \frac{\mathrm{d}x}{\mathrm{d}t}= - \rho x y  \\& \frac{\mathrm{d}y}{\mathrm{d}t}= \rho x y - (\sigma + \kappa) y  \\& \frac{\mathrm{d}z}{\mathrm{d}t}= \sigma y  \\& \frac{\mathrm{d}w}{\mathrm{d}t}= \kappa y  \\\end{align*}Donde $N$ es la población total y $\tau$ es un coeficiente ([min], es un entero para simplificar).  El rango de variables y parámetros:  \begin{align*}& 0 \leq (x, y, z, w, \kappa, \rho, \sigma) \leq 1  \\\end{align*}\begin{align*}& 1\leq \tau \leq 1440  \\\end{align*}El número de reproducción puede definirse como  \begin{align*}R_0 = \rho (\sigma + \kappa)^{-1} = \beta (\gamma + \alpha)^{-1}\end{align*}Valores medios estimados de $R_0$:  $R_0$ ("R nada") significa "el número medio de infecciones secundarias causadas por un huésped infectado".  2.06: Zika en América del Sur, 2015-2016  1,51: Ebola en Guinea, 2014  1,33: Gripe H1N1 en Sudáfrica, 2009  3.5 : El SRAS en 2002-2003  1,68: Gripe H2N2 en EE.UU., 1957  3.8 : Ola de otoño de la gripe española de 1918 en Génova  1.5 : Ola de primavera de 1918 de la gripe española en Génova   Primero de todo descargo la pirámide poblacional de España, para saber cuantas personas hay de cada edad en el país. El virus ataca más en edades avanzadas. Los datos de la pirámide poblacional se han obtenido de https://www.populationpyramid.net/es/espa%C3%B1a/2019/.Por otro lado, también se ha hecho uso de la tasa de mortalidad por edades obtenido de https://coronavirus-resumen.herokuapp.com/.<jupyter_code>edades = pd.read_csv('./data/piramide_2019.csv') 
poblacion_total = edades['Hombres'].sum() + edades['Mujeres'].sum()
edades[:3]
print(u'La población total en España es de {} personas'.format(poblacion_total))<jupyter_output>La población total en España es de 46736782 personas<jupyter_text>___ 1.- Desescalada con apertura total:___ Por ejemplo, establece $R_0 = 2.5, \kappa=0.005, \rho=0.2$ y los valores iniciales $(x_{(0)}, y_{(0)}, z_{(0)}, w_{(0)}) = (0.999, 0.001, 0, 0)$.<jupyter_code>#(numero reproductivo, tasa mortalidad * tau, tasa efectiva contagio * tau)
r0, kappa, rho = (2.5, 0.005, 0.2) 
sigma = rho / r0 - kappa
# (susceptibles, infectados, recuperados, fallecidos)
initials = (0.999, 0.001, 0, 0) 
display(Markdown(rf"$\kappa = {kappa},\ \rho = {rho},\ \sigma = {sigma}$."))<jupyter_output><empty_output><jupyter_text>Suponemos que el día inicial es el 5 de Mayo de 2020. $\tau=1440$ minutos y abrimos al total de la población $N=46.736.782$.<jupyter_code>tau = 1440
dia_inicial = datetime.datetime(2020, 5, 5)
poblacion = poblacion_total
%%time
df = simulation(SIRD, initials, step_n=200, kappa=kappa, rho=rho, sigma=sigma)
df.tail()
ori_df = pd.DataFrame(
    {
        "Date": (df["t"] * tau).apply(lambda x: timedelta(minutes=x)) + dia_inicial,
        "Group": "Stopping",
        "País": "España",
        "Province": "-",
        "Susceptible": 0,
        "Confirmed": 0,
        "Infected": (df["y"] * poblacion).astype(np.int64)
    }
)
ori_df["Recovered"] = (df["z"] * poblacion).astype(np.int64)
ori_df["Deaths"] = (df["w"] * poblacion).astype(np.int64)
ori_df["Confirmed"] = ori_df[["Infected", "Recovered", "Deaths"]].sum(axis=1)
ori_df["Susceptible"] = poblacion - ori_df["Confirmed"]
ori_df.tail()
line_plot(
    ori_df.set_index("Date")[["Susceptible", "Infected", "Recovered", "Deaths"]],
    "Modelo SIR-D desconfinando a todos",
    h=poblacion,
    y_integer=True
)
print(u'El número total de fallecimientos es de: {}'.format(ori_df['Deaths'].max()))
print(u'Fallece un {} % de la población'.format(np.round((ori_df['Deaths'].max()/poblacion)*100,2)))<jupyter_output><empty_output><jupyter_text>2.- Desescalada por edades___  2.1.- Apertura a < 50 años:___<jupyter_code>poblacion_menor_50 = edades.loc[edades['Tasa mortalidad']<=0.5][['Hombres', 'Mujeres']].sum().sum()
poblacion_menor_50<jupyter_output><empty_output><jupyter_text>Establecemos $R_0 = 2.5, \kappa=0.0004, \rho=0.2$ y los valores iniciales $(x_{(0)}, y_{(0)}, z_{(0)}, w_{(0)}) = (0.999, 0.001, 0, 0)$.<jupyter_code>#(numero reproductivo, tasa mortalidad * tau, tasa efectiva contagio * tau)
r0, kappa, rho = (2.5, 0.0004, 0.2)
sigma = rho / r0 - kappa
# (susceptibles, infectados, recuperados, fallecidos)
initials = (0.999, 0.001, 0, 0) 
display(Markdown(rf"$\kappa = {kappa},\ \rho = {rho},\ \sigma = {sigma}$."))<jupyter_output><empty_output><jupyter_text>Suponemos que el día inicial es el 5 de Mayo de 2020. $\tau=1440$ minutos y abrimos a la población de menos de 50 años.<jupyter_code>tau = 1440
dia_inicial = datetime.datetime(2020, 5, 5)
poblacion = poblacion_menor_50
%%time
df = simulation(SIRD, initials, step_n=90, kappa=kappa, rho=rho, sigma=sigma)
df.tail()
ori_df = pd.DataFrame(
    {
        "Date": (df["t"] * tau).apply(lambda x: timedelta(minutes=x)) + dia_inicial,
        "Group": "Stopping",
        "País": "España",
        "Province": "-",
        "Susceptible": 0,
        "Confirmed": 0,
        "Infected": (df["y"] * poblacion).astype(np.int64)
    }
)
ori_df["Recovered"] = (df["z"] * poblacion).astype(np.int64)
ori_df["Deaths"] = (df["w"] * poblacion).astype(np.int64)
ori_df["Confirmed"] = ori_df[["Infected", "Recovered", "Deaths"]].sum(axis=1)
ori_df["Susceptible"] = poblacion - ori_df["Confirmed"]
ori_df.tail()
line_plot(
    ori_df.set_index("Date")[["Susceptible", "Infected", "Recovered", "Deaths"]],
    "Modelo SIR-D desconfinando por edades  -- fase 2, apertura < 50 años",
    h=poblacion,
    y_integer=True
)
print(u'El número total de fallecimientos es de: {}'.format(ori_df['Deaths'].max()))
print(u'Fallece un {} % de la población'.format(np.round((ori_df['Deaths'].max()/poblacion)*100,2)))<jupyter_output><empty_output><jupyter_text>2.2.- Apertura a >= 50 y <70 años:___<jupyter_code>poblacion_mayor_50_menor_70 = edades.loc[(edades['Tasa mortalidad']>1) &
                               (edades['Tasa mortalidad']<4)][['Hombres', 'Mujeres']].sum().sum()
poblacion_mayor_50_menor_70
condicion_inicial = ori_df.loc[ori_df['Date']==ori_df['Date'].max()]
condicion_inicial
susceptibles = poblacion_mayor_50_menor_70 + condicion_inicial['Susceptible'].values[0]
infectados = condicion_inicial['Infected'].values[0]
recuperados = condicion_inicial['Recovered'].values[0]
fallecidos = condicion_inicial['Deaths'].values[0]
ini_sus = susceptibles/(susceptibles+infectados+recuperados+fallecidos)
ini_inf = infectados/(susceptibles+infectados+recuperados+fallecidos)
ini_recup = recuperados/(susceptibles+infectados+recuperados+fallecidos)
ini_fall = fallecidos/(susceptibles+infectados+recuperados+fallecidos)
ini_sus, ini_inf, ini_recup, ini_fall<jupyter_output><empty_output><jupyter_text>Ahora aumentamos la tasa de mortalidad esperada, ya que el nuevo grupo es más mayor: $R_0 = 2.5, \kappa=0.003, \rho=0.2$.<jupyter_code>#(numero reproductivo, tasa mortalidad * tau, tasa efectiva contagio * tau)
r0, kappa, rho = (2.5, 0.003, 0.2) 
sigma = rho / r0 - kappa
 # (susceptibles, infectados, recuperados, fallecidos)
initials = (ini_sus, ini_inf, ini_recup, ini_fall)
display(Markdown(rf"$\kappa = {kappa},\ \rho = {rho},\ \sigma = {sigma}$."))<jupyter_output><empty_output><jupyter_text>Suponemos que el día inicial es el 3 de Agosto de 2020. $\tau=1440$ minutos y abrimos también a la población de entre 50 y 70 años.<jupyter_code>tau = 1440
dia_inicial = datetime.datetime(2020, 8, 3)
poblacion = susceptibles + infectados + recuperados + fallecidos
%%time
df = simulation(SIRD, initials, step_n=90, kappa=kappa, rho=rho, sigma=sigma)
df.tail()
ori_df = pd.DataFrame(
    {
        "Date": (df["t"] * tau).apply(lambda x: timedelta(minutes=x)) + dia_inicial,
        "Group": "Stopping",
        "País": "España",
        "Province": "-",
        "Susceptible": 0,
        "Confirmed": 0,
        "Infected": (df["y"] * poblacion).astype(np.int64)
    }
)
ori_df["Recovered"] = (df["z"] * poblacion).astype(np.int64)
ori_df["Deaths"] = (df["w"] * poblacion).astype(np.int64)
ori_df["Confirmed"] = ori_df[["Infected", "Recovered", "Deaths"]].sum(axis=1)
ori_df["Susceptible"] = poblacion - ori_df["Confirmed"]
ori_df.tail()
line_plot(
    ori_df.set_index("Date")[["Susceptible", "Infected", "Recovered", "Deaths"]],
    "Modelo SIR-D desconfinando por edades -- fase 2, apertura < 70 años",
    h=poblacion,
    y_integer=True
)
print(u'El número total de fallecimientos es de: {}'.format(ori_df['Deaths'].max()))
print(u'Fallece un {} % de la población'.format(np.round((ori_df['Deaths'].max()/poblacion)*100,2)))<jupyter_output><empty_output><jupyter_text>2.3.- Apertura a >= 70:___<jupyter_code>poblacion_mayor_70 = edades.loc[(edades['Tasa mortalidad']>4)][['Hombres', 'Mujeres']].sum().sum()
poblacion_mayor_70
condicion_inicial = ori_df.loc[ori_df['Date']==ori_df['Date'].max()]
condicion_inicial
susceptibles = poblacion_mayor_70 + condicion_inicial['Susceptible'].values[0]
infectados = condicion_inicial['Infected'].values[0]
recuperados = condicion_inicial['Recovered'].values[0]
fallecidos = condicion_inicial['Deaths'].values[0]
ini_sus = susceptibles/(susceptibles+infectados+recuperados+fallecidos)
ini_inf = infectados/(susceptibles+infectados+recuperados+fallecidos)
ini_recup = recuperados/(susceptibles+infectados+recuperados+fallecidos)
ini_fall = fallecidos/(susceptibles+infectados+recuperados+fallecidos)
ini_sus, ini_inf, ini_recup, ini_fall<jupyter_output><empty_output><jupyter_text>Volvemos a subir la tasa de mortalidad $R_0 = 2.5, \kappa=0.005, \rho=0.2$.<jupyter_code>r0, kappa, rho = (2.5, 0.005, 0.2) #(numero reproductivo, tasa mortalidad * tau, tasa efectiva contagio * tau)
sigma = rho / r0 - kappa
initials = (ini_sus, ini_inf, ini_recup, ini_fall) # (susceptibles, infectados, recuperados, fallecidos)
display(Markdown(rf"$\kappa = {kappa},\ \rho = {rho},\ \sigma = {sigma}$."))<jupyter_output><empty_output><jupyter_text>Suponemos que el día inicial es el 1 de Noviembre de 2020. $\tau=1440$ minutos y abrimos al total de la población.<jupyter_code>tau = 1440
dia_inicial = datetime.datetime(2020, 11, 1)
poblacion = susceptibles + infectados + recuperados + fallecidos
%%time
df = simulation(SIRD, initials, step_n=20, kappa=kappa, rho=rho, sigma=sigma)
df.tail()
ori_df = pd.DataFrame(
    {
        "Date": (df["t"] * tau).apply(lambda x: timedelta(minutes=x)) + dia_inicial,
        "Group": "Stopping",
        "País": "España",
        "Province": "-",
        "Susceptible": 0,
        "Confirmed": 0,
        "Infected": (df["y"] * poblacion).astype(np.int64)
    }
)
ori_df["Recovered"] = (df["z"] * poblacion).astype(np.int64)
ori_df["Deaths"] = (df["w"] * poblacion).astype(np.int64)
ori_df["Confirmed"] = ori_df[["Infected", "Recovered", "Deaths"]].sum(axis=1)
ori_df["Susceptible"] = poblacion - ori_df["Confirmed"]
ori_df.tail()
line_plot(
    ori_df.set_index("Date")[["Susceptible", "Infected", "Recovered", "Deaths"]],
    "Modelo SIR-D desconfinando por edades -- fase 3, apertura total",
    h=poblacion,
    y_integer=True
)
print(u'El número total de fallecimientos es de: {}'.format(ori_df['Deaths'].max()))
print(u'Fallece un {} % de la población'.format(np.round((ori_df['Deaths'].max()/poblacion)*100,2)))<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.17307692307692307, 'fraction_numerical': 0.03453846153846154, 'mean_word_length': 5.120998116760829, 'pattern_counts': {'":': 28, '<': 58, '<?xml version=': 0, '>': 56, 'https://': 2, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '13', 'dir': 'jupyter-structured-clean-dedup', 'id': '491485', 'license': 'MIT', 'n_tokens_mistral': 5466, 'n_tokens_neox': 5052, 'n_words': 1099, 'path': 'Escenarios_Covid19_Espania.ipynb', 'repo_name': 'traker1993/analisis_escenarios_covid19', 'size': '13000'}