Random Stuff
The SEIR Model
where:
- — transmission probability per contact
- — rate of progression from exposed to infected, the E → I rate ()
- — recovery rate, the I → R rate ()
Sample Code that Implements the Model
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
def simulate_seir(
S0,
E0,
I0,
R0,
beta_mean,
beta_sd,
sigma,
gamma,
days,
stochastic_beta=True,
waning_immunity=False,
waning_interval=60,
waning_fraction=0.10,
seed=42,
):
"""Simulate a discrete-time SEIR model.
Parameters
----------
S0, E0, I0, R0 : float
Initial susceptible, exposed, infectious, and recovered counts.
beta_mean : float
Mean transmission probability/rate.
beta_sd : float
Standard deviation for stochastic beta.
sigma : float
Progression rate from exposed to infectious: 1/incubation period.
gamma : float
Recovery/removal rate: 1/infectious period.
days : int
Number of days to simulate.
stochastic_beta : bool
If True, draw beta_t ~ Normal(beta_mean, beta_sd) each day.
waning_immunity : bool
If True, move waning_fraction of R back to S every waning_interval days.
"""
rng = np.random.default_rng(seed)
N = S0 + E0 + I0 + R0
S = np.zeros(days + 1)
E = np.zeros(days + 1)
I = np.zeros(days + 1)
R = np.zeros(days + 1)
beta_values = np.zeros(days + 1)
S[0], E[0], I[0], R[0] = S0, E0, I0, R0
beta_values[0] = beta_mean
for t in range(days):
if stochastic_beta:
beta_t = rng.normal(beta_mean, beta_sd)
beta_t = max(beta_t, 0) # prevent biologically impossible negative transmission
else:
beta_t = beta_mean
beta_values[t + 1] = beta_t
new_exposed = beta_t * S[t] * I[t] / N
new_infectious = sigma * E[t]
new_recovered = gamma * I[t]
S[t + 1] = S[t] - new_exposed
E[t + 1] = E[t] + new_exposed - new_infectious
I[t + 1] = I[t] + new_infectious - new_recovered
R[t + 1] = R[t] + new_recovered
# Every 60 days, 10% of recovered individuals lose immunity and return to S.
# This is applied after disease-state transitions for that day.
if waning_immunity and (t + 1) % waning_interval == 0:
waned = waning_fraction * R[t + 1]
R[t + 1] -= waned
S[t + 1] += waned
return pd.DataFrame({
"day": np.arange(days + 1),
"S": S,
"E": E,
"I": I,
"R": R,
"beta": beta_values,
})
def summarize_epidemic(results, infection_threshold=1):
"""Return peak day, peak infectious count, and approximate epidemic duration."""
peak_idx = results["I"].idxmax()
peak_day = int(results.loc[peak_idx, "day"])
peak_infected = results.loc[peak_idx, "I"]
active = results[results["I"] >= infection_threshold]
if len(active) == 0:
duration = 0
else:
duration = int(active["day"].max() - active["day"].min() + 1)
return peak_day, peak_infected, duration
def plot_seir(results, title):
fig, ax = plt.subplots(figsize=(10, 6))
ax.plot(results["day"], results["S"], label="Susceptible")
ax.plot(results["day"], results["E"], label="Exposed")
ax.plot(results["day"], results["I"], label="Infectious")
ax.plot(results["day"], results["R"], label="Recovered/Removed")
ax.set_xlabel("Day")
ax.set_ylabel("Number of individuals")
ax.set_title(title)
ax.legend()
ax.spines["top"].set_visible(False)
ax.spines["right"].set_visible(False)
plt.tight_layout()
plt.show()
Other Notes
Modeling Vaccines
- Vaccines would reduce the number of susceptible people.
- You can change beta directly.
S → beta → E → gamma → I → lambda → R
If you are vaccinated you blast from S → R.
So,
- If R’s dont get boosted they go back to S.
- If they do, they stay in R.
Tracking Atomic statuses is hard!
“Endemic Equilibrium”
How would you eval if a vaccine intervention was effective?
Run the models, Plot Infectious curves.
Beta is constant, transmission is stable.
If transmission is volatile, if it swings, vaccines won’t be as effective. What do you do? When building a dam, don’t plan for average flow, plan for storm flow — this is how to think about vaccines.
SEER - Surveillance, Epidemiology, and End Results
SEER collects cancer incidence data from population-based cancer registries covering approximately 45.9 percent of the U.S. population. The SEER registries collect data on patient demographics, primary tumor site, tumor morphology, stage at diagnosis, and first course of treatment, and they follow up with patients for vital status.
Complete Case Analysis
Missingness Indicators
Might be better than imputation since you’re capturing the clinical signal?