Saturday, April 25, 2020

Using Mesa framework to simulate the spread of COVID-19

First, a disclaimer. I am not a medical professional, I am no expert in medical or health science. I am just a person who studied computer science and has an interest in multi-agent simulations.

Okay, so with the global spread of COVID-19, and many many people trying to use their programming and data science skills to model COVID-19, I thought I would use it as an example to learn the Mesa agent-based simulation framework.

Using Mesa, I made a simple simulation. In it, the population starts with an initial percentage of people infected with a disease. They have a chance of spreading the disease, a chance of dying for it, and after a fixed period, they recover from it. Recovering from the disease also grants a certain chance of immunity from subsequent infections. At the start of the simulation, a certain percentage of people would be in "stay at home" mode. When people become infected, they have a chance of being put into quarantine, and people in quarantine no longer infects others.

Here is when a 100x100 grid with a population density of 30%, an initial infected population of 5%. When 50% of them start off in "stay at home" mode, eventually, almost everyone still ends up getting infected.


When that "stay at home" rate is 80%, a lot of people still get infected eventually. But the peak number of infections is less. I guess that is what they meant by flattening the curve.

In addition to plotting the results as charts, the Mesa framework also allows visualization in a web browser. Here is the 50% stay at home case as an example.


The source code is available here for everyone to tweak and experiment.

To set the scenario, edit the parameters in run.py.

Then, to run the scenario, use python3 main.py which will produce a chart at the end.

If you want visualization on a web browser, run server.py instead.

If you add in new parameters in run.py, you will need to edit model.py to read those parameters. Then, edit model.py and person.py as necessary to handle those parameters. model.py deals with the entire simulation, while person.py is the behavior for each person (agent).

Feel free to tweak the model. At present, the model is very simplistic because it does not account for hospital capacity, severity of infection, and many many other real-world factors. You will need to consider these factors for accurate modeling. My goal was just to create a simple simulation to learn how to use the Mesa framework.

Side note: I somehow feel the Mesa framework is a bit bloated. So I will see if I can find a way to develop a simulation that uses Python with some other framework for visualization.

3 comments:

Teck said...

I did this in around 3 hours, so there is definitely a lot of room for further improvement.

Gabriel said...

Hi! I'm trying to use your program for a school project and I have a question. I run the simulation with 0.3 density of the agents and 100x100 grid for 1000 steps. I got the following results: infected: 314, immune 2509, deaths 264.
I don't understand why if I add all these I get a number bigger than the number of agents used in the simulation (3000).

Teck said...

Thank you for pointing it out. There was a bug, the dead agents were still flagged as infected. I have fixed it and updated the repo. Basically, added a line in while_infected(self) in person.py to set infected flag to False when an agent dies.

After the line:
self.alive = False # person died from infection
added this line:
self.infected = False # dead person no longer counts as infected

This should avoid the double counting.