Skip to content

SEIR Model Tutorial

milad edited this page May 10, 2026 · 2 revisions

Complete guide to understanding and using the SEIR (Susceptible-Exposed-Infected-Recovered) epidemic model.


πŸ“‹ Table of Contents


🧠 What is the SEIR Model?

The SEIR model extends the classic SIR model by adding an Exposed compartment for individuals who have been infected but are not yet infectious.

Compartments

Compartment Symbol Description
Susceptible S Healthy individuals who can catch the disease
Exposed E Infected but not yet infectious (incubation period)
Infected I Infectious individuals who can transmit the disease
Recovered R Individuals who recovered and are immune

Flow Diagram

Susceptible (S) β†’ Exposed (E) β†’ Infected (I) β†’ Recovered (R)
     ↓               ↓                ↓               ↓
   Healthy       Incubating        Sick/Fatal      Immune
                (not contagious)   (contagious)

πŸ€” Why SEIR Instead of SIR?

The SEIR model is more realistic for diseases with a significant incubation period.

Real-World Examples

Disease Incubation Period SEIR Needed?
COVID-19 4-7 days βœ… Yes
Ebola 2-21 days βœ… Yes
Measles 10-14 days βœ… Yes
Seasonal Flu 1-4 days ⚠️ Maybe
Common Cold 1-3 days ⚠️ Maybe
Food Poisoning 6-24 hours ❌ No

When to Use SEIR

Scenario Recommendation
Incubation period > 2 days βœ… Use SEIR
Quarantine of exposed individuals βœ… Use SEIR
Contact tracing is important βœ… Use SEIR
Quick onset disease ❌ SIR is sufficient

πŸ“ Mathematical Background

Differential Equations

The SEIR model is described by four differential equations:

dS/dt = -Ξ² Γ— S Γ— I / N
dE/dt =  Ξ² Γ— S Γ— I / N - Οƒ Γ— E
dI/dt =  Οƒ Γ— E - Ξ³ Γ— I
dR/dt =  Ξ³ Γ— I

Where:

  • N = Total population (S + E + I + R)
  • Ξ² (beta) = Infection rate
  • Οƒ (sigma) = Incubation rate (1/incubation period)
  • Ξ³ (gamma) = Recovery rate

Conservation Law

Total population remains constant:

S(t) + E(t) + I(t) + R(t) = N = constant

πŸ“Š Parameters Explained

Infection Rate (Ξ²) - Same as SIR

Value Meaning
0.0 - 0.3 Low transmission
0.3 - 0.6 Moderate transmission
0.6 - 1.0 High transmission

Incubation Rate (Οƒ)

Οƒ = 1 / (incubation period in days)
Incubation Period Οƒ Value
1 day 1.0
2 days 0.5
5 days 0.2
7 days 0.143
10 days 0.1
14 days 0.071

Recovery Rate (Ξ³) - Same as SIR

Ξ³ = 1 / (infectious period in days)
Infectious Period Ξ³ Value
2 days 0.5
5 days 0.2
7 days 0.143
10 days 0.1
14 days 0.071

⏰ Incubation Period

What is Incubation Period?

The time between infection and becoming infectious.

Real-World Incubation Periods

Disease Incubation Period Οƒ Value
COVID-19 4-7 days 0.14 - 0.25
Ebola 2-21 days 0.05 - 0.5
Measles 10-14 days 0.07 - 0.1
Flu 1-4 days 0.25 - 1.0
Common Cold 1-3 days 0.33 - 1.0

Basic Reproduction Number (Rβ‚€)

For SEIR, Rβ‚€ is calculated the same way:

Rβ‚€ = Ξ² / Ξ³

The exposed compartment affects dynamics, not the final Rβ‚€.


πŸ’» Code Examples

Basic SEIR Simulation

from sir_simulator.core_models.seir_model import run_seir_simulation

# Parameters
beta = 0.5    # Infection rate
sigma = 0.2   # Incubation rate (5 days incubation)
gamma = 0.1   # Recovery rate (10 days infectious)
S0 = 990      # Initial susceptible
E0 = 5        # Initial exposed
I0 = 5        # Initial infected
R0 = 0        # Initial recovered
t_max = 100   # 100 days

# Run simulation
df = run_seir_simulation(beta, sigma, gamma, S0, E0, I0, R0, t_max)

print(df.tail())

Calculate Key Metrics

# Calculate Rβ‚€
R0 = beta / gamma
print(f"Rβ‚€ = {R0:.2f}")

# Find peak metrics
peak_infected = df['Infected'].max()
peak_exposed = df['Exposed'].max()
peak_day = df[df['Infected'] == peak_infected]['time'].values[0]

print(f"Peak exposed: {int(peak_exposed)}")
print(f"Peak infected: {int(peak_infected)} on day {int(peak_day)}")

# Final outbreak size
final_susceptible = df['Susceptible'].iloc[-1]
total_infected = S0 - final_susceptible
print(f"Total infected: {int(total_infected)}")

Calculate Incubation Period

# Convert sigma to incubation period (days)
incubation_days = 1 / sigma
print(f"Incubation period: {incubation_days:.1f} days")

πŸ“Š Comparing SIR vs SEIR

Code to Compare Both Models

import matplotlib.pyplot as plt
from sir_simulator.core_models.sir_model import run_sir_simulation
from sir_simulator.core_models.seir_model import run_seir_simulation

# Common parameters
beta = 0.5
gamma = 0.1
S0 = 990
I0 = 10
t_max = 150

# Run SIR
df_sir = run_sir_simulation(beta, gamma, S0, I0, 0, t_max)

# Run SEIR (with same parameters + exposure)
sigma = 0.2  # 5 days incubation
E0 = 5
df_seir = run_seir_simulation(beta, sigma, gamma, S0, E0, I0, 0, t_max)

# Plot comparison
plt.figure(figsize=(12, 6))
plt.plot(df_sir['time'], df_sir['Infected'], label='SIR - Infected', 
         color='red', linestyle='-', linewidth=2)
plt.plot(df_seir['time'], df_seir['Infected'], label='SEIR - Infected', 
         color='blue', linestyle='--', linewidth=2)
plt.plot(df_seir['time'], df_seir['Exposed'], label='SEIR - Exposed', 
         color='orange', linestyle=':', linewidth=2)

plt.xlabel('Time (days)', fontsize=12)
plt.ylabel('Population', fontsize=12)
plt.title('SIR vs SEIR Model Comparison', fontsize=14)
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()

Key Differences

Feature SIR SEIR
Compartments 3 4
Incubation period ❌ No βœ… Yes
Peak timing Earlier Later (due to incubation)
Peak magnitude Higher Lower (spread out)
Realism Basic More realistic
Complexity Simple Moderate

Visual Comparison Table

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Metric          β”‚ SIR          β”‚ SEIR         β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Peak Infected   β”‚ Higher       β”‚ Lower        β”‚
β”‚ Peak Day        β”‚ Earlier      β”‚ Later        β”‚
β”‚ Outbreak Length β”‚ Shorter      β”‚ Longer       β”‚
β”‚ Rβ‚€              β”‚ Same Ξ²/Ξ³     β”‚ Same Ξ²/Ξ³     β”‚
β”‚ Final Size      β”‚ Slightly     β”‚ Slightly     β”‚
β”‚                 β”‚ higher       β”‚ lower        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

🎯 Advanced Usage

Compare Different Incubation Periods

import matplotlib.pyplot as plt

sigma_values = [0.5, 0.2, 0.1, 0.05]  # 2, 5, 10, 20 days incubation
colors = ['blue', 'green', 'orange', 'red']

plt.figure(figsize=(12, 6))

for sigma, color in zip(sigma_values, colors):
    df = run_seir_simulation(0.5, sigma, 0.1, 990, 5, 5, 0, 150)
    incubation_days = 1/sigma
    plt.plot(df['time'], df['Infected'], 
             label=f'Incubation: {incubation_days:.0f} days', 
             color=color)

plt.xlabel('Time (days)', fontsize=12)
plt.ylabel('Infected Population', fontsize=12)
plt.title('SEIR Model - Effect of Incubation Period', fontsize=14)
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()

Quarantine of Exposed Individuals

# Modify simulation to quarantine exposed individuals
# This would require custom code or using the scenario comparator

from sir_simulator.advanced_features.scenario_comparison import ScenarioComparator

comp = ScenarioComparator(population=1000, initial_infected=5, beta=0.3, gamma=0.1)
scenarios, metrics = comp.compare_all_scenarios(days=100)

print(metrics)

Parameter Optimization with Real Data

import numpy as np
from sir_simulator.advanced_features.parameter_optimization import ParameterOptimizer

# Load your real data
# data = pd.read_csv('your_data.csv')
# observed = data['cases'].values
# t = data['day'].values

# For demo, use synthetic data
t = np.linspace(0, 100, 100)
observed = 100 * np.exp(-0.1 * t) + 5 * np.random.randn(len(t))

optimizer = ParameterOptimizer(model_type='seir')
results = optimizer.fit(observed, t, [990, 5, 5, 0])

print(f"Ξ² = {results['beta']:.3f}")
print(f"Οƒ = {results['sigma']:.3f}")
print(f"Ξ³ = {results['gamma']:.3f}")
print(f"Incubation period = {1/results['sigma']:.1f} days")

⚠️ Common Pitfalls

1. Confusing Οƒ with Incubation Period

Incorrect Correct
Οƒ = 5 (meaning 5 days) Οƒ = 1/5 = 0.2
Οƒ = incubation period Οƒ = 1/incubation period

Remember: Οƒ is a rate, not a duration.

2. Initial Exposed = 0

If E0 = 0 and I0 > 0, the model works but misses the incubation effect.

3. Too Many Parameters

SEIR has 3 parameters vs SIR's 2. More data needed for fitting.

4. Forgetting to Set E0

# Good
df = run_seir_simulation(beta, sigma, gamma, S0, E0=5, I0=5, R0=0, t_max=100)

# Bad - missing E0
df = run_seir_simulation(beta, sigma, gamma, S0, I0=5, t_max=100)

πŸ“š Key Takeaways

Concept Summary
SEIR S β†’ E β†’ I β†’ R (adds Exposed compartment)
Οƒ Incubation rate = 1/incubation_days
Incubation Time from infection to infectiousness
Peak Later and lower than SIR
Best for COVID-19, Ebola, Measles

πŸ”— Next Steps


⬆ Back to Home

Clone this wiki locally