Skip to content

Commit

Permalink
Merge branch 'main' into meta-agents
Browse files Browse the repository at this point in the history
  • Loading branch information
quaquel authored Jan 2, 2025
2 parents 84b9bf3 + f751651 commit 77109bc
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 63 deletions.
44 changes: 22 additions & 22 deletions docs/tutorials/intro_tutorial.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"metadata": {},
"source": [
"**Important:** \n",
"- If you are just exploring Mesa and want the fastest way to execute the code we recommend executing this tutorial online in a Colab notebook. [![Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/projectmesa/mesa/blob/main/docs/tutorials/intro_tutorial.ipynb) or if you do not have a Google account you can use [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/projectmesa/mesa/main?labpath=docs%2Ftutorials%2Fintro_tutorial.ipynb) (Thas can take 30 seconds to 5 minutes to load)\n",
"- If you are just exploring Mesa and want the fastest way to execute the code we recommend executing this tutorial online in a Colab notebook. [![Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/projectmesa/mesa/blob/main/docs/tutorials/intro_tutorial.ipynb) or if you do not have a Google account you can use [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/projectmesa/mesa/main?labpath=docs%2Ftutorials%2Fintro_tutorial.ipynb) (This can take 30 seconds to 5 minutes to load)\n",
"- If you have installed mesa and are running locally, please ensure that your Mesa version is greater than or equal to 3.0.0b1.\n",
"\n",
"## Tutorial Description\n",
Expand Down Expand Up @@ -68,7 +68,7 @@
"\n",
"Even as a starter-level model it yields results that are both interesting and unexpected. \n",
"\n",
"Due to its simplicity and intrquiging results, we found ti to be a greater starter model. "
"Due to its simplicity and intriguing results, we found it to be the best starter model. "
]
},
{
Expand Down Expand Up @@ -104,7 +104,7 @@
"```\n",
"\n",
"\n",
"**If running in Google Colab run the below cell to install Mesa.** (This will also work in a locally installed version of Jupyter.)"
"**If running in Google Colab run the below cell to install Mesa.** (This will also work in a locally installed version of Jupyter)."
]
},
{
Expand Down Expand Up @@ -226,7 +226,7 @@
"\n",
"**Background:** The model can be visualized as a list containing all the agents. The model creates, holds and manages all the agent objects, specifically in a dictionary. The model activates agents in discrete time steps.\n",
"\n",
"**Model-specific information:** When a model is created the number of agents within the model is specified. The model then creates the agents and places them in an set of agents. \n",
"**Model-specific information:** When a model is created the number of agents within the model is specified. The model then creates the agents and places them in a set of agents. \n",
"\n",
"**Code implementation:** This is done by creating a new class (or object) that extends `mesa.Model` and calls `super().__init__()`, creating a subclass of the `Model` class from mesa. The new class is named `MoneyModel`. The technical details about the model object can be found in [model module](https://github.com/projectmesa/mesa/blob/main/mesa/model.py) and the AgentSet in the [agent module](https://github.com/projectmesa/mesa/blob/d7a3834c99a3be809abe2edc8b83610f3d4438ba/mesa/agent.py#L86). A critical point is that you can use the `seed` kwarg (keyword argument) to set a seed which controls the random number generator of the model class allowing for the reproducibility of results. \n",
"\n",
Expand Down Expand Up @@ -256,11 +256,11 @@
"source": [
"### Making the Agents `do`\n",
"\n",
"With the basics of the Agent class and Model class created we can no activate the agents to `do` things\n",
"With the basics of the Agent class and Model class created we can now activate the agents to `do` things\n",
"\n",
"**Background:** Mesa's `do` function calls agent functions the grow your ABM. A step is the smallest unit of time in the model, and is often referred to as a tick. The `do` function and Python functionality can be configured to activate agents in different orders. This can be important as the order in which agents are activated can impact the results of the model [Comer2014]. At each step of the model, one or more of the agents -- usually all of them -- are activated and take their own step, changing internally and/or interacting with one another or the environment.\n",
"**Background:** Mesa's `do` function calls agent functions to grow your ABM. A step is the smallest unit of time in the model, and is often referred to as a tick. The `do` function and Python functionality can be configured to activate agents in different orders. This can be important as the order in which agents are activated can impact the results of the model [Comer2014]. At each step of the model, one or more of the agents -- usually all of them -- are activated and take their own step, changing internally and/or interacting with one another or the environment.\n",
"\n",
"**Model-specific information:** For this section we will randomly reorder the Agent activation order using `mesa.Agent.shuffle_do` and have the agents `step` function print the agent unique id they are assigned during the agent creation process. \n",
"**Model-specific information:** For this section we will randomly reorder the Agent activation order using `mesa.Agent.shuffle_do` and have the agents `step` function print the agent's unique id that they were assigned during the agent creation process. \n",
"\n",
"**Code implementation:** Using standard ABM convention we add a `step` function to the `MoneyModel` class which calls the `mesa.Agent.shuffle_do` function. We then pass into `shuffle_do` the parameter \"step\". This tells mesa to look for and execute the `step` function in our MoneyAgent class. "
]
Expand Down Expand Up @@ -569,7 +569,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"This runs 100 instantiations of the model, and runs each for 10 steps. (notice that we set the histogram bins to be integers, since agents can only have whole numbers of wealth). This distribution looks a lot smoother. By running the model 100 times, we smooth out some of the 'noise' of randomness, and get to the model's overall expected behavior.\n",
"This runs 100 instantiations of the model, and runs each for 30 steps. (notice that we set the histogram bins to be integers, since agents can only have whole numbers of wealth). This distribution looks a lot smoother. By running the model 100 times, we smooth out some of the 'noise' of randomness, and get to the model's overall expected behavior.\n",
"\n",
"This outcome might be surprising. Despite the fact that all agents, on average, give and receive one unit of money every step, the model converges to a state where most agents have a small amount of money and a small number have a lot of money."
]
Expand All @@ -580,7 +580,7 @@
"source": [
"## Adding space\n",
"\n",
"**Background:** Many ABMs have a spatial element, with agents moving around and interacting with nearby neighbors. Mesa has several types of [spaces](https://mesa.readthedocs.io/latest/apis/space.html) from different types of grids to networks to an in development [cell_space](https://mesa.readthedocs.io/latest/apis/experimental.html#module-experimental.cell_space.__init__). Mesa grids are divided into cells, and agents can only be on a particular cell, like pieces on a chess board. Continuous space, in contrast, allows agents to have any arbitrary position. (Think of grids vs continuous space like the difference between integers and decimals.)\n",
"**Background:** Many ABMs have a spatial element, with agents moving around and interacting with nearby neighbors. Mesa has several types of [spaces](https://mesa.readthedocs.io/latest/apis/space.html) from different types of grids to networks to an in development [cell_space](https://mesa.readthedocs.io/latest/apis/experimental.html#module-experimental.cell_space.__init__). Mesa grids are divided into cells, and agents can only be on a particular cell, like pieces on a chess board. Continuous space, in contrast, allows agents to have any arbitrary position. (Think of grids vs continuous space like the difference between integers and decimals).\n",
"\n",
"Both grids and continuous spaces are frequently [toroidal](https://en.wikipedia.org/wiki/Toroidal_graph), meaning that the edges wrap around, with cells on the right edge connected to those on the left edge, and the top to the bottom. This prevents some cells having fewer neighbors than others, or agents being able to go off the edge of the environment. You can envision a torous by thinking of donut.\n",
"\n",
Expand Down Expand Up @@ -800,14 +800,14 @@
"Since one of the main goals of agent-based modeling is generating data for analysis, Mesa provides a class which can handle data collection and storage for us and make it easier to analyze.\n",
"\n",
"The data collector stores three categories of data: \n",
" - Model-level variables : Model-level collection functions take a model object as an input. Such as a function that computes a dynamic of the whole model (in this case we will compute a measure of wealth inequality based on all agents wealth)\n",
" - Model-level variables : Model-level collection functions take a model object as an input. Such as a function that computes a dynamic of the whole model (in this case we will compute a measure of wealth inequality based on all agent's wealth)\n",
" - Agent-level variables: Agent-level collection functions take an agent object as an input and is typically the state of an agent attributes, in this case wealth.\n",
" - Tables (which are a catch-all for everything else). \n",
"\n",
"**Model-specific information:** We will collect two variables to show Mesa capabilities. At the model level, let's measure the model's [Gini Coefficient](https://en.wikipedia.org/wiki/Gini_coefficient), a measure of wealth inequality. At the agent level, we want to collect every agent's wealth at every step. \n",
"\n",
"**Code implementation:**\n",
"Let's add a DataCollector to the model with [`mesa.DataCollector`](https://github.com/projectmesa/mesa/blob/main/mesa/datacollection.py), and collect the agents wealth and the gini coefficient at each time step. "
"Let's add a DataCollector to the model with [`mesa.DataCollector`](https://github.com/projectmesa/mesa/blob/main/mesa/datacollection.py), and collect the agent's wealth and the gini coefficient at each time step. "
]
},
{
Expand Down Expand Up @@ -882,9 +882,9 @@
"source": [
"At every step of the model, the datacollector will collect and store the model-level current Gini coefficient, as well as each agent's wealth, associating each with the current step.\n",
"\n",
"We run the model just as we did above. now is when an interactive session, especially via a notebook, comes in handy: the DataCollector can export the data its collected as a pandas* DataFrame, for easy interactive analysis. \n",
"We run the model just as we did above. Now is when an interactive session, especially via a notebook, comes in handy: the DataCollector can export the data it has collected as a pandas* DataFrame, for easy and interactive analysis. \n",
"\n",
"*If you are new to Python, please be aware that pandas is already installed as a dependency of Mesa and that [pandas](https://pandas.pydata.org/docs/) is a \"fast, powerful, flexible and easy to use open source data analysis and manipulation tool\". pandas is great resource to help analyze the data collected in your models."
"*If you are new to Python, please be aware that pandas is already installed as a dependency of Mesa and that [pandas](https://pandas.pydata.org/docs/) is a \"fast, powerful, flexible and easy to use open source data analysis and manipulation tool\". Pandas is a great resource to help analyze the data collected in your models."
]
},
{
Expand Down Expand Up @@ -1051,7 +1051,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"You can also use pandas to export the data to a CSV (comma separated value), which can be opened by any common spreadsheet application or opened by pandas.\n",
"You can also use pandas to export the data to a CSV (comma separated value) file, which can be opened by any common spreadsheet application or opened by pandas.\n",
"\n",
"If you do not specify a file path, the file will be saved in the local directory. After you run the code below you will see two files appear (*model_data.csv* and *agent_data.csv*)"
]
Expand Down Expand Up @@ -1280,7 +1280,7 @@
"\n",
"**Model-specific implementation:** In this case we will give agents an attribute of enthnicity of Green, Blue or Mixed. Green and Blue agents only give money to their ethnicity while Mixed can give money to anyone.\n",
"\n",
"**Code Implementation**: Using `groupby` we will execute the above logic in our code passing a list of grouped agents into our `give_money` function. To ensure we can plot wealth by group we also need to add ethnicity to our datacollector. "
"**Code Implementation**: Using `groupby` we will execute the above logic in our code by passing a list of grouped agents into our `give_money` function. To ensure we can plot wealth by group we also need to add ethnicity to our datacollector. "
]
},
{
Expand Down Expand Up @@ -1460,7 +1460,7 @@
" A dictionary containing all the parameters of the model class and desired values to use for the batch run as key-value pairs. Each value can either be fixed ( e.g. `{\"height\": 10, \"width\": 10}`) or an iterable (e.g. `{\"n\": range(10, 500, 10)}`). `batch_run` will then generate all possible parameter combinations based on this dictionary and run the model `iterations` times for each combination.\n",
"* `number_processes`\n",
" If not specified, defaults to 1. Set it to `None` to use all the available processors.\n",
" note: Multiprocessing does make debugging challenging. If your parameter sweeps are resulting in unexpected errors set `number_processes=1`.\n",
" Note: Multiprocessing does make debugging challenging. If your parameter sweeps are resulting in unexpected errors set `number_processes=1`.\n",
"* `iterations`\n",
" The number of iterations to run each parameter combination for. Optional. If not specified, defaults to 1.\n",
"* `data_collection_period`\n",
Expand All @@ -1482,16 +1482,16 @@
"1. the Gini coefficient value at each time step, and\n",
"2. the individual agent's wealth development and steps without giving money.\n",
"\n",
"**Important:** Since for the latter changes at each time step might be interesting, we set `data_collection_period=1`. By default, it only collects data at the end of each episode.\n",
"**Important:** Since for the latter, changes at each time step might be interesting, we set `data_collection_period=1`. By default, it only collects data at the end of each episode.\n",
"\n",
"note: The total number of runs is 245 (= 49 different populations * 5 iterations per population). However, the resulting list of dictionaries will be of length 6186250 (= 250 average agents per population * 49 different populations * 5 iterations per population * 101 steps per iteration). "
"Note: The total number of runs is 245 (= 49 different populations * 5 iterations per population). However, the resulting list of dictionaries will be of length 6186250 (= 250 average agents per population * 49 different populations * 5 iterations per population * 101 steps per iteration). "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**note for Windows OS users:** If you are running this tutorial in Jupyter, make sure that you set `number_processes = 1` (single process). If `number_processes` is greater than 1, it is less straightforward to set up. For details on how to use multiprocessing on windows, see [multiprocessing's programming guidelines](https://docs.python.org/3/library/multiprocessing.html#multiprocessing-programming). "
"**Note for Windows OS users:** If you are running this tutorial in Jupyter, make sure that you set `number_processes = 1` (single process). If `number_processes` is greater than 1, it is less straightforward to set up. For details on how to use multiprocessing on windows, see [multiprocessing's programming guidelines](https://docs.python.org/3/library/multiprocessing.html#multiprocessing-programming). "
]
},
{
Expand Down Expand Up @@ -1541,7 +1541,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"First, we want to take a closer look at how the Gini coefficient at the end of each episode changes as we increase the size of the population. For this, we filter our results to only contain the data of one agent (the Gini coefficient will be the same for the entire population at any time) at the 100th step of each episode and then scatter-plot the values for the Gini coefficient over the the number of agents. notice there are five values for each population size since we set `iterations=5` when calling the batch run."
"First, we want to take a closer look at how the Gini coefficient at the end of each episode changes as we increase the size of the population. For this, we filter our results to only contain the data of one agent (the Gini coefficient will be the same for the entire population at any time) at the 100th step of each episode and then scatter-plot the values for the Gini coefficient over the the number of agents. Notice there are five values for each population size since we set `iterations=5` when calling the batch run."
]
},
{
Expand Down Expand Up @@ -1600,7 +1600,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"Second, we want to display the agent's wealth at each time step of one specific episode. To do this, we again filter our large data frame, this time with a fixed number of agents and only for a specific iteration of that population.\n",
"Secondly, we want to display the agent's wealth at each time step of one specific episode. To do this, we again filter our large data frame, this time with a fixed number of agents and only for a specific iteration of that population.\n",
"To print the results, we convert the filtered data frame to a string specifying the desired columns to print. \n",
"\n",
"Pandas has built-in functions to convert to a lot of different data formats. For example, to display as a table in a Jupyter notebook, we can use the `to_html()` function which takes the same arguments as `to_string()` (see commented lines)."
Expand Down Expand Up @@ -1656,7 +1656,7 @@
"### Analyzing model reporters: Comparing 5 scenarios\n",
"Other insights might be gathered when we compare the Gini coefficient of different scenarios. For example, we can compare the Gini coefficient of a population with 25 agents to the Gini coefficient of a population with 400 agents. While doing this, we increase the number of iterations to 25 to get a better estimate of the Gini coefficient for each population size and get usable error estimations.\n",
"\n",
"As we look varying the parameters to see the impact on model outcomes, it is critical to again point that users can set the random seed. Due to the often inherent randomness with ABMs the seed becomes crucial for: \n",
"As we look varying the parameters to see the impact on model outcomes, it is critical to again point out that users can set the random seed. Due to the often inherent randomness with ABMs the seed becomes crucial for: \n",
"- **Reproducibility** - Being able to replicate the ABM results\n",
"- **Sensitivity Analysis** - Identifying how sensitive/robust your model results are to random fluctuations\n",
"\n",
Expand Down
Loading

0 comments on commit 77109bc

Please sign in to comment.