Introduction to Mesa: Agent-based Modeling in Python | by Ng Wai Foong | Towards Data Science

Python-based alternative to NetLogo, Repast, or MASON for agent-based modeling
Agent-based modeling relies on simulating the actions and interactions of autonomous agents to evaluate their effects on the system. It is often used to predict the projections that we will obtain given a complex phenomena. The main purpose is to obtain explanatory insight on how the agents will behave given a particular set of rules. Agent-based modeling has been extensively used in numerous industry such as biology, social sciences, network and business. This article covers the necessary steps to kick-start your agent-based modeling project using an open-source python module called Mesa. There are 4 sections in this tutorial:
SetupSchelling Segregation ModelVisualizationConclusion
Setup
Schelling Segregation Model
Visualization
Conclusion
Setup is pretty straightforward for Mesa. Make sure to create a new virtual environment. I name the environment as mesaenv. Open up your terminal and change the directory to mesaenv and activate the virtual environment using the following code:
Run the following command to activate the virtual environment depending on your use case.
#Anacondaconda activate mesaenv#Terminalsource bin/activate
This tutorial requires three modules:
mesa
matplotlib
jupyter
python3 -m pip install mesapython3 -m pip install matplotlibpython3 -m pip install jupyter
Create a base folder called Mesa that you will use to store all the python files. You should have the following files in the base folder at the end of this sections:
Model.pyRun.pyServer.py
Model.py
Run.py
Server.py
Feel free to download it in case you got lost somewhere in the tutorial. Once you are done, let’s proceed to the next section.
We will be using the famous Schelling Segregation model as use case for this tutorial. Please be noted that the introductory tutorial on the official mesa site is based on Boltzmann Wealth model. Schelling Segregation model is a better use case to explain how we can use agent-based modeling to explain why racial segregation issue is difficult to be eradicated. Although the actual model is quite simple, it provides explanatory insights at how individuals might self-segregate even though when they have no explicit desire to do so. Let’s have a look at the explanation for this model provided by the Mesa official github page:
The Schelling segregation model is a classic agent-based model, demonstrating how even a mild preference for similar neighbors can lead to a much higher degree of segregation than we would intuitively expect. The model consists of agents on a square grid, where each grid cell can contain at most one agent. Agents come in two colors: red and blue. They are happy if a certain number of their eight possible neighbors are of the same color, and unhappy otherwise. Unhappy agents will pick a random empty cell to move to each step, until they are happy. The model keeps running until there are no unhappy agents.
By default, the number of similar neighbors the agents need to be happy is set to 3. That means the agents would be perfectly happy with a majority of their neighbors being of a different color (e.g. a Blue agent would be happy with five Red neighbors and three Blue ones). Despite this, the model consistently leads to a high degree of segregation, with most agents ending up with no neighbors of a different color.
Create a new python file called model.py.
Agent: We will start off with the single agent class.
The code is quite straightforward:
Initialize the Agent class.Create a step function.Calculate the number of similar neighbors.Move the agent to a empty location if the agent is unhappy.
Initialize the Agent class.
Create a step function.
Calculate the number of similar neighbors.
Move the agent to a empty location if the agent is unhappy.
Model: For the model class. We will go through each part one-by-one to have a clearer understanding of how agent-based modeling works. First and foremost, create a Schelling class and define a init function as constructor.
class Schelling(Model):    def __init__():
Variables: The system will consists of at least a basic agent class and a model class. Let’s start by writing the model first. We will need to define 5 main variables:
Width: Horizontal axis of the grid which is used together with Height to define the total number of agents in the system.
Height: Vertical axis of the grid which is used together with Width to define the total number of agents in the system.
Density: Define the population density of agent in the system. Floating value from 0 to 1.
Fraction minority: The ratio between blue and red. Blue is represented as the minority while red is represented as the majority. Floating value from 0 to 1. If the value is higher than 0.5, blue will become the majority instead.
Homophily: Define the number of similar neighbors required for the agents to be happy. Integer value range from 0 to 8 since you can only be surrounded by 8 neighbors.
self.height = heightself.width = widthself.density = densityself.minority_pc = minority_pcself.homophily = homophily
Remember to add the required parameters as input parameters in the init function.
Grid: We will need to set the grid using the space module under mesa.
from mesa.space import SingleGridself.grid = SingleGrid(height, width, torus=True)
Scheduler: Next up, we will need to have a scheduler. The scheduler is a special model component which controls the order in which agents are activated. The most common scheduler is the random activation which activates all the agents once per step, in random order. There is also another type called Simultaneous activation. Check out the API reference to find out more.
from mesa.time import RandomActivationself.schedule = RandomActivation(self)
Data Collection: Data collection is essential to ensure that we obtained the necessary data after each step of the simulation. You can use the built-in datacollection module. In this case, we only need to know whether the agent is happy or not.
from mesa.datacollection import DataCollectorself.happy = 0self.datacollector = DataCollector(                                   {"happy": "happy"},{"x": lambda a: a.pos[0], "y": lambda a: a.pos[1]})
Agents Setup: We will now setup the agent using the following code:
The last part of the init function is to set the following parameters:
self.running = True                               self.datacollector.collect(self)
The running variable enables conditional shut off of the model once a condition is met. We will set it to false once all the agent are happy.
Step: This class requires a step function that represent each run.
Reset the counter of happy agents at each step.Start to collect data and determine the number of agent that are happy.Stop the model once all agents are happy.
Reset the counter of happy agents at each step.
Start to collect data and determine the number of agent that are happy.
Stop the model once all agents are happy.
Create a new python file called run.py and type in the following code.
Create a new python file called server.py.
Import: Add the following import statement to the file:
from mesa.visualization.ModularVisualization import ModularServerfrom mesa.visualization.modules import CanvasGrid, ChartModule, TextElementfrom mesa.visualization.UserParam import UserSettableParameter                                               from model import Schelling
HappyElement: Create a class called HappyElement and add two functions:
Init
Render
Draw function: Define a function called schelling_draw.
This part acts as the visualization part when running the server.
First, we define the base potrayal. A portrayal is a dictionary (which can easily be turned into a JSON object) which tells the JavaScript side how to draw it.We change the color and stroke of the portrayal based on the type of the agent. In this case, we will have red and blue agent.Initialize the Canvas and chart.Set the parameters for the model. UserSettableParameter means that the user can modify this parameter in the web page. It takes 6 parameters (type, name, initial value, min value, max value, value per step).Finally, we initialize the server with all the configurations that we have defined above.
First, we define the base potrayal. A portrayal is a dictionary (which can easily be turned into a JSON object) which tells the JavaScript side how to draw it.
We change the color and stroke of the portrayal based on the type of the agent. In this case, we will have red and blue agent.
Initialize the Canvas and chart.
Set the parameters for the model. UserSettableParameter means that the user can modify this parameter in the web page. It takes 6 parameters (type, name, initial value, min value, max value, value per step).
Finally, we initialize the server with all the configurations that we have defined above.
Let’s test it out by running the following code at the terminal. Make sure that you are at the base folder (Mesa).
mesa runserver
A web browser will be launched and you should see the following ouput:
The visualization of the canvas grid that we have defined earlier. Each dot represents an agent.
You can modify the setting to test out how it will affects the simulation. Modify this will not affect the current simulation. Remember to click on the Reset button to make changes.
You can define your own frame per second to speed up the simulation.
You will have the following buttons at your disposal:
Start/Stop: It will start the simulation. Once it is started, you can click on the same button to turn it off.
Step: Run only a single step to see the changes.
Reset: Reset the board based on the setting. If you use it while the simulation is running, the board will be reset and simulation will continue to run as usual.
Click on the Start button and you should see the following changes to the canvas.
There is a chart at the bottom to show the number of agents that are happy against the number of step.
The model should stop at a certain point depends on the setting that you have set. You can noticed that the agents are pretty much segregated.
Let’s recap on what we have learned today.
We started off with some simple steps to setup and install the necessary python modules.
Then, we learned about the Schelling Segregation Model and how we can model it easily using Mesa. We created 3 python files and explored further in-depth on the basic usage of components available in Mesa.
After that, we ran the server to see the visualization. We modified some settings and play around with the simulation. In fact, the official Mesa github provided us with a lot more examples that we can explore. Check out the following link to find out more.
Hope you enjoyed the tutorial. Have a great day and see you again in the next tutorial.