-
-
Notifications
You must be signed in to change notification settings - Fork 212
examples: add luck vs skill gambling model #322
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
Open
riddhi2106
wants to merge
7
commits into
mesa:main
Choose a base branch
from
riddhi2106:riddhi2106-patch-1
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+146
−0
Open
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
2a9404e
examples: add luck vs skill gambling model
riddhi2106 90f8572
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] 530d679
Fix pre-commit issue
EwoutH c57855b
Move gambling example into examples/gambling and isolate it
b1ed24b
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] 1eaa93d
Update README.md
riddhi2106 98f9885
Revert unintended root README change
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Empty file.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| # Luck vs Skill in Short-Term Gambling | ||
|
|
||
| This example demonstrates how short-term gambling success is dominated by luck, | ||
| even when agents differ in skill. | ||
|
|
||
| ## Model Description | ||
|
|
||
| Each agent has a fixed skill level between 0 and 1. Skill slightly increases the | ||
| probability of winning a bet, but outcomes are still stochastic. | ||
|
|
||
| Agents repeatedly place fixed-size bets. After a short number of rounds, agents | ||
| are ranked by wealth. | ||
|
|
||
| The model compares the average skill of: | ||
| - The top 10% of agents by wealth | ||
| - The bottom 10% of agents by wealth | ||
|
|
||
| ## Key Insight | ||
|
|
||
| Over short horizons, the skill distributions of winners and losers differ only slightly. | ||
| Early success is therefore a poor indicator of true skill. | ||
|
|
||
| This illustrates why gambling success, early trading profits, or beginner's luck | ||
| are often misattributed to ability rather than chance. | ||
|
|
||
| This model demonstrates: | ||
| 1. Beginner’s luck is a real statistical phenomenon | ||
| 2. Early winners are not reliable indicators of skill | ||
| 3. Skill emerges only over long horizons | ||
| 4. Human inference from short samples is systematically biased | ||
|
|
||
| ## How to Run | ||
|
|
||
| ```bash | ||
| solara run app.py |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| from mesa import Agent | ||
|
|
||
|
|
||
| class GamblingAgent(Agent): | ||
| def __init__(self, model, skill, wealth, bet_size): | ||
| super().__init__(model) | ||
| self.skill = skill | ||
| self.wealth = wealth | ||
| self.bet_size = bet_size | ||
|
|
||
| def step(self): | ||
| p_win = 0.5 + self.model.alpha * self.skill | ||
| if self.model.random.random() < p_win: | ||
| self.wealth += self.bet_size | ||
| else: | ||
| self.wealth -= self.bet_size |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| from mesa.visualization import SolaraViz, make_plot_component | ||
| from mesa.visualization.user_param import Slider | ||
| from model.model import LuckVsSkillModel | ||
|
|
||
|
|
||
| def post_process_lines(ax): | ||
| ax.set_xlabel("Simulation Step") | ||
| ax.set_ylabel("Average True Skill") | ||
| ax.set_title("Luck vs Skill in Short-Term Gambling") | ||
| ax.legend() | ||
|
|
||
|
|
||
| COLORS = { | ||
| "Top 10": "#d62728", | ||
| "Bottom 10": "#1f77b4", | ||
| } | ||
|
|
||
|
|
||
| lineplot_component = make_plot_component( | ||
| COLORS, | ||
| post_process=post_process_lines, | ||
| ) | ||
|
|
||
| model = LuckVsSkillModel() | ||
|
|
||
| model_params = { | ||
| "num_agents": 200, | ||
| "alpha": Slider("Skill impact (α)", 0.05, 0.0, 0.2, 0.01), # noqa: RUF001 | ||
| "initial_wealth": 100, | ||
| "bet_size": 1, | ||
| } | ||
|
|
||
| page = SolaraViz( | ||
| model, | ||
| components=[lineplot_component], | ||
| model_params=model_params, | ||
| name="Luck vs Skill: Short-Term Gambling", | ||
| ) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
| from mesa import Model | ||
| from mesa.datacollection import DataCollector | ||
|
|
||
| from .agent import GamblingAgent | ||
|
|
||
|
|
||
| class LuckVsSkillModel(Model): | ||
| def __init__( | ||
| self, | ||
| num_agents=200, | ||
| alpha=0.05, | ||
| initial_wealth=100, | ||
| bet_size=1, | ||
| seed=None, | ||
| ): | ||
| super().__init__(seed=seed) | ||
|
|
||
| self.alpha = alpha | ||
| self.steps = 0 | ||
|
|
||
| # Create agents | ||
| for _ in range(num_agents): | ||
| agent = GamblingAgent( | ||
| model=self, | ||
| skill=self.random.random(), | ||
| wealth=initial_wealth, | ||
| bet_size=bet_size, | ||
| ) | ||
| self.agents.add(agent) | ||
|
|
||
| self.datacollector = DataCollector( | ||
| model_reporters={ | ||
| "Step": lambda m: m.steps, | ||
| "Top 10": self.top_10_skill, | ||
| "Bottom 10": self.bottom_10_skill, | ||
| } | ||
| ) | ||
|
|
||
| def step(self): | ||
| self.steps += 1 | ||
|
|
||
| for agent in list(self.agents): | ||
| agent.step() | ||
|
|
||
| self.datacollector.collect(self) | ||
|
|
||
| def top_10_skill(self): | ||
| agents = sorted(self.agents, key=lambda a: a.wealth) | ||
| k = max(1, int(0.1 * len(agents))) | ||
| top = agents[-k:] | ||
| return sum(a.skill for a in top) / k | ||
|
|
||
| def bottom_10_skill(self): | ||
| agents = sorted(self.agents, key=lambda a: a.wealth) | ||
| k = max(1, int(0.1 * len(agents))) | ||
| bottom = agents[:k] | ||
| return sum(a.skill for a in bottom) / k |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
move to a subfolder,
examples/gambling/for exampleThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for taking the time to review my PR. I’ve moved the example into examples/gambling, restored the main README, and added a dedicated README for the example.