Reasoning about epidemics with simulations

Sam Stone
Structured Ramblings
8 min readMar 20, 2020

This post uses simulations and animations to understand epidemics. I started going down this path in my own attempt to understand the forces driving this crazy new world of coronavirus and “shelter in place.”

I’m hopeful that the underlying model and visualization code may be useful to others, including people (like me) just trying to make sense of what’s going on. I’m also hopeful it may be useful, or at least thought-provoking, for those making policy and healthcare decisions.

A few insights:

  • It’s hard to reduce the fatality rate (deaths / infections) via public policy; it’s easier to reduce the mortality rate (deaths / population). The fatality rate is largely driven by disease biology; the mortality rate captures the impact of healthcare and societal interventions. In policy conversations, it’s important to consider the mortality rate, not just the fatality rate.
  • One of the most dangerous aspects of a disease is a large proportion of infections that are contagious, but unknown. More testing can lower the mortality rate by reducing the amount of time a contagious person interacts with others before self-quarantining.
  • All else equal (in terms of healthcare interventions), epidemic impact can be worse for cities that are infected later. These non-origin cities simultaneously get many “patient zeros” arriving from other cities, while the origin city only has one “patient zero”. As long as non-origin cities are quicker to enact social distancing, they are at an advantage — but if they are as not, they could be disadvantaged.

A big caveat: I am not an epidemiologist. Moreover, the simulations in this post do not represent the scientific community’s latest understanding of Covid-19. All numbers are purely illustrative. In each simulation, I make assumptions about key factors (like infection duration or transmission probability); my assumptions are simply round numbers used for building intuition. These simulations are analytical, but they contain no real data.

1. The SIR Model

We’ll start with a simple, widely used epidemiological model called SIR: Susceptible, Infectious, Recovered. In this model, everyone starts as susceptible (except patient 0), may transition to infectious, and then recovers. Recovered patients are immune — they cannot be reinfected and they cannot transmit infection.

Here’s how an epidemic spreads through a simulated population of 100, where we make 2 assumptions:

  • Probability of connections between persons in the same city (5%)
  • Probability of infection transmission between connections, per day (20%)
Figure 1

Three aggregate statistics describe this epidemic’s behavior over time. The infection rate grows exponentially, peaks at day 13, and then shrinks exponentially. The population immunity rate follows an S-curve (and the susceptibility rate is just its inverse). Not everyone catches the infection, as the immunity rate plateaus at 92%, meaning 8% of the population never catches the infection. This happens because enough people recover, making them immune to transmission and “walling off” pockets of the population that remain susceptible. (However, if we change our two assumptions, its easy to produce an end-state where all person are infected.)

Chart 1

2. Diagnosis and fatalities

Let’s modify this simple model to behave more like a real-world virus:

  • There is a period of between infection and diagnosis, in which a person is infected but not diagnosed
  • Patients with a mild infection are never diagnosed, and they all recover
  • Most patients with a severe infection will recover, but some will die.

Here’s how this disease passes through a population. Again, not everyone catches the infection, but that’s just a function of assumptions:

Figure 2

We need a few new metrics to describe this population’s behavior:

  • Observed infection rate = diagnosed infections / population. This is what is known at the time and reported in the media.
  • Population infection rate (or “true infection rate”) = (diagnosed and undiagnosed infections) / population. This is not known at the time; it can be estimated afterwards, but even then it cannot be known precisely because some persons transition from susceptible to infected to recovered without ever being diagnosed, if their case is mild.
  • Case fatality rate = deaths / (diagnosed and undiagnosed infections). Like the true infection rate, this metric is also not known at the time, and it can only be estimated after the fact. There are other widely accepted ways to define case fatality rate, which I’ll refer to as just the “fatality rate” for the rest of the post.
  • Mortality rate = deaths / population. This is probably more useful than the fatality rate, because the numerator and denominator are less susceptible to measurement error (e.g. we don’t have to worry about undiagnosed cases).
Chart 2

Now we can see a defining attribute if the Covid-19 outbreak: the undiagnosed population is far larger than the diagnosed population, until the very end of the epidemic. The fatality rate is 10% and the mortality rate is 9%; now we’ll layer on healthcare and social interventions to see the impact.

3. The Healthcare System

The role of the healthcare system in moderating the outcomes of an epidemic can be represented with two assumptions:

  • The chances of survival are lower for a patient if there is no available hospital bed for the patient when they are diagnosed (95% survival with a hospital bed vs 80% without)
  • There are a fixed number of hospital beds across time (5 beds / 100 people)

In reality, the healthcare system is not static (there is surge capacity). And many things other than hospital bed count actually matter.

Here’s how the epidemic progresses now. The red dots with blue outlines are people who are infected and diagnosed, but who cannot get a hospital bed. This is because at the time they were diagnosed, all 5 hospital beds were already filled.

Figure 3

There is no significant difference in the number of infections or the rate at which infections grow vs prior to modeling hospital beds. However, the fatality rate behaves differently. It is low at first, because there are ample hospital beds. But when hospital beds run out, it climbs, and only plateaus when the number of severe infections falls back below 5.

Chart 3

4. Contagion Prevention

Cities across the world are fighting Covid-19 outside the traditional healthcare system via quarantines, social distancing, and shelter-in-place doctrines. For individuals participating in these preventative measures, they all have something in common: while they are participating, (1) an individual cannot be infected, if they are not already infected, and (2) they cannot infect anyone else. We’ll call our preventative measure “social distancing” in the following charts, but this could just as well as be quarantine or shelter-in- place. Social distancing is modeled with 2 assumptions:

  • The number of diagnosed cases in a city before social distancing begins in the city (7 per 100 people, which occurs on day 10)
  • The adoption rate of social distancing, once it is in effect, amongst susceptible and infected-not diagnosed persons (70%)

The black outlines indicate the individuals practicing social distancing. A handful of individuals practice social distancing before day 13, because they have been diagnosed positive (e.g. they are just in quarantine. Then, on day 13, social as a whole flips to social distancing, impacting both susceptible and infected-not diagnosed people.

Figure 4
Chart 4

With social distancing, the “curve is flattened” — the observed infection rate, and the true infection rate are both lower, and the end-state mortality rate falls from 14% to 9%.

5. Multiple Geographies

Finally, let’s incorporate multiple geographies (e.g. cities or countries or continents) to see how an epidemic becomes a pandemic. This is implemented with two assumptions:

  • A probability that a person has connections in another city (<1%)
  • A travel probability — the likelihood that a person, who has connections in another city, switches cities on any given day (5%)

(For the fans of graph theory, this network is an undirected partitioned graph, where each partition is a city.)

Here’s a 3-city population, where the infection begins in City C and then progresses to Cities A and B:

Here are the summary statistics, for each city and for the entire population:

The infection rate peaks in City C first, then in A, and then in B. Noticeably, Cities A and B do not fare much better than C in terms of mortality rate. Actually, City A does worse than C, despite the later onset. This is because City A, before it enacts social distancing, is receiving infected patients from both City B and C — in other words it has a number of “patient zeros” at the same time. City C, on the other hand, as the originating city of the pandemic, doesn’t get this “bounce back” of infected patient — it only has one patient zero.

This is just the tip of the iceberg. The underlying code and visualization tools can be use to explore many other question around how epidemics progress. For example:

  • What is the cost each day a city waits to require “shelter in place”?
  • Which interventions are most beneficial, for example higher adherence to “shelter in place” or reducing travel?
  • Under what circumstances is a city more or less likely to be re-infected from other cities?

Every city and nation is now figuring out how Covid-19 is likely to progress, and how to minimize the consequences.

My hope is that these simulation tools can help people reason about the seismic societal shifts happening right now, and perhaps that these tools are also useful to some scientists and policymakers.

--

--