Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added a new example: city walking behaviour #241

Draft
wants to merge 12 commits into
base: main
Choose a base branch
from

Conversation

Sahil-Chhoker
Copy link

@Sahil-Chhoker Sahil-Chhoker commented Dec 27, 2024

Add Walking Behavior Agent-Based Model

Summary

This PR introduces an Agent-Based Model (ABM) for simulating walking behavior in a hypothetical city. The model explores how socioeconomic status (SES), built environment, and social factors dynamically influence walking patterns. The following files and components have been added to the repository:


Files Added

  1. README.md:

    • Provides a detailed overview of the model architecture, agent characteristics, environmental layers, and simulation scenarios.
  2. Model.py:

    • Sets up the grid and initializes the four scenarios (RR, RS, CR, CS).
    • Manages the safety and aesthetic property layers.
    • Places different workplaces according to the scenario.
    • Places Humans according to their SES values
    • Collects metrics such as average daily walking trips, work-related trips, and leisure walks for analysis.
  3. Agents.py:

    • Demographics:
      • Gender (50/50 distribution)
      • Age (18-87 years, random distribution)
      • Family Size (1-2 members)
      • Pet Ownership (20% dog ownership rate)
    • Personal Attributes:
      • Walking Ability
      • Walking Attitude
      • Employment Status
      • Social Networks
    • Workplaces:
      • Grocery Store
      • Social Place
      • Non-Food Store
      • Others

Key Features Added

1. Initialization Parameters

  • Grid Dimensions: Width and height of the city grid.
  • Workplace Distribution: Configurations for Grocery Stores, Social Places, and other workplaces.
  • Population Demographics: SES-based household positioning, age, family size, and pet ownership distribution.

2. Environmental Layers

  • Safety Layer (safety_cell_layer): Dynamic safety values according to the scenarios influencing route selection.
  • Aesthetic Layer (aesthetic_cell_layer): Center-focused aesthetic value distribution impacting walking preferences.

3. Simulation Scenarios

  • RR (Random-Random): Random distribution of land use and safety values.
  • RS (Random-Safety): Random land use with lower safety in core areas.
  • CR (Centralized-Random): Centralized land use with random safety values.
  • CS (Centralized-Safety): Centralized land use with lower safety in core areas.

4. Agent Characteristics

  • Agents include attributes like walking ability, attitude, employment status, and social networks.
  • Agents dynamically adjust walking attitude based on feedback mechanisms like: walking attitudes of family and friends, safety and aesthetic values, pedestrian density, and total amount walked by the person during that day.
  • Agents decide walking routes and destinations based on proximity, safety, and purpose(basic needs, leisure and work).

5. Behavioral Feedback Mechanisms

  1. Social Influence:

    • Attitudes update based on social connections:
      • Family:
        image
      • Friends:
        image
  2. Walking Experience:

    • Positive walking experiences increase willingness to walk:
      image
  3. Density of Walkers:

    • Feedback depends on the ratio of current walking density to previous density (( I_d )):
      • ( I_d > 1 ): Positive feedback.
      • ( I_d < 1 ): Negative feedback.
  4. Total Distance Walked:

    • Feedback reflects the impact of fatigue:
      image
  5. Daily Attitude Update:

    • Combined feedback updates attitude:
      image

6. Data Collection System

  • The model tracks the following metrics across five SES levels (1-5):
    • Average daily walking trips
    • Work-related trips
    • Basic needs trips (grocery and non-food shopping)
    • Leisure trips (non-purposeful neighborhood walks)

Known Shortcomings

  1. Very slow.
  2. Unable to simulate with recommended grid size (800x800) and human population.
  3. Distribution of values across the safety and aesthetic property layers may not be correct.
  4. Having a dog does not affect the walking attitude, whereas it should.
  5. Wrong results noted:
    • Screenshot 2024-12-26 161405
      to be compared with
    • accumulated_graphs
    • (one day being one step)
    • (attention to be paid to the SES color being different in both the graphs)

@EwoutH
Copy link
Member

EwoutH commented Dec 27, 2024

Looks like quite a serious model!

If you could add to the PR description:

  • A summary / overview of the model
  • Any outstanding questions / considerations

@EwoutH
Copy link
Member

EwoutH commented Dec 28, 2024

Thanks for the extended descriptions.

Have you profiled the model to identify the main performance bottlenecks?

@EwoutH
Copy link
Member

EwoutH commented Dec 28, 2024

@projectmesa/maintainers I’m a bit in doubt on the complexity of this example. On the one hand it shows you can create ABMs with detailed environments and complex behavior, on the other hand I don’t know an example this extended would really benefit our users. I would like to hear some of your stances.

@Sahil-Chhoker
Copy link
Author

Have you profiled the model to identify the main performance bottlenecks?

I haven't, can you tell how can I do that?

@EwoutH
Copy link
Member

EwoutH commented Dec 28, 2024

Some starting point:

Most IDEs also have a profiler built-in.

@Sahil-Chhoker
Copy link
Author

Sahil-Chhoker commented Dec 28, 2024

Here is the table I built from the data collected by the profiler running the model 10 times.

Performance Analysis Results

Function/Method Name NCalls TotTime CumTime %Total
step(agents.py) 4,850 0.019 0.596 74.4%
simulate_daily_walks 4,850 0.033 0.426 53.2%
decide_leisure_walk 4,850 0.092 0.226 28.2%
calculate_distance 185,574 0.093 0.132 16.5%
get_feedback 1,303 0.041 0.128 16.0%
weakref.keys 185,980 0.072 0.113 14.1%
find_nearest_location 2,391 0.010 0.109 13.6%
min (built-in) 5,689 0.018 0.093 11.6%
sum (built-in) 14,770 0.012 0.068 8.5%
lambda (agents.py:135) 17,825 0.018 0.041 5.1%
sqrt (built-in) 190,260 0.039 0.039 4.9%
cell (cell_agent.py) 188,561 0.029 0.029 3.6%

@EwoutH
Copy link
Member

EwoutH commented Dec 28, 2024

Okay, this is quite useful already! It shows that most of the runtime is taken up in the Agent step, and specifically the decision logic.

You can try to speed that up, but if you want I can also give it a try (hopefully tomorrow or Monday).

@Sahil-Chhoker
Copy link
Author

You can try to speed that up, but if you want I can also give it a try (hopefully tomorrow or Monday).

I'll do what I can, but I'm not particularly confident. Can we use caching to prevent duplicate lookups in calculate_distance? I'm also not sure what could speed up the other functions.

@EwoutH
Copy link
Member

EwoutH commented Dec 30, 2024

Hypothesis for model results not correlating with the paper:

  1. Safety and aesthetics are note implemented correctly (check by adding visualisation of PropertyLayers)
  2. Agents are not reading the correct values from the PropertyLayers
  3. Agents are not using the read value correctly in their behavior

@EwoutH
Copy link
Member

EwoutH commented Dec 30, 2024

In theory this should work:

I'll help you visualize both property layers by updating the space component in app.py. We'll create a portrayal dictionary for the property layers that defines a color gradient from transparent to solid blue/green.

Here's how to modify the app.py code. First, add this portrayal dictionary right after the model_params definition:

propertylayer_portrayal = {
    "safety": {
        "color": "blue",
        "alpha": 0.5,
        "colorbar": True
    },
    "aesthetic": {
        "color": "green", 
        "alpha": 0.5,
        "colorbar": True
    }
}

Then update the space_component definition to include the property layers:

space_component = make_space_component(
    agent_portrayal, 
    draw_grid=True, 
    post_process=post_process_space,
    propertylayer_portrayal=propertylayer_portrayal
)

This will:

  1. Draw the safety layer in blue gradient where low values are transparent and high values are solid blue
  2. Draw the aesthetic layer in green gradient where low values are transparent and high values are solid green
  3. Display colorbars for both layers to show the value scale
  4. Set alpha to 0.5 so the layers blend nicely and don't completely obscure agents

The layers will be drawn before the agents, so you'll still be able to see all the agents on top of the colored background created by these layers.

@EwoutH
Copy link
Member

EwoutH commented Dec 30, 2024

@Sahil-Chhoker
Copy link
Author

I have successfully visualized the property layers, and they are functioning as intended. Before moving on to the other points, I reread the paper and realized I had overlooked the concept of households. I will now implement the household concept and check the results again.

@EwoutH
Copy link
Member

EwoutH commented Dec 31, 2024

Awesome, that's amazing to hear! Did you figure out what the bug was or what I missed yesterday?

@EwoutH
Copy link
Member

EwoutH commented Dec 31, 2024

I reread the paper and realized I had overlooked the concept of households. I will now implement the household concept and check the results again.

CC @tpike3, Households sounds like Meta agents. Maybe you could assist here!

@Sahil-Chhoker
Copy link
Author

@EwoutH Unfortunately no, but since they are just a bunch of numpy arrays I exported the data and made some graphs based on the values. I can confirm they are implemented as they are intended.

CC @tpike3, Households sounds like Meta agents. Maybe you could assist here!

I read a bit about MetaAgents, and from my understanding, they are groups of agents that form during the model runtime based on certain properties. While I can see their usefulness, I don’t think they are particularly relevant to this model. This is because the household system is defined during the human placement, and a household is simply the cell where they spawn. Therefore, in my opinion, this can be handled during initialization.

@EwoutH
Copy link
Member

EwoutH commented Dec 31, 2024

Thanks, sounds good!

@Sahil-Chhoker
Copy link
Author

@EwoutH I have a question: is it correct to use model.random everywhere inside the agents' logic? For example, if agents need to find new locations to move to every day, wouldn’t using the same model.random result in the agents walking to the same place they walked the previous day?

@quaquel
Copy link
Member

quaquel commented Dec 31, 2024

it's better to use self.random inside an Agent, so self.random.random() will draw a random number of unit interval. In either case agent.random or model.random just refer to the same seeded python stdlib random.Random instance which is a random number generator so repeated calls will return different numbers.

@Sahil-Chhoker
Copy link
Author

The model has improved significantly with the following changes:

  1. Rewriting the walking behavior to incorporate household positions.
  2. Improving the placement of agents based on their SES.
  3. Scaling the feedback factor by 20 due to its current size.

Tasks to be completed:

  1. Fix the logic for leisure walks.
  2. Review the positioning of agents.

current results for RR:
Screenshot 2024-12-31 184428
observations:

  1. It becomes stable like in the graph from paper.
  2. Distribution by SES is correct.

@Sahil-Chhoker
Copy link
Author

I have thoroughly reviewed the model in every aspect and believe I have covered everything correctly. In my opinion, the only remaining task is to make the model efficient enough to run on an 800x800 grid or decide to keep this simpler model after applying smaller optimizations.

Current Results:
image

Current Profile: Running the model with 20x20 grid and 1350 humans for 10 steps.

Function ncalls tottime percall cumtime percall
_wrapped_step 10 0.000 0.000 2.300 0.230
step 10 0.000 0.000 2.300 0.230
shuffle_do 10 0.023 0.002 2.165 0.217
step (agents) 13,500 0.055 0.000 2.119 0.000
simulate_daily_walks 13,500 0.101 0.000 1.636 0.000
decide_leisure_walk 13,500 0.024 0.000 0.920 0.000
get_leisure_cells 1,208 0.565 0.000 0.885 0.001
init (model) 1 0.000 0.000 0.761 0.761
add_initial_humans 1 0.007 0.007 0.715 0.715
init (agents) 1,350 0.011 0.000 0.687 0.001
get_workplace 1,350 0.245 0.000 0.561 0.000
keys 1,217,553 0.348 0.000 0.415 0.000
find_walkable_locations 8,851 0.038 0.000 0.404 0.000
get_feedback 3,001 0.133 0.000 0.369 0.000
check_near_point 10,022 0.126 0.000 0.254 0.000
sum 49,697 0.038 0.000 0.223 0.000
calculate_distance 368,985 0.137 0.000 0.212 0.000
collect 11 0.001 0.000 0.147 0.013
abs 864,370 0.125 0.000 0.125 0.000
mean 3,001 0.051 0.000 0.117 0.000
get_distance 87,277 0.083 0.000 0.103 0.000

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be nice to add a high-level overview of the (expected) results in this Readme, and maybe a screenshot or two to support that.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Understood!

@EwoutH
Copy link
Member

EwoutH commented Jan 2, 2025

Awesome, I will do a full review this weekend.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants