Tipping point models

The SIS model from epidemiology as an example of a model exhibiting a tipping point. This model allows us to calculate the percentage of a population that needs to be vaccinated in order to get population level herd immunity.

There's a nice animation here.

The discussion here is heavily based on the discussion of tipping points in Scott Page's very nice coursera course on Model Thinking. I essentially transcribed his algebra in SymPy.

Diffusion model

The first model we develop is a simple diffusion model. It has no tipping, but shows that the spread of infectious diseases is an accelating process, that becomes quicker as more people are infected.

First some general definitions of symtobls.

In [31]:
import sympy as sm
from sympy.abc import N, c, t, tau
Wt = sm.symbols('Wt')
Wtt, Penc = sm.symbols('Wtt,Penc',cls=sm.Function)

Let $W_t$ be the number of sick people in the population, whose overall size is $N$. Here is the formula for $P_{enc}$, the probability that a healthy person and a sick person meet. These are the cases in which an infection can happen.

In [152]:
Penc = (Wt/N)*((N - Wt)/N)

Using this we can write down the number of infected individuals in the next time period. It is $W_t$ plus the number of newly infected inviduals which depends on $P_{enc}$ as well as on $c$, the probability the people in the population interact, and $\tau$, the transmission rate of the disease.

In [153]:
Wtt=N*c*Penc*tau + Wt
In [154]:
$$Wt + \frac{Wt c}{N} \tau \left(N - Wt\right)$$

To understand the dynamics of this process it is enough study how $P_{enc}$ changes as $W_t$ increases.

In [41]:
$$\frac{Wt}{N^{2}} \left(N - Wt\right)$$

First, let's see what happens when $W_t$ is small and $N$ is large.

In [155]:
$$\frac{1}{N^{2}} \left(N - 1\right)$$
In [156]:

Or you can do it in one step

In [38]:

Thus, when $W_t$ is small, the probability of encountering someone who is sick is low. What happens when $W_t$ is large, i.e. $W_t\approx N$?

In [157]:

Zero?? How come?! The reason is simple (and symmetric): in this case the probability of encountering someone who is healthy is very low, hence the probability of an encouter between a sick person and a health person is low. To complete the picture, let's check what happens when $W_t=N/2$

In [158]:


For completeness let's put down some assumptions and graph $W_t$ over time. Assume N=100, $\tau=0.5$ (which is very high). Start with only on person sick, i.e. $W_0=1$. Let $c=0.5$ too.

In [159]:
In [160]:
for t in range(0,49):
In [161]:
%pylab inline
Populating the interactive namespace from numpy and matplotlib
In [162]:
pylab.ylabel('Number of infected individuals')
pylab.title('Diffusion of infection')
<matplotlib.text.Text at 0xc14b08c>

As Scott Page explains in his lecture, what we see here is simply an accelarting process, not a tipping point. This accelaration matches the expectation we developed earlier by studying algebracially the properties of $P_{enc}$.

The SIS model

We now turn to the SIS model (Susceptible-Infected-Susceptible). The difference is that now infected individuals can become cured, and reutrn to the pool of susceptible individuals (thus, being sick does not make you immune to subsequent reinfection). The difference consists solely of adding a term to $W_{t+1}$ measuring the numer of cured inviduals. Let $a$ be the rate of being cured.

In [163]:
a = sm.symbols('a',negative=False, real=True)
Wtt_sis = sm.symbols('Wtt_sis',cls=sm.Function)
Wtt_sis = Wtt - a*Wt
In [167]:
$$- Wt a + Wt + \frac{Wt c}{N} \tau \left(N - Wt\right)$$

We are just interested in the change, so let's simplify things a bit:

In [168]:
change=sm.collect(Wtt_sis -Wt,Wt)
$$Wt \left(- a + \frac{c \tau}{N} \left(N - Wt\right)\right)$$

Now assume $Wt<<N$

In [169]:
$$Wt \left(- a + c \tau\right)$$

so the number of infections will increase (i.e., the infection will spread) if $c\tau-a>0$, or $c\tau/a>1$. This number $R_0=c\tau/a$ is called the Basic reproduction number. If it is bigger than 1, the disease spreads. This (as opposed to that we saw in the diffusion model) is a true tipping point. $R_0$ values for several well-known diseases (via Wikipedia): Measles - 12-18; Mumps - 4-7; HIV - 2-5; Flu - 2-3; Ebola - 1.5-2.5. Ouch!


Assuming a vaccine is 100% effective, we should check $r_0=R_0(1-v)$, where $v$ is the proportion of the population that is vaccinated (making $1-v$ the proportion of individuals who are not vaccinated) instead of $R_0$. If you are not sure why, review the expression used to derive $R_0$. For vaccination to be effective we need $R_0(1-v)<1$

In [170]:
v,R = sm.symbols('v,R',negative=False, real=True)
$$R \left(- v + 1\right) < 1$$


In [171]:
$$- v + 1 < \frac{1}{R}$$
In [172]:
$$v > 1 - \frac{1}{R}$$

$v$ has to be above this threshold for vaccination to be effective in stopping the spread othe disease. Below that number there is no population level effect ("herd immunity"). That's the key result: the beneifts do not increase linearly, with each vaccinated inidividual improving the protection of the population by the same amount. There's a tipping point, which depends on $R_0$. Thus, for measles, we need:

In [175]:

or essentially 95% of the population to be vaccinated to get herd immunity. This has profound policy implications. To be provocative: If you, as a health official, know that this number is unatainable (e.g., because too many people decide not to vaccinate their kids for some reason) -- should you recommend stopping the program to mandate vaccinatons on everyone else?