import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import odeint
import ipywidgets as widgets
from ipywidgets import interact
import pandas as pd
import plotly.graph_objects as go
%matplotlib inlineParte I — Datos reales
def sir_model(y, t, beta, gamma):
S, I, R = y
N = S + I + R
dSdt = -beta * S * I / N
dIdt = beta * S * I / N - gamma * I
dRdt = gamma * I
return [dSdt, dIdt, dRdt]
def simulate_sir(beta=0.3, gamma=0.1, S0=990, I0=10, R0=0, days=160):
t = np.linspace(0, days, days)
y0 = [S0, I0, R0]
solution = odeint(sir_model, y0, t, args=(beta, gamma))
S, I, R = solution.T
return t, S, I, Rdef plot_sir_plotly(beta=0.3, gamma=0.1, S0=990, I0=10, R0=0, days=160):
t, S, I, R = simulate_sir(beta, gamma, S0, I0, R0, days)
fig = go.Figure()
fig.add_trace(go.Scatter(x=t, y=S, mode='lines', name='Susceptible'))
fig.add_trace(go.Scatter(x=t, y=I, mode='lines', name='Infected'))
fig.add_trace(go.Scatter(x=t, y=R, mode='lines', name='Recovered'))
fig.update_layout(
title=f"SIR Model (R₀ = {beta/gamma:.2f})",
xaxis_title="Time",
yaxis_title="Population",
template="plotly_white"
)
fig.show()Trabajamos con datos de casos en España.
Ejercicio 1
Carga los datos agregados y representa la evolución temporal.
Preguntas:
- ¿Qué forma tiene la curva?
- ¿Dónde está el pico?
Parte II — Modelo SIR
El modelo SIR describe la evolución de:
- S → susceptibles
- I → infectados
- R → recuperados
Ejercicio 2
Ejecuta el modelo SIR básico.
interact(
plot_sir_plotly,
beta=widgets.FloatSlider(value=0.3, min=0.0, max=1.0, step=0.01, description='beta'),
gamma=widgets.FloatSlider(value=0.1, min=0.01, max=1.0, step=0.01, description='gamma'),
S0=widgets.IntSlider(value=990, min=0, max=1000, step=10, description='S0'),
I0=widgets.IntSlider(value=10, min=1, max=500, step=1, description='I0'),
R0=widgets.IntSlider(value=0, min=0, max=500, step=1, description='R0'),
days=widgets.IntSlider(value=160, min=10, max=365, step=10, description='days')
);Ejercicio 3 — Ajuste de parámetros
Modifica:
- el tamaño de la población (S0+I0+R0)
- la condición inicial (I0)
- beta (tasa de infección)
- gamma (recuperación)
para aproximar la curva real.
Preguntas:
- ¿qué parámetro cambia el pico?
- ¿qué parámetro cambia la duración?
Hint
beta controla la velocidad de contagio
gamma controla la duración de la infección
covid_df = pd.read_parquet("data/processed/cnig_provincias_covid_cases.parquet")
pop_df = pd.read_parquet("data/processed/cnig_provincias_zone_movements.parquet")N = pop_df.loc['2020-02-14', 'total_population'].sum()
I_real = covid_df.groupby('date')['new_cases'].sum().rolling(window=10, min_periods=1).sum()
I_real = I_real.values[:180] * 20
plt.plot(I_real)
I_real.shapebeta=0.15
gamma=0.115
I0=500
S0=N - I0
R0=0
days=1800
t, S, I, R = simulate_sir(beta, gamma, S0, I0, R0, days)
figure = plt.figure(figsize=(6,3))
#plt.plot(t, S, label='S', color='purple')
plt.plot(t, I, label='I (sim)', color='firebrick')
plt.plot(I_real, '--', label='I (real)', color='purple')
#plt.plot(t, R, label='R', color='k')
plt.legend(frameon=False, loc='center right')
plt.xlabel("time")
plt.ylabel("compartment")
plt.show()Ejercicio 4 — Ajustar el modelo a los datos de España
Modifica:
- el tamaño de la población (S0+I0+R0)
- la condición inicial (I0)
- beta (tasa de infección)
- gamma (recuperación)
- Representar las curvas de infectados simuladas y reales apara diferente parametros
- Calcular alguna métrica de error entre las curvas de forma manual
Limitaciones del modelo SIR
El modelo SIR:
- asume población homogénea
- no incluye estructura espacial
- no incluye movilidad
Pregunta
¿Qué falta para modelar mejor una epidemia real?
Parte III — Movilidad
En la práctica anterior calculamos:
risk(i → j)
Esto sugiere:
- las regiones están conectadas
- los infectados viajan
- la epidemia se propaga entre regiones
necesitamos modelos espaciales
Instrucciones para instalar EpiCommute
- Abrimos la terminar y nos conectamos al servidor
- Entramos en la carpetta del curso (
cd mini-course-scicomp) - Activamos el venv
- Instalar EpiCommute:
- Descargamos Epicommute:
git clone https://github.com/franksh/EpiCommute.git - Acedemos a la carpeta del paquete:
cd EpiCommute - Instalamos el paquete en el venv:
python setupy.py install - Probamos que se instaló de forma correcta:
python -c "import EpiCommute" - Si no hay mensajes de erro es que fue todo OK!
- Descargamos Epicommute:
¿Que es EpiCommute?
Es un paquete en python que implemta un modelo simple de metapoblaciones y que fue usado en el sigueinte artículo: - COVID-19 lockdown induces disease-mitigating structural changes in mobility networks
Las idas orginales está desarrolladas en este otro artículo:
Ejercicio 1 — Simulación básica
Ejecuta el modelo básico.
Preguntas:
- ¿cómo evoluciona la epidemia?
- ¿qué regiones se infectan primero?
ejecutar 04_1_basic_example.ipynb
Ejercicio 2 — Efecto de la movilidad
Ejecuta la simulación:
- sin movilidad
- con movilidad
Preguntas:
- ¿qué cambia?
- ¿la epidemia se propaga más rápido?
ejecutar 2_lattice_mobility.ipynb
Ejercicio 3 — Efecto de la reducción de movilidad.
Simular los distintos tipos de cuarentenas y observar las diferencias
Preguntas:
- ¿se reduce el pico?
- ¿se retrasa la epidemia?