Corona Virus - Impact of Social Distancing

DESCRIPTION

We create a small model simulation on how diseases such as the corona virus can spread through communities. While the author does have a Ph.D., and studied modeling & simulation, he is not a 'real doctor' or a public health expert.

We wanted to setup a basic model that a user can play with to even begin to ask questions. Please feel free to change the parameters on the right and hit the "Run" button to re-run the simulation with changes.

For simplicity and speed we start with a population size of 100K, roughly one-tenth the size of San Francisco. San Francisco has about 40 cases of Corona virus, and so we scaled it down to 4 as the starting disease population. We realize this number could be much larger because of untested individuals.

We define a concept of resistance, colloquially, as the average number of people you interact with who carry the disease and are contagious for it to spread to you. For example a resistance of 0.95 would mean, you need to interact with 20 currently contagious individuals on average before you contract the disease.

Incubation period is the number of days you are asymptomatic but contagious. Incubation period under current scientific studies are around 5 days for the COVID-19. Disease period is the number of days you have the disease. By default we use 4 and 7 for these parameters which seem fairly conservative.

Mortality rate is the often talked about deaths to number of cases ratio. Set to 0.01 (1%) by default here.

We have a boolean complete Quarantine if sick so they have no chance of spreading the disease after they are infected.

We also have a "Global" or "Neighborhood" interaction model. A Global model means you mean random people such as store associate clerk, people in a movie theatre etc. A neighborhood model is basically when people are at home and only interact with their immediate family. The number of people interactions is the number of people one interacts with on a daily basis.

Here are some interesting results.

First, we consider a typical (very conservative in fact) San Francisco day with no distancing. If you use 100K population size, 4 individuals with the disease, 10 random interactions a day, 0.95 resistance (feels really high), and full quarantine when sick, we basically have no chance of stopping the disease - it will hit the majority of the SF population. And if thats a model for the rest of the US, it will hit most of US and we pretty much have no chance. Note that, these outcomes are pretty robust to a lot of change in parameters.

Second, we consider the setting where we are restricted to our homes for the most part. No conferences, schools, restaurants, movies etc. Now the results change dramatically. Try just updating Interaction Model from "Global" to "Neighborhood". Firstly, you'll notice that we dramatically cut down on the percent infected. Second, you'll notice that we dramatically slow down the spread of the disease.

Third, under the same "Neighborhood" model, just cut down the number of people interactions from 10 to 4, the size of a typical family. Now we will in fact quickly beat the disease and wipe it out completely. Even in cases when we don't wipe it out (from 4-10 interaction size or lower resistance) we have it totally under control. Once again, this is also robust for lower resistance levels and higher starting disease population levels.

Now, you may wonder what about a 'mixed' interaction model. The problem here is that even a little bit of global interaction (set to 4) and resistance of 0.9 (slightly lower than 0.95) is enough to let the disease out of control and infect 2/3rd of the population before dying out. This drops to 1/3rd of the population if we have 3 global interactions per day. And if we did not quarantine sick, then in fact it spreads to nearly everyone.

** Help **

sample(outcomes, probabilities)

Sample an outcome from the outcomes array based on the corresponding probabilities in the probabilities array.

radiobutton(name, options)

Creates a radio button parameter with name and have each option in the options array selectable. Returns the selected option.

textbox(name, default_value)

Create a textbox parameter with name and a required default value. Returns the value of the textbox.

scatter_graph(data, xlabel, ylabel)

Create a graph based on a data array and plot (data.xlabel, data.ylabel) on it. Can also pass xmin=null, xmax=null, ymin=null, ymax=null as added arguments.

stop_simulation()

Calling this function, stops the simulation.

average(values)

Returns the average of the values in the array. It can be handy to store the values of metrics from each simulation run and average it across all runs to obtain an estimate of the metric.

error_average(values)

Returns the estimated error (1.96 x standard error) of the average of the values at 95% confidence. In simple terms, you can assume that the estimate average(values) has error bounds +/- error_average(values). It can be handy to store the values of metrics from each simulation run and estimate both the average and the error of the average across all runs.

stdev(values)

Returns the standard deviation of the values in the passed in array.