From 5b04da775400539761f9ee5f3c4f1cb2d7eef422 Mon Sep 17 00:00:00 2001 From: Krishna Kishore Buddi Date: Mon, 6 Apr 2026 19:17:33 -0400 Subject: [PATCH 1/2] Clean up causal success tutorial per format rules --- .../.claude/settings.local.json | 12 + .../.dockerignore | 143 ++ .../.gitignore | 1 + .../Causal_Success_API.md | 446 ---- .../Dockerfile | 53 +- .../README.md | 332 +-- .../__init__.py | 1 + ...s_of_Success_in_60_minutes.how_to_guide.md | 158 ++ ...ess_API.ipynb => causal_success.API.ipynb} | 556 ++--- ...l_success_API.py => causal_success.API.py} | 209 +- .../causal_success.example.ipynb | 1326 ++++++++++ ...s_example.py => causal_success.example.py} | 542 ++-- .../causal_success_example.ipynb | 2224 ----------------- .../causal_success_example.md | 526 ---- .../causal_success_tutorial.md | 291 --- .../causal_success_utils.py | 373 ++- .../conftest.py | 14 + .../docker_bash.sh | 21 +- .../docker_build.sh | 13 +- .../docker_clean.sh | 6 +- .../docker_cmd.sh | 31 +- .../docker_exec.sh | 6 +- .../docker_jupyter.sh | 69 +- .../docker_push.sh | 6 +- .../requirements.txt | 33 +- .../run_jupyter.sh | 70 +- .../test/test_docker_all.py | 48 + .../test_causal_success_utils.py | 488 ++-- 28 files changed, 2877 insertions(+), 5121 deletions(-) create mode 100644 research/A_Causal_Analysis_of_Success_in_Modern_Society/.claude/settings.local.json create mode 100644 research/A_Causal_Analysis_of_Success_in_Modern_Society/.dockerignore delete mode 100644 research/A_Causal_Analysis_of_Success_in_Modern_Society/Causal_Success_API.md create mode 100644 research/A_Causal_Analysis_of_Success_in_Modern_Society/__init__.py create mode 100644 research/A_Causal_Analysis_of_Success_in_Modern_Society/all.learn_Causal_Analysis_of_Success_in_60_minutes.how_to_guide.md rename research/A_Causal_Analysis_of_Success_in_Modern_Society/{causal_success_API.ipynb => causal_success.API.ipynb} (60%) rename research/A_Causal_Analysis_of_Success_in_Modern_Society/{causal_success_API.py => causal_success.API.py} (82%) create mode 100644 research/A_Causal_Analysis_of_Success_in_Modern_Society/causal_success.example.ipynb rename research/A_Causal_Analysis_of_Success_in_Modern_Society/{causal_success_example.py => causal_success.example.py} (67%) delete mode 100644 research/A_Causal_Analysis_of_Success_in_Modern_Society/causal_success_example.ipynb delete mode 100644 research/A_Causal_Analysis_of_Success_in_Modern_Society/causal_success_example.md delete mode 100644 research/A_Causal_Analysis_of_Success_in_Modern_Society/causal_success_tutorial.md create mode 100644 research/A_Causal_Analysis_of_Success_in_Modern_Society/conftest.py create mode 100644 research/A_Causal_Analysis_of_Success_in_Modern_Society/test/test_docker_all.py diff --git a/research/A_Causal_Analysis_of_Success_in_Modern_Society/.claude/settings.local.json b/research/A_Causal_Analysis_of_Success_in_Modern_Society/.claude/settings.local.json new file mode 100644 index 000000000..50971c39e --- /dev/null +++ b/research/A_Causal_Analysis_of_Success_in_Modern_Society/.claude/settings.local.json @@ -0,0 +1,12 @@ +{ + "permissions": { + "allow": [ + "Bash(ls -lh /c/Users/kisho/gpsaggese.github.io/tutorials/Autogen/*.ipynb)", + "Bash(xargs grep:*)", + "Bash(python -c 'import json; f=open\\('\\\\''causal_success.API.ipynb'\\\\'','\\\\''r'\\\\'',encoding='\\\\''utf-8'\\\\''\\); nb=json.load\\(f\\); f.close\\(\\); changed=False:*)", + "Bash(python _fix_refs.py)", + "Bash(rm _fix_refs.py)", + "Bash(ls *.ipynb *.py)" + ] + } +} diff --git a/research/A_Causal_Analysis_of_Success_in_Modern_Society/.dockerignore b/research/A_Causal_Analysis_of_Success_in_Modern_Society/.dockerignore new file mode 100644 index 000000000..fd85b2584 --- /dev/null +++ b/research/A_Causal_Analysis_of_Success_in_Modern_Society/.dockerignore @@ -0,0 +1,143 @@ +# Exclude files from Docker build context. This prevents unnecessary files from +# being sent to Docker daemon, reducing build time and image size. + +# Python artifacts +__pycache__/ +*.pyc +*.pyo +*.pyd +*.egg-info/ + +# Virtual environments +venv/ +.venv/ +env/ +.env +.envrc +client_venv.helpers/ +ENV/ + +# Jupyter +.ipynb_checkpoints/ +.jupyter/ + +# Build artifacts +build/ +dist/ +*.eggs/ +.eggs/ + +# Cache and temporary files +*.log +*.tmp +*.cache +.pytest_cache/ +.mypy_cache/ +.coverage +htmlcov/ + +# Git and version control +.git/ +.gitignore +.gitattributes +.github/ + +# Docker build scripts (not needed at runtime) +docker_build.sh +docker_push.sh +docker_clean.sh +docker_exec.sh +docker_cmd.sh +docker_bash.sh +docker_jupyter.sh +docker_name.sh +run_jupyter.sh +Dockerfile.* +.dockerignore + +# Documentation +README.md +README.admin.md +docs/ +*.md +CHANGELOG.md +LICENSE + +# Configuration and secrets +.env.* +.env.local +.env.development +.env.production +.DS_Store +Thumbs.db + +# Shell configuration +.bashrc +.bash_history +.zshrc + +# Large data files (mount via volume instead) +data/ +*.csv +*.pkl +*.h5 +*.parquet +*.feather +*.arrow +*.npy +*.npz + +# Generated images +*.png +*.jpg +*.jpeg +*.gif +*.svg +*.pdf + +# Test files and examples +tests/ +test_* +*_test.py +tutorials/ +examples/ + +# IDE and editor files +.vscode/ +.idea/ +*.swp +*.swo +*~ +.project +.pydevproject +.settings/ +*.iml +.sublime-project +.sublime-workspace + +# Node and frontend (if applicable) +node_modules/ +npm-debug.log +yarn-error.log +.npm + +# Requirements management +requirements.in +Pipfile +Pipfile.lock +poetry.lock +setup.py +setup.cfg + +# CI/CD configuration +.gitlab-ci.yml +.travis.yml +Jenkinsfile +.circleci/ + +# Miscellaneous +*.bak +.venv.bak/ +*.whl +*.tar.gz +*.zip diff --git a/research/A_Causal_Analysis_of_Success_in_Modern_Society/.gitignore b/research/A_Causal_Analysis_of_Success_in_Modern_Society/.gitignore index 8378f2dc8..0fbd9cc2b 100644 --- a/research/A_Causal_Analysis_of_Success_in_Modern_Society/.gitignore +++ b/research/A_Causal_Analysis_of_Success_in_Modern_Society/.gitignore @@ -12,6 +12,7 @@ env/ # ---- Jupyter Notebooks ---- .ipynb_checkpoints/ +Untitled*.ipynb # ---- Logs and Text Output ---- *.log diff --git a/research/A_Causal_Analysis_of_Success_in_Modern_Society/Causal_Success_API.md b/research/A_Causal_Analysis_of_Success_in_Modern_Society/Causal_Success_API.md deleted file mode 100644 index 87f74dd6b..000000000 --- a/research/A_Causal_Analysis_of_Success_in_Modern_Society/Causal_Success_API.md +++ /dev/null @@ -1,446 +0,0 @@ -# Causal Success Analysis: API Documentation - -## Overview - -This document explains the core functions and classes in -`causal_success_utils.py`. If you're new to the project, this is where you'll -learn what each function does and how to use it. The code implements an -agent-based simulation where a population of individuals (agents) experience -random events over time. - -Think of this as the technical manual. For a step-by-step walkthrough of the -complete analysis, check out `causal_success_example.md` instead. For a -higher-level narrative and motivation, see `causal_success_tutorial.md`. - -## The Agent Class - -In our case, an agent represents a person with certain abilities and resources. - -### What an Agent Contains - -Each agent has four main attributes that define their talents: - -- **Intensity**: how active someone is. Higher intensity means more exposure to - opportunities and risks. Think of it like surface area for luck: the more - you're out there doing things, the more chances you have to encounter events - (both good and bad). -- **IQ**: ability to capitalize on opportunities. When a lucky event happens, - this determines whether the agent can actually take advantage of it. Not every - opportunity works out, even when it appears. -- **Networking**: social connections. This lets beneficial events sometimes - spill over to others. If you know the right people, you might catch - opportunities that weren't directly aimed at you. -- **Initial Capital**: starting wealth. We usually set this to `1.0` for - everyone so that inequality emerges from the simulation dynamics, not from - inherited advantages. - -Beyond these talents, each agent tracks: - -- `capital`: current wealth -- `capital_history`: list of capital values over time -- `lucky_events` and `unlucky_events`: event counts - -### Creating a Single Agent - - ```python - from causal_success_utils import Agent - - # Create an Agent with Specific Talents - person = Agent( - agent_id=0, - intensity=0.6, # Pretty active (range: 0 to 1) - iq=0.7, # Good at seizing opportunities - networking=0.5, # Average connections - initial_capital=1.0 - ) - - print(person.talent) - # {'intensity': 0.6, 'iq': 0.7, 'networking': 0.5, 'initial_capital': 1.0} - - prob = person.get_event_probability() - print(f"Event exposure probability: {prob:.3f}") - # Event Exposure Probability: 0.648 - ``` - -Event exposure probability is computed via a sigmoid centered at 0.5, so -intensity values above 0.5 lead to above-average exposure and vice versa. - -### Applying Events to Agents - -Events change an agent's capital through **multiplication**, not addition. This -is what creates compounding effects. - - ```python - # Apply a lucky event (25% gain) - person.apply_event("lucky", 0.25) - print(f"Capital after lucky event: ${person.capital:.2f}") - # Capital after lucky event: $1.25 - - # Apply an unlucky event (15% loss) - person.apply_event("unlucky", 0.15) - print(f"Capital after unlucky event: ${person.capital:.2f}") - # Capital after unlucky event: $1.06 - - print(person.lucky_events, person.unlucky_events) - # 1 1 - ``` - -A 25% gain on $1 is $0.25, but a 25% gain on $100 is $25. This multiplicative -process is what drives inequality over time. - -## Population Functions - -### `create_population` - - ```python - from causal_success_utils import create_population - - agents = create_population(n_agents=100, seed=42) - print(f"Population size: {len(agents)}") - # Population size: 100 - ``` - -**Behavior:** - -- Generates `n_agents` agents -- `intensity`, `iq`, and `networking` are drawn from `N(0.5, 0.15)` and clipped - to `[0, 1]` -- `initial_capital` defaults to `1.0` for everyone - -**Parameters:** - -- `n_agents: int`: number of agents -- `seed: int`: RNG seed for reproducibility - -## Running the Simulation - -### `run_simulation` - -This is the core engine that moves the system forward over time. - -```python -from causal_success_utils import run_simulation, create_population - -agents = create_population(n_agents=100, seed=42) - -agents = run_simulation( - agents=agents, - n_periods=80, - n_lucky_events_per_period=5, - n_unlucky_events_per_period=5, - lucky_mean=0.25, - lucky_std=0.08, - unlucky_mean=0.15, - unlucky_std=0.05, - seed=42, - verbose=True -) - -print("Simulation complete!") -print(f"Final capital range: ${min(a.capital for a in agents):.2f} " - f"to ${max(a.capital for a in agents):.2f}") -``` - -**High-level logic per period:** - -- For each lucky event: - 1. Compute exposure probabilities from `get_event_probability()` - (intensity-based) - 2. Select an agent at random, weighted by exposure - 3. Draw an impact (percent gain), clipped between 5% and 50% - 4. With probability equal to the agent's `iq`, apply the multiplicative gain - 5. With 10% probability, spill over to another agent, weighted by `networking` - and gated by their `iq` - -- For each unlucky event: - 1. Same exposure mechanism - 2. Draw impact (percent loss), clipped between 5% and 30% - 3. Apply multiplicative loss to capital, floored at `0.01` - -**Key parameters:** - -- `n_periods`: number of time periods -- `n_lucky_events_per_period`, `n_unlucky_events_per_period` -- `lucky_mean`, `lucky_std`, `unlucky_mean`, `unlucky_std`: mean and std of - event magnitudes -- `seed`: RNG seed -- `verbose`: if `True`, uses `tqdm` to show a progress bar (if available) - -### `run_policy_simulation` - -Adds an initial resource allocation step before running the standard simulation. - -```python -from causal_success_utils import create_population, run_policy_simulation - -agents = create_population(n_agents=100, seed=42) - -agents = run_policy_simulation( - agents=agents, - policy="egalitarian", - resource_amount=100.0, - n_periods=80, - seed=42 -) -``` - -**Policies:** - -- `"egalitarian"`: equal split of `resource_amount` across agents -- `"meritocratic"`: resources proportional to `talent_norm` -- `"performance"`: resources proportional to current capital (rich-get-richer) -- `"random"`: one randomly chosen agent receives all the resources -- `"cate_optimal"`: resources proportional to (non-negative) CATE estimates - passed in cate_values -- **Arguments:** - -- `agents: List[Agent]`: population of agents to allocate resources to and then - simulate -- `policy: str`: one of `"egalitarian"`, `"meritocratic"`, `"performance"`, - `"random"`, or `"cate_optimal"` -- `resource_amount: float`: total resource budget to distribute at time 0 -- `cate_values: Optional[np.ndarray]`: required when `policy="cate_optimal"`; - 1D array of CATE estimates (one per agent) -- `**simulation_kwargs`: additional keyword arguments passed through to - `run_simulation` (e.g., `n_periods`, `seed`, etc.) - -## Analysis Functions - -### `calculate_gini` - -Compute the Gini coefficient of a non-negative 1D array. - - ```python - from causal_success_utils import calculate_gini - import numpy as np - - capital_values = np.array([1.5, 2.0, 8.5, 12.3, 25.7]) - gini = calculate_gini(capital_values) - print(f"Gini coefficient: {gini:.3f}") - ``` - -Returns a float in `[0, 1]`. - -### `get_results_dataframe` - -Convert a list of agents into a tidy `pandas.DataFrame`: - - ```python - from causal_success_utils import get_results_dataframe - - df = get_results_dataframe(agents) - print(df.head()) - print(df.columns) - ``` - -Columns include: - -- `id` -- `talent_intensity`, `talent_iq`, `talent_networking` -- `initial_capital` -- `talent_norm` -- `capital` -- `lucky_events`, `unlucky_events`, `net_events` - -### `generate_summary_statistics` - -Compute key summary statistics from the simulation: - - ```python - from causal_success_utils import generate_summary_statistics - - stats = generate_summary_statistics(agents) - for key, value in stats.items(): - print(f"{key:25s}: {value:.4f}") - ``` - -Includes: - -- `n_agents` -- `mean_capital`, `median_capital`, `std_capital` -- `min_capital`, `max_capital`, `capital_range` -- `gini_coefficient` -- `top_10_pct_share`, `top_20_pct_share`, `bottom_50_pct_share` -- `mean_lucky_events`, `mean_unlucky_events` -- `mean_talent_norm` - -### `validate_simulation_results` - -Basic sanity checks on the simulation output: - -```python -from causal_success_utils import validate_simulation_results - -try: - validate_simulation_results(agents) - print("All checks passed.") -except ValueError as e: - print("Validation failed:", e) -``` - -Checks: - -- No negative capital -- No NaN values -- Non-negative event counts -- Capital history length is consistent with total events per agent - -## Complete Example Workflow - - ```python - import numpy as np - import pandas as pd - from causal_success_utils import ( - create_population, - run_simulation, - get_results_dataframe, - calculate_gini, - generate_summary_statistics, - validate_simulation_results, - ) - - agents = create_population(n_agents=100, seed=42) - agents = run_simulation(agents, n_periods=80, seed=42, verbose=True) - - validate_simulation_results(agents) - - df = get_results_dataframe(agents) - gini = calculate_gini(df["capital"].values) - stats = generate_summary_statistics(agents) - - print("Gini:", gini) - print("Top 10% share:", stats["top_10_pct_share"]) - ``` - -## Bayesian Inference API - -In addition to the simulation and descriptive statistics, the project includes a -**Bayesian regression layer** that estimates the effect of luck on log-capital -while controlling for talent. - -All Bayesian functions live in `causal_success_utils.py` and rely on **PyMC** -and **ArviZ**. - -### Overview of the Model - -The Bayesian model is a linear regression on the log of final capital: - -\[ \log(\text{capital}\_i) = \alpha - -- \beta\_{\text{luck}} \cdot \text{lucky_events}\_i -- \beta\_{\text{intensity}} \cdot \text{talent_intensity}\_i -- \beta\_{\text{iq}} \cdot \text{talent_iq}\_i -- \beta\_{\text{networking}} \cdot \text{talent_networking}\_i -- \varepsilon_i \] - -- `beta_luck` Is the Primary Quantity of Interest: the (Log-Scale) Effect of - One additional lucky event, holding talent constant. -- Priors Are Weakly Informative, Centered at 0. - -### `fit_bayesian_luck_model` - - ```python - from causal_success_utils import ( - create_population, - run_simulation, - get_results_dataframe, - fit_bayesian_luck_model, - ) - - # Simulate Data - agents = create_population(n_agents=100, seed=42) - agents = run_simulation(agents, n_periods=80, seed=42) - df = get_results_dataframe(agents) - - # Fit Bayesian Model - model, idata = fit_bayesian_luck_model( - df, - draws=1000, - tune=1000, - target_accept=0.9, - random_seed=42, - ) - ``` - -**Arguments:** - -- `df: pd.DataFrame`: output from `get_results_dataframe` -- `draws: int`: posterior draws per chain (default 1000) -- `tune: int`: warm-up / burn-in iterations (default 1000) -- `target_accept: float`: NUTS target acceptance rate (default 0.9) -- `random_seed: int`: random seed - -**Returns:** - -- `model`: PyMC model object -- `idata`: ArviZ `InferenceData` with posterior samples - -> Note: If PyMC or ArviZ are not installed, this function will raise an -> `ImportError`. - -### `summarize_bayesian_fit` - -Get a tidy summary table (posterior mean, standard deviation, and credible -intervals) for the main parameters. - -```python -from causal_success_utils import summarize_bayesian_fit - -summary = summarize_bayesian_fit(idata) -print(summary) -``` - -By default, it summarizes: - -- `alpha` -- `beta_luck` -- `beta_intensity` -- `beta_iq` -- `beta_networking` -- `sigma` - -You can also pass a custom `var_names` list if you want to restrict the summary. - -### `posterior_predictive_check` - -Run a basic posterior predictive check (PPC) by simulating log-capital from the -model and comparing to the observed log-capital. - - ```python - from causal_success_utils import posterior_predictive_check - - ppc_results = posterior_predictive_check(model, idata, df) - - y_obs = ppc_results["y_obs"] - y_pred_mean = ppc_results["y_pred_mean"] - y_pred_std = ppc_results["y_pred_std"] - - print("Observed log-capital (first 5):", y_obs[:5]) - print("Predicted mean log-capital (first 5):", y_pred_mean[:5]) - ``` - -**Returns a dictionary with:** - -- `"y_obs"`: observed log-capital -- `"y_pred_mean"`: posterior predictive mean log-capital per agent -- `"y_pred_std"`: posterior predictive standard deviation per agent - -This is useful for checking how well the model captures the distribution of -outcomes. - -## When to Use What - -- Use the **simulation functions** (`create_population`, `run_simulation`, - `run_policy_simulation`) to generate data and explore how talent and luck - interact in the model world. -- Use the **summary and inequality functions** (`get_results_dataframe`, - `generate_summary_statistics`, `calculate_gini`) to quantify emergent patterns - (inequality, top shares, etc.). -- Use the **Bayesian functions** (`fit_bayesian_luck_model`, - `summarize_bayesian_fit`, `posterior_predictive_check`) when you want: - - A principled posterior over the effect of luck, - - Credible intervals around effect sizes, - - And basic model checking via posterior predictive simulations. - -Together, these APIs give you a complete pipeline from simulation → descriptive -analysis → causal and Bayesian inference. diff --git a/research/A_Causal_Analysis_of_Success_in_Modern_Society/Dockerfile b/research/A_Causal_Analysis_of_Success_in_Modern_Society/Dockerfile index 6c7fc012c..f5c02c562 100644 --- a/research/A_Causal_Analysis_of_Success_in_Modern_Society/Dockerfile +++ b/research/A_Causal_Analysis_of_Success_in_Modern_Society/Dockerfile @@ -1,53 +1,30 @@ -FROM ubuntu:24.04 -ENV DEBIAN_FRONTEND noninteractive +# Use Python 3.12 slim (already has Python and pip). +FROM python:3.12-slim -RUN apt-get -y update -RUN apt-get -y upgrade +# Avoid interactive prompts during apt operations. +ENV DEBIAN_FRONTEND=noninteractive -# Install system utilities. -RUN apt install -y --no-install-recommends \ - sudo \ - curl \ - systemctl \ - gnupg \ - git \ - vim - -# Install Python and build deps (venv requires python3-venv on Debian/Ubuntu). -RUN apt-get update && apt-get install -y --no-install-recommends \ - build-essential \ - python3 \ - python3-pip \ - python3-dev \ - python3-venv \ +# Install CA certificates (needed for HTTPS). +RUN apt-get update && apt-get install -y \ + ca-certificates \ && rm -rf /var/lib/apt/lists/* -# Create virtual environment. -RUN python3 -m venv /venv - -# Make the venv the default Python. -ENV PATH="/venv/bin:$PATH" - -# Upgrade pip inside the venv. -RUN python -m pip install --upgrade pip - -# Install Jupyter. -RUN pip3 install jupyterlab - # Install project specific packages. -COPY requirements.txt requirements.txt -RUN pip3 install -r requirements.txt - -RUN mkdir /install +RUN mkdir -p /install +COPY requirements.txt /install/requirements.txt +RUN pip install --upgrade pip && \ + pip install --no-cache-dir jupyterlab jupyterlab_vim jupytext -r /install/requirements.txt # Config. -ADD etc_sudoers /install/ +COPY etc_sudoers /install/ COPY etc_sudoers /etc/sudoers COPY bashrc /root/.bashrc # Report package versions. -ADD version.sh /install/ +COPY version.sh /install/ RUN /install/version.sh 2>&1 | tee version.log # Jupyter. EXPOSE 8888 + +CMD ["/bin/bash"] diff --git a/research/A_Causal_Analysis_of_Success_in_Modern_Society/README.md b/research/A_Causal_Analysis_of_Success_in_Modern_Society/README.md index 1ba6ca1b9..e80879bfe 100644 --- a/research/A_Causal_Analysis_of_Success_in_Modern_Society/README.md +++ b/research/A_Causal_Analysis_of_Success_in_Modern_Society/README.md @@ -1,322 +1,34 @@ # A Causal Analysis of Success in Modern Society -**Author:** Krishna Kishore Buddi -**Course:** MSML610 – Modern Statistical Machine Learning -**Instructor:** Prof. GP Saggese +This project simulates talent-versus-luck dynamics in an agent-based model and +uses causal inference to quantify how much luck actually drives inequality. -## 1. Abstract +## Quick Start -Why do measures of success—such as wealth, academic influence, or professional -recognition—exhibit extreme inequality, while underlying human abilities appear -broadly similar? This project explores that question using an agent-based -simulation combined with modern causal inference techniques. +Build the image and launch Jupyter from the project directory. -We model success as a **multiplicative stochastic process** shaped by both -talent and random events, then apply **Double Machine Learning (DML)** and -**Causal Forests** to estimate the causal effect of "luck" while controlling for -talent. A small **Bayesian regression** extension provides posterior uncertainty -for the estimated luck effect. Across runs, the analysis shows that stochastic -factors exert a much stronger influence on long-run outcomes than modest talent -differences alone. These findings challenge simple meritocratic narratives and -inform policy design and opportunity allocation. +```bash +cd research/A_Causal_Analysis_of_Success_in_Modern_Society +./docker_build.sh +./docker_jupyter.sh +``` -## 2. Motivation +For Docker build-system details, see the +[project template README](../../class_project/project_template/README.md). -Human traits such as intelligence, effort, and creativity tend to cluster around -average values, often resembling **normal distributions**. In contrast, outcomes -such as income, citations, and firm size follow **highly skewed, heavy-tailed -distributions**, where a small minority accumulates a disproportionate share of -total "success." +## Notebooks -This mismatch suggests that success is shaped by more than just individual -merit. Understanding how randomness interacts with **compounding dynamics** -helps explain why inequality emerges so reliably, even when starting conditions -are similar and talent differences are relatively modest. +Work through the notebooks in the order listed below. -## 3. Research Question and Hypothesis +1. [`causal_success.API.ipynb`](causal_success.API.ipynb) walks through every + building block on its own: the Agent class, the simulation engine, Gini + metrics, policy simulation, and the Bayesian inference helpers. +2. [`causal_success.example.ipynb`](causal_success.example.ipynb) runs the + full pipeline end to end, including DML and Causal Forest estimation and + a comparison of five allocation strategies. -**Core question** +Reusable logic lives in [`causal_success_utils.py`](causal_success_utils.py). -> Why does success follow a power-law–like distribution when human talent -> appears roughly normally distributed? +## Changelog -**Hypothesis** - -Random **multiplicative events** play a larger _causal_ role in determining -long-term success than talent differentials alone. Because gains and losses -compound over time, small stochastic differences—especially early in life—can -generate large divergences in outcomes. - -## 4. Model Overview - -### 4.1 Agents - -We simulate a population of **100 agents**. Each agent (i) has four attributes -in [0, 1]: - -- **Intensity** – sustained effort and activity level. - Higher intensity → higher probability of encountering events (good and bad). - -- **IQ** – ability to capitalize on beneficial opportunities. - IQ does not create opportunities, but gates whether an agent can convert a - good event into a gain. - -- **Networking** – social connectivity. - Modulates the chance that a good event "spills over" to another agent, - representing referrals and informal networks. - -- **Initial Capital** – starting resources. - Set to 1.0 for all agents in the baseline, so inequality arises _endogenously_ - from dynamics rather than initial wealth. - -All talent attributes are drawn from N(0.5, 0.15) and **clipped to [0, 1]** to -avoid unrealistic extremes. - -### 4.2 Event Process and Dynamics - -The simulation runs for **80 time periods**. In each period: - -1. A fixed number of **beneficial ("lucky")** and **detrimental ("unlucky")** - events is generated. -2. Events are assigned probabilistically; exposure probability is a sigmoid - function of intensity. -3. When a beneficial event hits an agent: - - With probability equal to the agent's IQ, it is successfully exploited. - - Capital is updated multiplicatively: C\_{t+1} = C_t(1 + Δ_lucky) -4. When a detrimental event hits an agent: - - Capital is updated multiplicatively: C\_{t+1} = C_t(1 - Δ_unlucky) - - Capital is floored at a small positive value (e.g., 0.01) to avoid collapse - to exactly zero. -5. **Networking spillovers**: a fraction of lucky events generate secondary, - smaller boosts for other agents, allocated in proportion to networking - scores. - -Event magnitudes are drawn from normal distributions and clipped to realistic -ranges (e.g., lucky impacts ~25% ± 8%, unlucky impacts ~15% ± 5%). - -## 5. Analysis Pipeline - -The analysis is organized into the following steps: - -1. **Descriptive statistics and inequality measures** - - Distribution of final capital - - Gini coefficient - - Top/bottom wealth shares - - Correlations between talent, luck, and log(capital) - -2. **Top performer inspection** - - Compare top-decile agents to the population in terms of talent and - experienced lucky events. - - Typical finding: top agents are not always the most "talented," but they - tend to have many more lucky events. - -3. **Double Machine Learning (DML)** - - Outcome: log(final capital) - - Treatment: number of lucky events - - Controls: talent vector (intensity, IQ, networking) - - Use DML to estimate the **causal effect** of lucky events while controlling - flexibly for confounding. - - Robust pattern: each additional lucky event increases final capital by - roughly **10–15%**, conditional on talent. - -4. **Causal Forests (heterogeneous treatment effects)** - - Use Causal Forests to estimate **Conditional Average Treatment Effects - (CATEs)**. - - Examine how the effect of luck varies with agent features (e.g., IQ, - networking). - - This informs which agents benefit most from an additional opportunity. - -5. **Bayesian regression (optional extension)** - - Fit a Bayesian regression model: log(C_final) ~ alpha + beta_luck _ - lucky_events + beta_int _ intensity + beta_iq _ iq + beta_net _ - networking + epsilon - - Implemented with **PyMC** and summarized via **ArviZ**. - - Provides a posterior distribution for the luck effect (beta_luck) with - credible intervals. - -## 6. Policy Experiments - -The project also compares different one-shot **resource allocation policies** -using the simulation as a sandbox. - -### Implemented Policies (`run_policy_simulation`) - -- **Egalitarian** - Equal share of a fixed budget for every agent. - -- **Meritocratic** - Resources allocated in proportion to a talent summary (e.g., norm of the - talent vector). - -- **Performance-based** - Allocation proportional to current capital (rich-get-richer). - -- **Random** - A random agent receives the full budget. - -- **CATE-optimal** - Resources allocated proportionally to **non-negative CATE estimates** from the - Causal Forest. Implemented via `policy="cate_optimal"` in - `run_policy_simulation`, with `cate_values` passed as an argument. - -### Qualitative Findings - -Across runs, we typically see: - -- **Egalitarian** reduces inequality but may slightly reduce total output - compared to targeted schemes. -- **Performance-based** amplifies inequality substantially and can concentrate - gains in already advantaged agents. -- **Meritocratic** often lies between egalitarian and performance-based in both - inequality and efficiency. -- **Random** can perform surprisingly well as a baseline. -- **CATE-optimal** tends to maximize total output by directing resources to - agents who are estimated to benefit the most from an extra opportunity. - -These trade-offs illustrate how policy design interacts with multiplicative -dynamics and randomness. - -## 7. Repository Structure - -Key files in the project: - -- **Core utilities** - - `causal_success_utils.py` Main toolbox: - - Agent class and simulation engine - - Inequality metrics and summary statistics - - `run_policy_simulation` with multiple allocation rules (including - `cate_optimal`) - - Bayesian regression helpers (PyMC + ArviZ) - -- **API documentation** - - `causal_success.API.md` Textual API specification: functions, arguments, and - example usage. - - `causal_success.API.ipynb` Notebook version of the API walkthrough with - runnable examples. - -- **Example analysis** - - `causal_success.example.md` Narrative, end-to-end example: simulation → DML - → Causal Forest → policy comparison. - - `causal_success.example.ipynb` The corresponding notebook with all code and - plots. - -- **Tutorial / theory** - - `causal_success_tutorial.md` Higher-level explanation of the modeling - choices, theory, and connections to real-world inequality. - -- **Environment / infrastructure** - - `requirements.txt` Python dependencies (NumPy, pandas, scikit-learn, econml, - pymc, arviz, etc.). - - `Dockerfile` Reproducible environment for running the notebooks. - - `docker_build.sh`, `docker_jupyter.sh`, `run_jupyter.sh` Convenience scripts - for building the image and launching Jupyter Lab inside the container. - -- **Top-level** - - `README.md` (this file) - -## 8. Setup and Reproducibility - -The project targets **Python 3.10** and is designed to be fully reproducible -with **Docker**. You can either use Docker (recommended for clean grading) or a -local Python environment. - -### 8.1 Using Docker (Recommended) - -1. **Build the image** - - From the project root: - - ```bash - ./docker_build.sh - ``` - -2. **Launch Jupyter Lab inside the container** - - Depending on your scripts, use either: - - ```bash - ./docker_jupyter.sh - ``` - - or - - ```bash - ./run_jupyter.sh - ``` - -3. **Open the notebook UI** - - Copy the Jupyter URL printed in the terminal (usually - `http://127.0.0.1:8888/...`) - - Open it in your browser. - - Navigate to `causal_success.API.ipynb` or `causal_success.example.ipynb`. - -All code, including simulations, causal models, and policy experiments, can be -run end-to-end from within the container. - -### 8.2 Local Python Environment (Optional) - -If you prefer not to use Docker: - -1. Create and activate a virtual environment (example with `venv`): - - ```bash - python3 -m venv .venv - source .venv/bin/activate # on Windows: .venv\Scriptsctivate - ``` - -2. Install dependencies: - - ```bash - pip install -r requirements.txt - ``` - -3. Start Jupyter Lab: - - ```bash - jupyter lab - ``` - -4. Open the notebooks as above. - -## 9. How to Use the Project - -A typical workflow: - -1. **Explore the API** - - Open `causal_success.API.ipynb`. - - Inspect how to: - - Create a population, - - Run the simulation, - - Compute inequality, - - Use `run_policy_simulation`, - - Run the Bayesian model. - -2. **Run the main analysis** - - Open `causal_success.example.ipynb`. - - Execute cells in order: - - Simulate a baseline run, - - Examine inequality, - - Run DML and Causal Forest, - - Generate CATE-optimal allocations, - - Compare policy outcomes. - -3. **Dive into theory** - - Read `causal_success_tutorial.md` for the narrative and theoretical - context. - -## 10. Limitations and Extensions - -This is a **stylized model** intended to isolate a core mechanism: - -- It does **not** explicitly model structural barriers, institutions, or - strategic behavior. -- Talent is static; in reality, success and failure feed back into skills and - opportunities. -- Opportunity structures and shocks are simplified. - -Natural extensions include: - -- Endogenous talent evolution over time. -- Richer network structures and community effects. -- More realistic opportunity processes calibrated to empirical data. -- Policy experiments with multi-period interventions and constraints. +2026-04-05: Cleanup pass against tutorial format rules. 2026-02-25: Initial release. diff --git a/research/A_Causal_Analysis_of_Success_in_Modern_Society/__init__.py b/research/A_Causal_Analysis_of_Success_in_Modern_Society/__init__.py new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/research/A_Causal_Analysis_of_Success_in_Modern_Society/__init__.py @@ -0,0 +1 @@ + diff --git a/research/A_Causal_Analysis_of_Success_in_Modern_Society/all.learn_Causal_Analysis_of_Success_in_60_minutes.how_to_guide.md b/research/A_Causal_Analysis_of_Success_in_Modern_Society/all.learn_Causal_Analysis_of_Success_in_60_minutes.how_to_guide.md new file mode 100644 index 000000000..3641aa4b7 --- /dev/null +++ b/research/A_Causal_Analysis_of_Success_in_Modern_Society/all.learn_Causal_Analysis_of_Success_in_60_minutes.how_to_guide.md @@ -0,0 +1,158 @@ +--- +title: "Causal Analysis of Success in 60 Minutes" +authors: + - KrishnaKishoreBuddi + - gpsaggese +date: 2026-02-25 +description: > + Build an agent-based simulation that turns normally-distributed talent into + power-law outcomes, then use DML and Causal Forests to prove luck is the + dominant driver. Implements the framework from Saggese (2025). +categories: + - Causal Inference + - Agent-Based Modeling +--- + +TL;DR: If everyone starts roughly equal in ability, why do a handful of people +end up wildly more successful than everyone else? This tutorial builds a +simulation to reproduce that pattern, then uses causal ML to prove that luck, +not talent, is the dominant driver. You can run the whole thing in 60 minutes. + + + +## What You Will Build + +This tutorial implements the simulation and causal analysis from +[Saggese (2025), *A Causal Analysis of Skill and Luck in Agent Outcomes*](https://github.com/gpsaggese/gpsaggese.github.io/blob/master/papers/Causal_Analysis_of_Agent_Skill_And_Luck/Causal_Analysis_of_Agent_Skill_And_Luck.pdf). +By the end you will have a working agent-based simulation with $N = 100$ +agents, talent vectors $T_i \in [0,1]^4$, and multiplicative capital evolution +$C_{i,t+1} = C_{i,t}(1 + \Delta)$ running over $T = 200$ periods. You will +produce a DML estimate showing that each lucky event causes roughly $12.7\%$ +higher final capital ($\hat{\tau} = 0.12$) after controlling for talent +confounders, along with CATE estimates from Causal Forests that show IQ +moderates the treatment effects ($\rho = 0.41$). Five resource allocation +policies (egalitarian, meritocratic, performance-based, random, CATE-optimal) +are compared side by side, and the notebook optionally closes with Bayesian +posterior distributions as a robustness check. + +## What You Will Need + +All you really need is Docker (recommended) or Python 3.10+ with `pip`, about +60 minutes of focused time, and no prior causal inference background. The +notebooks explain everything from scratch. + +To get started: + +```bash +cd research/A_Causal_Analysis_of_Success_in_Modern_Society +./docker_build.sh +./docker_jupyter.sh +``` + +Then open the notebooks in order. Start with `causal_success.API.ipynb` to +understand the building blocks, and move on to `causal_success.example.ipynb` +for the full analysis. + +## The Idea in 30 Seconds + +Human abilities, things like intelligence, effort, and creativity, cluster +around the middle. But wealth, citations, and company sizes don't. They follow +extreme power laws where a tiny fraction of people hold most of the total. + +The paper defines luck formally as $L_A(E) = U_A(E) \cdot S(E|I_A) \cdot (1 - +C_A(E))$, combining utility, surprise (rarity), and lack of control. This +tutorial shows that **multiplicative compounding** is the mechanism that turns +modest luck differences into massive outcome gaps. The simulation demonstrates +the dynamic, and the causal analysis confirms it. The variance decomposition +comes out to roughly $0.08$ (talent) $+ 0.67$ (luck) $+ 0.25$ (interaction). + +## Background Reading + +Four sources are worth having open alongside the notebooks. Saggese (2025), +["A Causal Analysis of Skill and Luck in Agent Outcomes"](https://github.com/gpsaggese/gpsaggese.github.io/blob/master/papers/Causal_Analysis_of_Agent_Skill_And_Luck/Causal_Analysis_of_Agent_Skill_And_Luck.pdf), +provides the theoretical framework that this tutorial implements. Pluchino, +Biondo & Rapisarda (2018), +["Talent versus Luck"](https://doi.org/10.1142/S0219525918500145), is the paper +that inspired the original simulation design. Chernozhukov et al. (2018), +["Double/Debiased Machine Learning"](https://doi.org/10.1111/ectj.12097), lays +out the econometric method behind the DML estimates. Finally, the +[EconML documentation](https://econml.azurewebsites.net/) covers the Microsoft +library that powers the DML and Causal Forest fits here. + +## What Is In the Tutorial + +Everything lives in `research/A_Causal_Analysis_of_Success_in_Modern_Society/`. +The core library is `causal_success_utils.py`, which contains the Agent class, +the simulation engine, Gini and inequality metrics, the policy simulation, +wrappers around DML and Causal Forest fitting, the policy comparison function, +and the Bayesian regression helpers. The walkthrough notebook +`causal_success.API.ipynb` demos each of these pieces in isolation with small, +self-contained examples, while `causal_success.example.ipynb` runs the full +analysis from start to finish. Docker setup (`Dockerfile`, `docker_build.sh`, +`docker_jupyter.sh`) is included for one-command reproducibility. + +## What Happens in `causal_success.example.ipynb` + +### Part 1: Building the World and Watching Inequality Emerge + +We create $N = 100$ agents with talent vectors $T_i$ drawn from truncated +$\mathcal{N}(0.5, 0.15^2)$ distributions and identical starting capital +$C_{i,0} = 1.0$. Over $T = 200$ periods, random events hit agents with exposure +probability $q_i = \sigma(\alpha(t_i^{(1)} - 0.5))$ and change capital +multiplicatively. Even though everyone starts equal, final capital spans orders +of magnitude. The Gini coefficient reaches roughly $0.38$, and the top 10% end +up holding around $28\%$ of total capital. + +The punchline is stark. Top performers have a median talent rank of about +$52/100$ (i.e., perfectly average), yet they experienced $8.3$ lucky events +versus the population mean of $4.8$. + +### Part 2: Proving It Causally and Testing Policies + +Correlation isn't enough on its own, because talent confounds luck. The +paper's causal model (Section 6.8) specifies the treatment as +$T_i =$ lucky events, the outcome as $Y_i = \log(C_{i,T})$, and the +confounders as $X_i = (t_i^{(1)}, t_i^{(2)}, t_i^{(3)})$. DML yields +$\hat{\tau} = 0.12$ ($e^{0.12} \approx 12.7\%$ per event), with tight +confidence intervals. Naive OLS overstates the effect at $0.156$ because +residual confounding isn't removed. + +Causal Forests then estimate heterogeneous effects, with mean CATE $= 0.12$ +and $\sigma = 0.03$, and IQ moderates the treatment effects at $\rho = 0.41$. +The CATE-optimal allocation policy uses those estimates to target resources +via $R_i \propto \max(0, \hat{\tau}(X_i))$. + +The policy comparison (Table 5 in the paper) shows CATE-optimal achieving the +highest total welfare ($921$), while performance-based allocation is dominated +on both efficiency and equity. That's a cautionary finding for institutions +that reward past success without adjusting for luck. + +## Key Takeaways + +The variance decomposition ($67\%$ luck, $8\%$ talent, $25\%$ interaction) +puts numbers on something that had mostly been intuition. Among reasonably +capable agents, luck is the dominant differentiator of outcomes. + +For individuals, increasing exposure ($t_i^{(1)}$) raises the event encounter +rate through the sigmoid mechanism. But outcomes retain a large stochastic +component, which is exactly why the paper's luck formalism suggests some +humility about success. + +For policymakers, CATE-optimal targeting maximizes total welfare. +Performance-based allocation, the "back the winners" rule, is dominated on +both dimensions, and egalitarian allocation provides a robust alternative when +estimation is noisy. + +For researchers, the tutorial demonstrates how agent-based simulation combined +with causal inference can validate theoretical frameworks against known +ground-truth causal structure (Section 6.10 of the paper). + +## What Is Next + +This tutorial covers the core simulation from Section 6 of the paper. Natural +extensions include talent evolution equations, explicit network graph +structures, calibration to empirical wealth or citation distributions, and +multi-period policy interventions. All of these are discussed in Section 6.11 +of the paper. + +Now go run the notebooks and see it for yourself. diff --git a/research/A_Causal_Analysis_of_Success_in_Modern_Society/causal_success_API.ipynb b/research/A_Causal_Analysis_of_Success_in_Modern_Society/causal_success.API.ipynb similarity index 60% rename from research/A_Causal_Analysis_of_Success_in_Modern_Society/causal_success_API.ipynb rename to research/A_Causal_Analysis_of_Success_in_Modern_Society/causal_success.API.ipynb index 99b5c98db..074b681db 100644 --- a/research/A_Causal_Analysis_of_Success_in_Modern_Society/causal_success_API.ipynb +++ b/research/A_Causal_Analysis_of_Success_in_Modern_Society/causal_success.API.ipynb @@ -6,29 +6,55 @@ "source": [ "# Causal Success Analysis: API Demonstration\n", "\n", - "**Purpose:** Introduce and explore each core function in isolation before moving\n", - "on to the full analysis.\n", + "**Purpose:** Introduce and explore each core function in isolation before moving on to the full analysis.\n", "\n", - "This notebook is meant to be a hands-on walkthrough of the building blocks\n", - "behind the project. We import the simulation code and experiment with each\n", - "component one at a time to understand what it does and why it matters.\n", + "This notebook is meant to be a hands-on walkthrough of the building blocks behind the project. We import the simulation code and experiment with each component one at a time to understand what it does and why it matters.\n", "\n", - "If you’re interested in seeing how all of these pieces come together in a\n", - "complete analysis—simulation, causal inference, and policy comparison—take a\n", - "look at `causal_success_example.ipynb`.\n", + "If you’re interested in seeing how all of these pieces come together in a complete analysis—simulation, causal inference, and policy comparison—take a look at `causal_success.example.ipynb`.\n", "\n", - "You can think of this notebook as getting familiar with the individual tools\n", - "before using them together in a full workflow.\n" + "You can think of this notebook as getting familiar with the individual tools before using them together in a full workflow." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## When to Use What\n", + "\n", + "The **simulation functions** (`create_population`, `run_simulation`,\n", + "`run_policy_simulation`) are how you generate data and explore the interaction\n", + "between talent and luck inside the model world. Once you have a simulation in\n", + "hand, the **summary and inequality functions** (`get_results_dataframe`,\n", + "`generate_summary_statistics`, `calculate_gini`) quantify the emergent\n", + "patterns such as inequality and top shares.\n", + "\n", + "When you want a principled posterior over the effect of luck, credible\n", + "intervals around the effect sizes, or basic model checking via posterior\n", + "predictive simulations, reach for the **Bayesian functions**\n", + "(`fit_bayesian_luck_model`, `summarize_bayesian_fit`,\n", + "`posterior_predictive_check`).\n", + "\n", + "Taken together, these APIs form a complete pipeline from **simulation** to\n", + "**descriptive analysis** to **causal and Bayesian inference**." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Setup: Import Everything\n", + "\n", + "First we need to bring in the functions we're going to demonstrate." ] }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "%load_ext autoreload\n", - "%autoreload 2\n", + "# %load_ext autoreload\n", + "# %autoreload 2\n", "\n", "import logging\n", "import sys\n", @@ -45,37 +71,38 @@ }, { "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "WARNING:pytensor.tensor.blas:Using NumPy C-API based implementation for BLAS functions.\n" - ] - } - ], - "source": [ - "# TODO(ai_gp): Use `import causal_success_utils as csu` and change the callers.\n", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Ensure the project module is importable (works locally and in Docker).\n", + "project_root = Path.cwd()\n", + "\n", + "if (project_root / \"causal_success_utils.py\").exists():\n", + " sys.path.insert(0, str(project_root))\n", + "elif Path(\"/app/causal_success_utils.py\").exists():\n", + " sys.path.insert(0, \"/app\")\n", + "\n", + "# Import simulation components.\n", "from causal_success_utils import (\n", " Agent,\n", " create_population,\n", " run_simulation,\n", " run_policy_simulation,\n", + " run_policy_and_measure,\n", " calculate_gini,\n", " get_results_dataframe,\n", " generate_summary_statistics,\n", " validate_simulation_results,\n", ")\n", "\n", - "# # Plotting configuration.\n", + "# Plotting configuration.\n", "# %matplotlib inline\n", - "# plt.style.use(\"seaborn-v0_8-darkgrid\")\n", + "plt.style.use(\"seaborn-v0_8-darkgrid\")\n", "\n", - "# _LOG.info(\"Environment configured successfully\")\n", - "# _LOG.info(\"NumPy version: %s\", np.__version__)\n", - "# _LOG.info(\"Pandas version: %s\", pd.__version__)" + "_LOG.info(\"Environment configured successfully\")\n", + "_LOG.info(\"NumPy version: %s\", np.__version__)\n", + "_LOG.info(\"Pandas version: %s\", pd.__version__)" ] }, { @@ -84,47 +111,33 @@ "source": [ "## Demo 1: Creating a Single Agent\n", "\n", - "Let’s create one simulated person and take a quick look at their starting traits and stat.\n" + "Let’s create one simulated person and take a quick look at their starting traits and stats." ] }, { "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Agent ID: 0\n", - "Talent profile:\n", - " intensity : 0.700\n", - " iq : 0.600\n", - " networking : 0.400\n", - " initial_capital : 1.000\n", - "Starting capital: $1.00\n", - "Talent norm (combined ability): 1.418\n", - "Event exposure probability: 0.599\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "# Create a single agent with chosen talent levels\n", "person = Agent(\n", " agent_id=0,\n", - " # High activity / exposure.\n", - " intensity=0.7, \n", - " # Moderately good at exploiting opportunities.\n", - " iq=0.6, \n", - " # Below-average social reach.\n", - " networking=0.4, \n", + " intensity=0.7, # High activity / exposure\n", + " iq=0.6, # Moderately good at exploiting opportunities\n", + " networking=0.4, # Below-average social reach\n", " initial_capital=1.0,\n", ")\n", - "print(f\"Agent ID: {person.id}\")\n", - "print(\"Talent profile:\")\n", + "\n", + "print(\"Agent created successfully\")\n", + "\n", + "print(f\"\\nAgent ID: {person.id}\")\n", + "\n", + "print(\"\\nTalent profile:\")\n", "for name, value in person.talent.items():\n", " print(f\" {name:18s}: {value:.3f}\")\n", - "print(f\"Starting capital: ${person.capital:.2f}\")\n", + "\n", + "print(f\"\\nStarting capital: ${person.capital:.2f}\")\n", "print(f\"Talent norm (combined ability): {person.talent_norm:.3f}\")\n", "print(f\"Event exposure probability: {person.get_event_probability():.3f}\")" ] @@ -135,17 +148,9 @@ "source": [ "**What to notice:**\n", "\n", - "The event exposure probability is computed using a sigmoid function of the\n", - "agent’s intensity. With an intensity of 0.7, this agent has **above-average\n", - "exposure** to events, resulting in an exposure probability of about **0.60**. An\n", - "agent with lower intensity (for example, 0.3) would have noticeably less\n", - "exposure, while higher intensity values push the probability closer to 1.\n", + "The event exposure probability is computed using a sigmoid function of the agent’s intensity. With an intensity of 0.7, this agent has **above-average exposure** to events, resulting in an exposure probability of about **0.60**. An agent with lower intensity (for example, 0.3) would have noticeably less exposure, while higher intensity values push the probability closer to 1.\n", "\n", - "The talent norm is simply the Euclidean norm of the talent vector (intensity,\n", - "IQ, networking, and initial capital). It provides a single summary measure of\n", - "overall capability. This value is useful for analysis and comparison, but it\n", - "does not directly determine success on its own—outcomes still depend heavily on\n", - "the sequence of events the agent experienes." + "The talent norm is simply the Euclidean norm of the talent vector (intensity, IQ, networking, and initial capital). It provides a single summary measure of overall capability. This value is useful for analysis and comparison, but it does not directly determine success on its own—outcomes still depend heavily on the sequence of events the agent experiences." ] }, { @@ -154,42 +159,14 @@ "source": [ "## Demo 2: Applying Events to an Agent\n", "\n", - "Next, we’ll apply a few lucky and unlucky events to the same agent and watch how their capital change.\n" + "Next, we’ll apply a few lucky and unlucky events to the same agent and watch how their capital changes." ] }, { "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Starting capital: $1.00\n", - "\n", - "Applying a lucky event (30% gain)...\n", - "Capital after lucky event: $1.30\n", - "\n", - "Applying an unlucky event (20% loss)...\n", - "Capital after unlucky event: $1.04\n", - "\n", - "Applying another lucky event (25% gain)...\n", - "Final capital: $1.30\n", - "\n", - "Event summary:\n", - " Lucky events: 2\n", - " Unlucky events: 1\n", - " Net events: 1\n", - "\n", - "Capital history:\n", - " Step 0: $1.00\n", - " Step 1: $1.30\n", - " Step 2: $1.04\n", - " Step 3: $1.30\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "print(f\"Starting capital: ${person.capital:.2f}\")\n", "\n", @@ -225,7 +202,7 @@ "\n", "Because each change is a percentage of the current capital, the **order and timing of events matter**. Early gains raise the base on which future gains and losses are calculated, while early setbacks shrink it.\n", "\n", - "Over many periods, this compounding effect can produce large differences in outcomes, even when agents start with identical resources and similar abilties.\n" + "Over many periods, this compounding effect can produce large differences in outcomes, even when agents start with identical resources and similar abilities." ] }, { @@ -234,37 +211,14 @@ "source": [ "## Demo 3: Creating a Population\n", "\n", - "So far we’ve looked at a single individual. Now we’ll scale things up and create a small population of agents, each with randomly assigned talents drawn from the same underlying distribution.\n" + "So far we’ve looked at a single individual. Now we’ll scale things up and create a small population of agents, each with randomly assigned talents drawn from the same underlying distribution." ] }, { "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Created 20 agents\n", - "\n", - "First 5 agents:\n", - " ID Intensity IQ Networking Capital\n", - "++++++++++++++++++++++++++++++++++++++++++++++++++\n", - " 0 0.546 0.344 0.613 $ 1.00\n", - " 1 0.641 0.207 0.305 $ 1.00\n", - " 2 0.519 0.453 0.497 $ 1.00\n", - " 3 0.372 0.632 0.617 $ 1.00\n", - " 4 0.510 0.669 0.570 $ 1.00\n", - "\n", - "Intensity statistics:\n", - " Mean: 0.527\n", - " Std: 0.120\n", - " Min: 0.371\n", - " Max: 0.821\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "# Create a small population\n", "agents = create_population(n_agents=20, seed=42)\n", @@ -300,7 +254,7 @@ "\n", "Each talent dimension is drawn independently from a normal distribution with mean 0.5 and standard deviation 0.15, then clipped to stay within the \\([0, 1]\\) range. As expected, most values cluster near 0.5 with moderate spread, which is reflected in the summary statistics above.\n", "\n", - "At this point, all agents still have exactly \\$1.00 in capital. There is variation in *potential* (talents), but no variation in *outcomes* yet. Any inequality that appears later will be the result of how random events interact with these talents over time, not differences in starting weath.\n" + "At this point, all agents still have exactly \\$1.00 in capital. There is variation in *potential* (talents), but no variation in *outcomes* yet. Any inequality that appears later will be the result of how random events interact with these talents over time, not differences in starting wealth." ] }, { @@ -309,37 +263,14 @@ "source": [ "## Demo 4: Running a Short Simulation\n", "\n", - "Now we’ll let the population evolve over time. We’ll run a short simulation with 20 agents over 10 periods to see how differences in outcomes begin to emerge.\n" + "Now we’ll let the population evolve over time. We’ll run a short simulation with 20 agents over 10 periods to see how differences in outcomes begin to emerge." ] }, { "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Running simulation: 20 agents, 10 periods...\n", - "\n", - "Simulation complete!\n", - "\n", - "After 10 periods:\n", - " ID Capital Lucky Unlucky Net\n", - "++++++++++++++++++++++++++++++++++++++++\n", - " 0 $ 0.87 0 1 -1\n", - " 1 $ 1.00 1 2 -1\n", - " 2 $ 1.63 4 1 3\n", - " 3 $ 0.76 0 2 -2\n", - " 4 $ 0.73 0 2 -2\n", - "\n", - "Capital range: $0.46 to $1.63\n", - "Mean capital: $0.97\n", - "Spread: 3.5x\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "# Run a short simulation\n", "print(\"Running simulation: 20 agents, 10 periods...\\n\")\n", @@ -381,7 +312,7 @@ "\n", "These differences are driven primarily by **event histories**. For example, Agent 2 experienced several more lucky than unlucky events and ended up well ahead of the population mean, while Agents 3 and 4 encountered multiple unlucky events and fell behind. The mean capital remains close to \\$1.00, indicating that gains by some agents are largely offset by losses elsewhere.\n", "\n", - "This short run illustrates the core mechanism of the model: random events, combined with multiplicative updates, quickly generate dispersion in outcomes. While inequality is still limited at this horizon, extending the simulation in time or increasing event frequency amplifies these differences substantially, which motivates the longer simulations examined later in the anaysis.\n" + "This short run illustrates the core mechanism of the model: random events, combined with multiplicative updates, quickly generate dispersion in outcomes. While inequality is still limited at this horizon, extending the simulation in time or increasing event frequency amplifies these differences substantially, which motivates the longer simulations examined later in the analysis." ] }, { @@ -390,28 +321,14 @@ "source": [ "## Demo 5: Calculating the Gini Coefficient\n", "\n", - "To quantify how unequal the outcomes have become, we use the **Gini coefficient**, a standard measure of inequality widely used in economics and social scienc.\n" + "To quantify how unequal the outcomes have become, we use the **Gini coefficient**, a standard measure of inequality widely used in economics and social science." ] }, { "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Gini coefficient: 0.117\n", - "\n", - "Interpretation:\n", - " → Relatively equal distribution\n", - "\n", - "Gini if everyone had equal capital: 0.000\n", - "Gini if one person had everything: 0.950\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "# Get capital values\n", "capital_values = np.array([a.capital for a in agents])\n", @@ -450,7 +367,7 @@ "\n", "In this short simulation, the Gini coefficient is **0.117**, indicating that outcomes are still relatively equal. This is expected given the small number of periods and events. Inequality has begun to emerge, but it remains modest at this stage.\n", "\n", - "As the simulation runs for more periods, the Gini coefficient typically increases. In longer runs (for example, 80 periods), values often rise into the **0.35–0.45** range, reflecting how multiplicative gains and losses compound over time to produce much stronger inequality.\n" + "As the simulation runs for more periods, the Gini coefficient typically increases. In longer runs (for example, 80 periods), values often rise into the **0.35–0.45** range, reflecting how multiplicative gains and losses compound over time to produce much stronger inequality." ] }, { @@ -464,45 +381,9 @@ }, { "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "First few rows:\n", - "\n", - " id talent_intensity talent_iq talent_networking initial_capital \\\n", - "0 0 0.545708 0.344002 0.612568 1.0 \n", - "1 1 0.641085 0.207345 0.304673 1.0 \n", - "2 2 0.519176 0.452564 0.497480 1.0 \n", - "3 3 0.372043 0.631910 0.616669 1.0 \n", - "4 4 0.509905 0.669086 0.570126 1.0 \n", - "\n", - " talent_norm capital lucky_events unlucky_events net_events \n", - "0 1.338422 0.873118 0 1 -1 \n", - "1 1.243707 0.996856 1 2 -1 \n", - "2 1.312190 1.633899 4 1 3 \n", - "3 1.384921 0.761320 0 2 -2 \n", - "4 1.425736 0.727726 0 2 -2 \n", - "\n", - "DataFrame shape: (20, 10)\n", - "Columns: ['id', 'talent_intensity', 'talent_iq', 'talent_networking', 'initial_capital', 'talent_norm', 'capital', 'lucky_events', 'unlucky_events', 'net_events']\n", - "\n", - "Basic statistics:\n", - " capital talent_norm lucky_events unlucky_events\n", - "count 20.000000 20.000000 20.000000 20.00000\n", - "mean 0.971058 1.347600 0.900000 1.50000\n", - "std 0.229353 0.069652 1.020836 1.60591\n", - "min 0.463628 1.230724 0.000000 0.00000\n", - "25% 0.858491 1.301778 0.000000 0.75000\n", - "50% 1.000000 1.363339 1.000000 1.00000\n", - "75% 1.051030 1.395831 1.000000 2.00000\n", - "max 1.633899 1.441477 4.000000 6.00000\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "# Convert to DataFrame\n", "df = get_results_dataframe(agents)\n", @@ -528,12 +409,12 @@ "\n", "Representing the simulation results as a DataFrame makes patterns much easier to see and analyze. Each row corresponds to a single agent, and each column captures either a talent attribute, an event count, or a final outcome.\n", "\n", - "From the summary statistics, we can already observe several important facts. Average capital remains close to \\$1 00, which is consistent with gains and losses roughly balancing out over this short run. At the same time, there is meaningful dispersion: some agents accumulated over \\$1.60 after experiencing multiple lucky events, while others suffered repeated unlucky events and fell below \\$0.50.\n", + "From the summary statistics, we can already observe several important facts. Average capital remains close to \\$1.00, which is consistent with gains and losses roughly balancing out over this short run. At the same time, there is meaningful dispersion: some agents accumulated over \\$1.60 after experiencing multiple lucky events, while others suffered repeated unlucky events and fell below \\$0.50.\n", "\n", "Using a DataFrame allows us to compute correlations, rank agents by outcomes,\n", "and prepare the data for causal analysis methods in later sections. These\n", "operations would be cumbersome and error-prone if we worked directly with\n", - "lists of agent objects.\n" + "lists of agent objects." ] }, { @@ -544,39 +425,14 @@ "\n", "Rather than calculating each metric by hand, we can use a helper function that summarizes the entire simulation in one step.\n", "\n", - "This function returns all the key quantities you would typically report: inequality measures, distributional statistics, and average event counts. It provides a quick snapshot of how the system evolved and is especially useful when comparing multiple simulation runs or policy scenaros.\n" + "This function returns all the key quantities you would typically report: inequality measures, distributional statistics, and average event counts. It provides a quick snapshot of how the system evolved and is especially useful when comparing multiple simulation runs or policy scenarios." ] }, { "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Complete Summary Statistics:\n", - "\n", - "==================================================\n", - "n_agents : 20.000\n", - "mean_capital : 0.971\n", - "median_capital : 1.000\n", - "std_capital : 0.224\n", - "min_capital : 0.464\n", - "max_capital : 1.634\n", - "capital_range : 3.5x\n", - "gini_coefficient : 11.7%\n", - "top_10_pct_share : 14.6%\n", - "top_20_pct_share : 26.0%\n", - "bottom_50_pct_share : 42.4%\n", - "mean_lucky_events : 0.900\n", - "mean_unlucky_events : 1.500\n", - "mean_talent_norm : 1.348\n", - "==================================================\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "# Generate comprehensive statistics\n", "stats = generate_summary_statistics(agents)\n", @@ -603,7 +459,7 @@ "\n", "The Gini coefficient of approximately 0.12 indicates low overall inequality at this stage, which is expected given the short time horizon. However, wealth concentration is already visible: the top 10% of agents hold about 15% of total capital, while the bottom half collectively holds just over 40%.\n", "\n", - "These statistics illustrate an important feature of the model: inequality does not appear all at once. Instead, it accumulates gradually as random events compound over time. In longer simulations, the same dynamics lead to substantially higher inequality, even though the underlying talent distribution remains unchnged.\n" + "These statistics illustrate an important feature of the model: inequality does not appear all at once. Instead, it accumulates gradually as random events compound over time. In longer simulations, the same dynamics lead to substantially higher inequality, even though the underlying talent distribution remains unchanged." ] }, { @@ -616,28 +472,14 @@ "\n", "Specifically, it confirms that capital values never become negative, that no missing or undefined values appear, and that event counts align correctly with each agent’s recorded history. These checks help catch subtle bugs that might otherwise go unnoticed but could invalidate downstream analysis.\n", "\n", - "While this step does not change the results, it provides confidence that the simulation outputs are internally consistent and safe to use for statistical and causal anaysis.\n" + "While this step does not change the results, it provides confidence that the simulation outputs are internally consistent and safe to use for statistical and causal analysis." ] }, { "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "All validation checks passed!\n", - "\n", - "Checks performed:\n", - " • No negative capital values\n", - " • No NaN values\n", - " • Event counts are positive\n", - " • Capital history length matches events\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "# Validate results\n", "try:\n", @@ -662,75 +504,28 @@ "\n", "The goal here is not to declare a single “best” policy, but to illustrate how different allocation rules interact with the same underlying dynamics. By comparing outcomes across policies, we can see how initial resource distribution shapes inequality, efficiency, and opportunity over time.\n", "\n", - "In this demo, we compare two simple approaches:\n", - "- **Egalitarian allocation**, where resources are distributed equally to all agents\n", - "- **Meritocratic allocation**, where resources are distributed in proportion to measured talent\n", - "\n", - "Both policies are followed by the same stochastic simulation, allowing us to isolate the effect of the allocation rue itself.\n" + "This demo compares two simple approaches. **Egalitarian allocation**\n", + "distributes resources equally to all agents, while **meritocratic allocation**\n", + "distributes them in proportion to measured talent. Both policies are followed\n", + "by the same stochastic simulation, so the only thing we're changing is the\n", + "allocation rule itself." ] }, { "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Testing egalitarian allocation...\n", - "\n" - ] - }, - { - "ename": "AttributeError", - "evalue": "module 'helpers.hdbg' has no attribute 'dassert_le'", - "output_type": "error", - "traceback": [ - "\u001b[31m---------------------------------------------------------------------------\u001b[39m", - "\u001b[31mAttributeError\u001b[39m Traceback (most recent call last)", - "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[11]\u001b[39m\u001b[32m, line 27\u001b[39m\n\u001b[32m 23\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m df, calculate_gini(df[\u001b[33m\"\u001b[39m\u001b[33mcapital\u001b[39m\u001b[33m\"\u001b[39m].values)\n\u001b[32m 26\u001b[39m \u001b[38;5;28mprint\u001b[39m(\u001b[33m\"\u001b[39m\u001b[33mTesting egalitarian allocation...\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[33m\"\u001b[39m)\n\u001b[32m---> \u001b[39m\u001b[32m27\u001b[39m df_equal, gini_equal = \u001b[43mrun_policy\u001b[49m\u001b[43m(\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43megalitarian\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[32m 28\u001b[39m \u001b[38;5;28mprint\u001b[39m(\u001b[33m\"\u001b[39m\u001b[33mEgalitarian policy:\u001b[39m\u001b[33m\"\u001b[39m)\n\u001b[32m 29\u001b[39m \u001b[38;5;28mprint\u001b[39m(\u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33m Final Gini: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mgini_equal\u001b[38;5;132;01m:\u001b[39;00m\u001b[33m.3f\u001b[39m\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m\"\u001b[39m)\n", - "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[11]\u001b[39m\u001b[32m, line 21\u001b[39m, in \u001b[36mrun_policy\u001b[39m\u001b[34m(policy_name, cate_values)\u001b[39m\n\u001b[32m 18\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[33m\"\u001b[39m\u001b[33mcate_values must be provided for \u001b[39m\u001b[33m'\u001b[39m\u001b[33mcate_optimal\u001b[39m\u001b[33m'\u001b[39m\u001b[33m.\u001b[39m\u001b[33m\"\u001b[39m)\n\u001b[32m 19\u001b[39m kwargs[\u001b[33m\"\u001b[39m\u001b[33mcate_values\u001b[39m\u001b[33m\"\u001b[39m] = cate_values\n\u001b[32m---> \u001b[39m\u001b[32m21\u001b[39m agents = \u001b[43mrun_policy_simulation\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 22\u001b[39m df = get_results_dataframe(agents)\n\u001b[32m 23\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m df, calculate_gini(df[\u001b[33m\"\u001b[39m\u001b[33mcapital\u001b[39m\u001b[33m\"\u001b[39m].values)\n", - "\u001b[36mFile \u001b[39m\u001b[32m/curr_dir/causal_success_utils.py:474\u001b[39m, in \u001b[36mrun_policy_simulation\u001b[39m\u001b[34m(agents, policy, resource_amount, cate_values, **simulation_kwargs)\u001b[39m\n\u001b[32m 429\u001b[39m \u001b[38;5;250m\u001b[39m\u001b[33;03m\"\"\"\u001b[39;00m\n\u001b[32m 430\u001b[39m \u001b[33;03mAllocate initial resources under a policy, then run the standard simulation.\u001b[39;00m\n\u001b[32m 431\u001b[39m \n\u001b[32m (...)\u001b[39m\u001b[32m 471\u001b[39m \u001b[33;03m:return: Same agents list after resource allocation and full simulation\u001b[39;00m\n\u001b[32m 472\u001b[39m \u001b[33;03m\"\"\"\u001b[39;00m\n\u001b[32m 473\u001b[39m hdbg.dassert(agents, \u001b[33m\"\u001b[39m\u001b[33magents list cannot be empty\u001b[39m\u001b[33m\"\u001b[39m)\n\u001b[32m--> \u001b[39m\u001b[32m474\u001b[39m hdbg.dassert_lt(\n\u001b[32m 475\u001b[39m -\u001b[32m0.0001\u001b[39m, resource_amount, \u001b[33m\"\u001b[39m\u001b[33mresource_amount must be non-negative\u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m 476\u001b[39m )\n\u001b[32m 477\u001b[39m n = \u001b[38;5;28mlen\u001b[39m(agents)\n\u001b[32m 478\u001b[39m rng = np.random.default_rng(simulation_kwargs.get(\u001b[33m\"\u001b[39m\u001b[33mseed\u001b[39m\u001b[33m\"\u001b[39m, \u001b[38;5;28;01mNone\u001b[39;00m))\n", - "\u001b[31mAttributeError\u001b[39m: module 'helpers.hdbg' has no attribute 'dassert_le'" - ] - } - ], - "source": [ - "N = 20\n", - "SEED = 123\n", - "RESOURCE = 20.0\n", - "N_PERIODS = 10\n", - "\n", - "\n", - "def run_policy(policy_name: str, cate_values=None):\n", - " agents = create_population(n_agents=N, seed=SEED)\n", - " kwargs = dict(\n", - " agents=agents,\n", - " policy=policy_name,\n", - " resource_amount=RESOURCE,\n", - " n_periods=N_PERIODS,\n", - " seed=SEED,\n", - " )\n", - " if policy_name == \"cate_optimal\":\n", - " if cate_values is None:\n", - " raise ValueError(\"cate_values must be provided for 'cate_optimal'.\")\n", - " kwargs[\"cate_values\"] = cate_values\n", - "\n", - " agents = run_policy_simulation(**kwargs)\n", - " df = get_results_dataframe(agents)\n", - " return df, calculate_gini(df[\"capital\"].values)\n", - "\n", - "\n", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ "print(\"Testing egalitarian allocation...\\n\")\n", - "df_equal, gini_equal = run_policy(\"egalitarian\")\n", + "df_equal, gini_equal = run_policy_and_measure(\"egalitarian\")\n", "print(\"Egalitarian policy:\")\n", "print(f\" Final Gini: {gini_equal:.3f}\")\n", "print(f\" Mean capital: ${df_equal['capital'].mean():.2f}\")\n", "print(f\" Total capital: ${df_equal['capital'].sum():.2f}\")\n", "\n", "print(\"\\nTesting meritocratic allocation...\\n\")\n", - "df_merit, gini_merit = run_policy(\"meritocratic\")\n", + "df_merit, gini_merit = run_policy_and_measure(\"meritocratic\")\n", "print(\"Meritocratic policy:\")\n", "print(f\" Final Gini: {gini_merit:.3f}\")\n", "print(f\" Mean capital: ${df_merit['capital'].mean():.2f}\")\n", @@ -764,7 +559,7 @@ "\n", "However, a modest difference appears in inequality. The egalitarian policy produces a slightly lower Gini coefficient than the meritocratic policy, indicating a more even distribution of outcomes. This suggests that allocating resources uniformly at the outset dampens early divergence, even when subsequent growth remains multiplicative and stochastic.\n", "\n", - "At the same time, the total capital generated under both policies is nearly identical, indicating that reduced inequality in this setting does not come at a substantial efficiency cost. Because this result comes from a single run with one random seed and a short time horizon, it should be interpreted as illustrative rather than conclusive. Robust policy evaluation would require averaging outcomes across many simulaions.\n" + "At the same time, the total capital generated under both policies is nearly identical, indicating that reduced inequality in this setting does not come at a substantial efficiency cost. Because this result comes from a single run with one random seed and a short time horizon, it should be interpreted as illustrative rather than conclusive. Robust policy evaluation would require averaging outcomes across many simulations." ] }, { @@ -775,7 +570,7 @@ "\n", "Numbers summarize outcomes, but visualizations make the distributional effects easier to grasp. In this final demo, we create a simple plot of final capital values to see how outcomes spread across agents.\n", "\n", - "Even in short simulations, these plots often reveal early signs of skewness, with a small number of agents pulling ahead while others fall behind. This visual perspective complements the numerical inequality measures shown earler.\n" + "Even in short simulations, these plots often reveal early signs of skewness, with a small number of agents pulling ahead while others fall behind. This visual perspective complements the numerical inequality measures shown earlier." ] }, { @@ -845,31 +640,29 @@ "\n", "Specifically, we covered:\n", "\n", - "1. Creating individual agents with well-defined talent attributes \n", - "2. Applying lucky and unlucky events using multiplicative dynamics \n", - "3. Generating populations with realistically distributed talents \n", - "4. Running simulations over time with configurable parameters \n", - "5. Measuring inequality using standard metrics such as the Gini coefficient \n", - "6. Converting simulation results into DataFrames for efficient analysis \n", - "7. Producing comprehensive summary statistics in a single step \n", - "8. Validating simulation outputs to ensure internal consistency \n", - "9. Comparing alternative policy-based resource allocation rules \n", - "10. Visualizing talent, capital, and luck to understand distributional patterns \n", + "1. Creating individual agents with well-defined talent attributes\n", + "2. Applying lucky and unlucky events using multiplicative dynamics\n", + "3. Generating populations with realistically distributed talents\n", + "4. Running simulations over time with configurable parameters\n", + "5. Measuring inequality using standard metrics such as the Gini coefficient\n", + "6. Converting simulation results into DataFrames for efficient analysis\n", + "7. Producing comprehensive summary statistics in a single step\n", + "8. Validating simulation outputs to ensure internal consistency\n", + "9. Comparing alternative policy-based resource allocation rules\n", + "10. Visualizing talent, capital, and luck to understand distributional patterns\n", "\n", "Together, these demos illustrate how simple stochastic mechanisms, when compounded over time, can generate unequal outcomes even from nearly identical starting conditions.\n", "\n", - "---\n", - "\n", "### Next steps\n", "\n", - "To see all of these components working together in a full analysis pipeline, open **`causal_success_example.ipynb`**, which integrates simulation, statistical analysis, and causal inference end to end.\n", + "To see all of these components working together in a full analysis pipeline, open **`causal_success.example.ipynb`**, which integrates simulation, statistical analysis, and causal inference end to end.\n", "\n", - "For detailed technical documentation of the underlying functions and classes, refer to **`causal_success_API.md`**.\n", + "For detailed technical documentation of the underlying functions and classes, refer to **`causal_success_utils.py`**.\n", "\n", "For the broader motivation, theoretical background, and interpretation of results, see **`README.md`**.\n", "\n", "You now have a clear understanding of the individual pieces. The next notebook\n", - "shows how they fit together.\n" + "shows how they fit together." ] }, { @@ -878,13 +671,12 @@ "source": [ "## Bayesian Inference API\n", "\n", - "In addition to the simulation and descriptive statistics, the project includes a\n", + "On top of the simulation and descriptive statistics, the project includes a\n", "**Bayesian regression layer** that estimates the effect of luck on log-capital\n", - "while controlling for talent.\n", - "\n", - "All Bayesian functions live in `causal_success_utils.py` and rely on **PyMC**\n", - "and **ArviZ**. They are **optional**: if these libraries are not installed, you\n", - "can still run the simulation and summary functions.\n", + "while controlling for talent. All of the Bayesian functions live in\n", + "`causal_success_utils.py` and depend on **PyMC** and **ArviZ**. They are\n", + "optional: if those libraries are not installed, you can still run the\n", + "simulation and summary functions on their own.\n", "\n", "### Overview of the Model\n", "\n", @@ -892,8 +684,10 @@ "\n", "$$\\log(\\text{capital}_i) = \\alpha + \\beta_{\\text{luck}} \\cdot \\text{lucky_events}_i + \\beta_{\\text{intensity}} \\cdot \\text{talent_intensity}_i + \\beta_{\\text{iq}} \\cdot \\text{talent_iq}_i + \\beta_{\\text{networking}} \\cdot \\text{talent_networking}_i + \\varepsilon_i$$\n", "\n", - "- `beta_luck` is the **Primary Quantity of Interest**: the (log-scale) effect of one additional lucky event, holding talent constant.\n", - "- Priors are **weakly informative**, centered at 0.\n", + "The primary quantity of interest is `beta_luck`, the log-scale effect of one\n", + "additional lucky event with talent held constant. All priors are weakly\n", + "informative and centered at 0, so the data is allowed to dominate the\n", + "inference.\n", "\n", "### `fit_bayesian_luck_model`\n", "\n", @@ -920,26 +714,18 @@ ")\n", "```\n", "\n", - "**Arguments:**\n", - "\n", - "- `df: pd.DataFrame`: output from `get_results_dataframe`\n", - "- `draws: int`: posterior draws per chain (default 1000)\n", - "- `tune: int`: warm-up / burn-in iterations (default 1000)\n", - "- `target_accept: float`: NUTS target acceptance rate (default 0.9)\n", - "- `random_seed: int`: random seed\n", - "\n", - "**Returns:**\n", - "\n", - "- `model`: PyMC model object\n", - "- `idata`: ArviZ `InferenceData` with posterior samples\n", - "\n", - "> Note: If PyMC or ArviZ are not installed, this function will raise an\n", - "> `ImportError`.\n", + "The function takes a DataFrame `df` produced by `get_results_dataframe`, the\n", + "number of posterior draws per chain (`draws`, default 1000), the number of\n", + "warm-up iterations (`tune`, default 1000), the NUTS target acceptance rate\n", + "(`target_accept`, default 0.9), and a `random_seed`. It returns a tuple\n", + "containing the PyMC model object and an ArviZ `InferenceData` object holding\n", + "the posterior samples. Note that if PyMC or ArviZ are not installed, this\n", + "function will raise an `ImportError`.\n", "\n", "### `summarize_bayesian_fit`\n", "\n", - "Get a tidy summary table (posterior mean, standard deviation, and credible\n", - "intervals) for the main parameters.\n", + "This helper returns a tidy summary table with posterior means, standard\n", + "deviations, and credible intervals for the main parameters.\n", "\n", "```python\n", "from causal_success_utils import summarize_bayesian_fit\n", @@ -948,21 +734,14 @@ "print(summary)\n", "```\n", "\n", - "By default, it summarizes:\n", - "\n", - "- `alpha`\n", - "- `beta_luck`\n", - "- `beta_intensity`\n", - "- `beta_iq`\n", - "- `beta_networking`\n", - "- `sigma`\n", - "\n", - "You can also pass a custom `var_names` list if you want to restrict the summary.\n", + "By default it summarizes `alpha`, `beta_luck`, `beta_intensity`, `beta_iq`,\n", + "`beta_networking`, and `sigma`. You can also pass a custom `var_names` list\n", + "if you want to restrict the summary to a subset of parameters.\n", "\n", "### `posterior_predictive_check`\n", "\n", - "Run a basic posterior predictive check (PPC) by simulating log-capital from the\n", - "model and comparing to the observed log-capital.\n", + "Running a basic posterior predictive check (PPC) simulates log-capital from\n", + "the fitted model and compares it against the observed log-capital.\n", "\n", "```python\n", "from causal_success_utils import posterior_predictive_check\n", @@ -977,18 +756,17 @@ "print(\"Predicted mean log-capital (first 5):\", y_pred_mean[:5])\n", "```\n", "\n", - "**Returns a dictionary with:**\n", - "\n", - "- `\"y_obs\"`: observed log-capital\n", - "- `\"y_pred_mean\"`: posterior predictive mean log-capital per agent\n", - "- `\"y_pred_std\"`: posterior predictive standard deviation per agent\n", - "\n", - "This is useful for checking how well the model captures the distribution of\n", - "outcomes." + "The returned dictionary contains `\"y_obs\"` (observed log-capital),\n", + "`\"y_pred_mean\"` (posterior predictive mean log-capital per agent), and\n", + "`\"y_pred_std\"` (posterior predictive standard deviation per agent). This is\n", + "useful for checking how well the model captures the distribution of outcomes." ] } ], "metadata": { + "jupytext": { + "formats": "ipynb,py:percent" + }, "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", @@ -1004,9 +782,9 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.3" + "version": "3.12.13" } }, "nbformat": 4, "nbformat_minor": 4 -} +} \ No newline at end of file diff --git a/research/A_Causal_Analysis_of_Success_in_Modern_Society/causal_success_API.py b/research/A_Causal_Analysis_of_Success_in_Modern_Society/causal_success.API.py similarity index 82% rename from research/A_Causal_Analysis_of_Success_in_Modern_Society/causal_success_API.py rename to research/A_Causal_Analysis_of_Success_in_Modern_Society/causal_success.API.py index b22ce5791..762f4152c 100644 --- a/research/A_Causal_Analysis_of_Success_in_Modern_Society/causal_success_API.py +++ b/research/A_Causal_Analysis_of_Success_in_Modern_Society/causal_success.API.py @@ -1,6 +1,7 @@ # --- # jupyter: # jupytext: +# formats: ipynb,py:percent # text_representation: # extension: .py # format_name: percent @@ -12,26 +13,6 @@ # name: python3 # --- -# %% [markdown] -# ## When to Use What -# -# - Use the **simulation functions** (`create_population`, `run_simulation`, -# `run_policy_simulation`) to generate data and explore how talent and luck -# interact in the model world. -# - Use the **summary and inequality functions** (`get_results_dataframe`, -# `generate_summary_statistics`, `calculate_gini`) to quantify emergent patterns -# (inequality, top shares, etc.). -# - Use the **Bayesian functions** (`fit_bayesian_luck_model`, -# `summarize_bayesian_fit`, `posterior_predictive_check`) when you want: -# - A principled posterior over the effect of luck, -# - Credible intervals around effect sizes, -# - And basic model checking via posterior predictive simulations. -# -# Together, these APIs give you a complete pipeline from **simulation** → -# **descriptive analysis** → **causal and Bayesian inference**. - -# %% - # %% [markdown] # # Causal Success Analysis: API Demonstration # @@ -39,9 +20,29 @@ # # This notebook is meant to be a hands-on walkthrough of the building blocks behind the project. We import the simulation code and experiment with each component one at a time to understand what it does and why it matters. # -# If you’re interested in seeing how all of these pieces come together in a complete analysis—simulation, causal inference, and policy comparison—take a look at `causal_success_example.ipynb`. +# If you’re interested in seeing how all of these pieces come together in a complete analysis—simulation, causal inference, and policy comparison—take a look at `causal_success.example.ipynb`. # -# You can think of this notebook as getting familiar with the individual tools before using them together in a full wrkflow. +# You can think of this notebook as getting familiar with the individual tools before using them together in a full workflow. +# + +# %% [markdown] +# ## When to Use What +# +# The **simulation functions** (`create_population`, `run_simulation`, +# `run_policy_simulation`) are how you generate data and explore the interaction +# between talent and luck inside the model world. Once you have a simulation in +# hand, the **summary and inequality functions** (`get_results_dataframe`, +# `generate_summary_statistics`, `calculate_gini`) quantify the emergent +# patterns such as inequality and top shares. +# +# When you want a principled posterior over the effect of luck, credible +# intervals around the effect sizes, or basic model checking via posterior +# predictive simulations, reach for the **Bayesian functions** +# (`fit_bayesian_luck_model`, `summarize_bayesian_fit`, +# `posterior_predictive_check`). +# +# Taken together, these APIs form a complete pipeline from **simulation** to +# **descriptive analysis** to **causal and Bayesian inference**. # # %% [markdown] @@ -80,6 +81,7 @@ create_population, run_simulation, run_policy_simulation, + run_policy_and_measure, calculate_gini, get_results_dataframe, generate_summary_statistics, @@ -97,7 +99,7 @@ # %% [markdown] # ## Demo 1: Creating a Single Agent # -# Let’s create one simulated person and take a quick look at their starting traits and stat. +# Let’s create one simulated person and take a quick look at their starting traits and stats. # # %% @@ -127,13 +129,13 @@ # # The event exposure probability is computed using a sigmoid function of the agent’s intensity. With an intensity of 0.7, this agent has **above-average exposure** to events, resulting in an exposure probability of about **0.60**. An agent with lower intensity (for example, 0.3) would have noticeably less exposure, while higher intensity values push the probability closer to 1. # -# The talent norm is simply the Euclidean norm of the talent vector (intensity, IQ, networking, and initial capital). It provides a single summary measure of overall capability. This value is useful for analysis and comparison, but it does not directly determine success on its own—outcomes still depend heavily on the sequence of events the agent experienes. +# The talent norm is simply the Euclidean norm of the talent vector (intensity, IQ, networking, and initial capital). It provides a single summary measure of overall capability. This value is useful for analysis and comparison, but it does not directly determine success on its own—outcomes still depend heavily on the sequence of events the agent experiences. # # %% [markdown] # ## Demo 2: Applying Events to an Agent # -# Next, we’ll apply a few lucky and unlucky events to the same agent and watch how their capital change. +# Next, we’ll apply a few lucky and unlucky events to the same agent and watch how their capital changes. # # %% @@ -167,7 +169,7 @@ # # Because each change is a percentage of the current capital, the **order and timing of events matter**. Early gains raise the base on which future gains and losses are calculated, while early setbacks shrink it. # -# Over many periods, this compounding effect can produce large differences in outcomes, even when agents start with identical resources and similar abilties. +# Over many periods, this compounding effect can produce large differences in outcomes, even when agents start with identical resources and similar abilities. # # %% [markdown] @@ -207,7 +209,7 @@ # # Each talent dimension is drawn independently from a normal distribution with mean 0.5 and standard deviation 0.15, then clipped to stay within the \([0, 1]\) range. As expected, most values cluster near 0.5 with moderate spread, which is reflected in the summary statistics above. # -# At this point, all agents still have exactly \$1.00 in capital. There is variation in *potential* (talents), but no variation in *outcomes* yet. Any inequality that appears later will be the result of how random events interact with these talents over time, not differences in starting weath. +# At this point, all agents still have exactly \$1.00 in capital. There is variation in *potential* (talents), but no variation in *outcomes* yet. Any inequality that appears later will be the result of how random events interact with these talents over time, not differences in starting wealth. # # %% [markdown] @@ -253,13 +255,13 @@ # # These differences are driven primarily by **event histories**. For example, Agent 2 experienced several more lucky than unlucky events and ended up well ahead of the population mean, while Agents 3 and 4 encountered multiple unlucky events and fell behind. The mean capital remains close to \$1.00, indicating that gains by some agents are largely offset by losses elsewhere. # -# This short run illustrates the core mechanism of the model: random events, combined with multiplicative updates, quickly generate dispersion in outcomes. While inequality is still limited at this horizon, extending the simulation in time or increasing event frequency amplifies these differences substantially, which motivates the longer simulations examined later in the anaysis. +# This short run illustrates the core mechanism of the model: random events, combined with multiplicative updates, quickly generate dispersion in outcomes. While inequality is still limited at this horizon, extending the simulation in time or increasing event frequency amplifies these differences substantially, which motivates the longer simulations examined later in the analysis. # # %% [markdown] # ## Demo 5: Calculating the Gini Coefficient # -# To quantify how unequal the outcomes have become, we use the **Gini coefficient**, a standard measure of inequality widely used in economics and social scienc. +# To quantify how unequal the outcomes have become, we use the **Gini coefficient**, a standard measure of inequality widely used in economics and social science. # # %% @@ -325,7 +327,7 @@ # # Representing the simulation results as a DataFrame makes patterns much easier to see and analyze. Each row corresponds to a single agent, and each column captures either a talent attribute, an event count, or a final outcome. # -# From the summary statistics, we can already observe several important facts. Average capital remains close to \$1 00, which is consistent with gains and losses roughly balancing out over this short run. At the same time, there is meaningful dispersion: some agents accumulated over \$1.60 after experiencing multiple lucky events, while others suffered repeated unlucky events and fell below \$0.50. +# From the summary statistics, we can already observe several important facts. Average capital remains close to \$1.00, which is consistent with gains and losses roughly balancing out over this short run. At the same time, there is meaningful dispersion: some agents accumulated over \$1.60 after experiencing multiple lucky events, while others suffered repeated unlucky events and fell below \$0.50. # # Using a DataFrame allows us to compute correlations, rank agents by outcomes, # and prepare the data for causal analysis methods in later sections. These @@ -338,7 +340,7 @@ # # Rather than calculating each metric by hand, we can use a helper function that summarizes the entire simulation in one step. # -# This function returns all the key quantities you would typically report: inequality measures, distributional statistics, and average event counts. It provides a quick snapshot of how the system evolved and is especially useful when comparing multiple simulation runs or policy scenaros. +# This function returns all the key quantities you would typically report: inequality measures, distributional statistics, and average event counts. It provides a quick snapshot of how the system evolved and is especially useful when comparing multiple simulation runs or policy scenarios. # # %% @@ -363,7 +365,7 @@ # # The Gini coefficient of approximately 0.12 indicates low overall inequality at this stage, which is expected given the short time horizon. However, wealth concentration is already visible: the top 10% of agents hold about 15% of total capital, while the bottom half collectively holds just over 40%. # -# These statistics illustrate an important feature of the model: inequality does not appear all at once. Instead, it accumulates gradually as random events compound over time. In longer simulations, the same dynamics lead to substantially higher inequality, even though the underlying talent distribution remains unchnged. +# These statistics illustrate an important feature of the model: inequality does not appear all at once. Instead, it accumulates gradually as random events compound over time. In longer simulations, the same dynamics lead to substantially higher inequality, even though the underlying talent distribution remains unchanged. # # %% [markdown] @@ -373,7 +375,7 @@ # # Specifically, it confirms that capital values never become negative, that no missing or undefined values appear, and that event counts align correctly with each agent’s recorded history. These checks help catch subtle bugs that might otherwise go unnoticed but could invalidate downstream analysis. # -# While this step does not change the results, it provides confidence that the simulation outputs are internally consistent and safe to use for statistical and causal anaysis. +# While this step does not change the results, it provides confidence that the simulation outputs are internally consistent and safe to use for statistical and causal analysis. # # %% @@ -396,48 +398,23 @@ # # The goal here is not to declare a single “best” policy, but to illustrate how different allocation rules interact with the same underlying dynamics. By comparing outcomes across policies, we can see how initial resource distribution shapes inequality, efficiency, and opportunity over time. # -# In this demo, we compare two simple approaches: -# - **Egalitarian allocation**, where resources are distributed equally to all agents -# - **Meritocratic allocation**, where resources are distributed in proportion to measured talent -# -# Both policies are followed by the same stochastic simulation, allowing us to isolate the effect of the allocation rue itself. +# This demo compares two simple approaches. **Egalitarian allocation** +# distributes resources equally to all agents, while **meritocratic allocation** +# distributes them in proportion to measured talent. Both policies are followed +# by the same stochastic simulation, so the only thing we're changing is the +# allocation rule itself. # # %% -N = 20 -SEED = 123 -RESOURCE = 20.0 -N_PERIODS = 10 - - -def run_policy(policy_name: str, cate_values=None): - agents = create_population(n_agents=N, seed=SEED) - kwargs = dict( - agents=agents, - policy=policy_name, - resource_amount=RESOURCE, - n_periods=N_PERIODS, - seed=SEED, - ) - if policy_name == "cate_optimal": - if cate_values is None: - raise ValueError("cate_values must be provided for 'cate_optimal'.") - kwargs["cate_values"] = cate_values - - agents = run_policy_simulation(**kwargs) - df = get_results_dataframe(agents) - return df, calculate_gini(df["capital"].values) - - print("Testing egalitarian allocation...\n") -df_equal, gini_equal = run_policy("egalitarian") +df_equal, gini_equal = run_policy_and_measure("egalitarian") print("Egalitarian policy:") print(f" Final Gini: {gini_equal:.3f}") print(f" Mean capital: ${df_equal['capital'].mean():.2f}") print(f" Total capital: ${df_equal['capital'].sum():.2f}") print("\nTesting meritocratic allocation...\n") -df_merit, gini_merit = run_policy("meritocratic") +df_merit, gini_merit = run_policy_and_measure("meritocratic") print("Meritocratic policy:") print(f" Final Gini: {gini_merit:.3f}") print(f" Mean capital: ${df_merit['capital'].mean():.2f}") @@ -467,7 +444,7 @@ def run_policy(policy_name: str, cate_values=None): # # However, a modest difference appears in inequality. The egalitarian policy produces a slightly lower Gini coefficient than the meritocratic policy, indicating a more even distribution of outcomes. This suggests that allocating resources uniformly at the outset dampens early divergence, even when subsequent growth remains multiplicative and stochastic. # -# At the same time, the total capital generated under both policies is nearly identical, indicating that reduced inequality in this setting does not come at a substantial efficiency cost. Because this result comes from a single run with one random seed and a short time horizon, it should be interpreted as illustrative rather than conclusive. Robust policy evaluation would require averaging outcomes across many simulaions. +# At the same time, the total capital generated under both policies is nearly identical, indicating that reduced inequality in this setting does not come at a substantial efficiency cost. Because this result comes from a single run with one random seed and a short time horizon, it should be interpreted as illustrative rather than conclusive. Robust policy evaluation would require averaging outcomes across many simulations. # # %% [markdown] @@ -475,7 +452,7 @@ def run_policy(policy_name: str, cate_values=None): # # Numbers summarize outcomes, but visualizations make the distributional effects easier to grasp. In this final demo, we create a simple plot of final capital values to see how outcomes spread across agents. # -# Even in short simulations, these plots often reveal early signs of skewness, with a small number of agents pulling ahead while others fall behind. This visual perspective complements the numerical inequality measures shown earler. +# Even in short simulations, these plots often reveal early signs of skewness, with a small number of agents pulling ahead while others fall behind. This visual perspective complements the numerical inequality measures shown earlier. # # %% @@ -536,26 +513,24 @@ def run_policy(policy_name: str, cate_values=None): # # Specifically, we covered: # -# 1. Creating individual agents with well-defined talent attributes -# 2. Applying lucky and unlucky events using multiplicative dynamics -# 3. Generating populations with realistically distributed talents -# 4. Running simulations over time with configurable parameters -# 5. Measuring inequality using standard metrics such as the Gini coefficient -# 6. Converting simulation results into DataFrames for efficient analysis -# 7. Producing comprehensive summary statistics in a single step -# 8. Validating simulation outputs to ensure internal consistency -# 9. Comparing alternative policy-based resource allocation rules -# 10. Visualizing talent, capital, and luck to understand distributional patterns +# 1. Creating individual agents with well-defined talent attributes +# 2. Applying lucky and unlucky events using multiplicative dynamics +# 3. Generating populations with realistically distributed talents +# 4. Running simulations over time with configurable parameters +# 5. Measuring inequality using standard metrics such as the Gini coefficient +# 6. Converting simulation results into DataFrames for efficient analysis +# 7. Producing comprehensive summary statistics in a single step +# 8. Validating simulation outputs to ensure internal consistency +# 9. Comparing alternative policy-based resource allocation rules +# 10. Visualizing talent, capital, and luck to understand distributional patterns # # Together, these demos illustrate how simple stochastic mechanisms, when compounded over time, can generate unequal outcomes even from nearly identical starting conditions. # -# --- -# # ### Next steps # -# To see all of these components working together in a full analysis pipeline, open **`causal_success_example.ipynb`**, which integrates simulation, statistical analysis, and causal inference end to end. +# To see all of these components working together in a full analysis pipeline, open **`causal_success.example.ipynb`**, which integrates simulation, statistical analysis, and causal inference end to end. # -# For detailed technical documentation of the underlying functions and classes, refer to **`causal_success_API.md`**. +# For detailed technical documentation of the underlying functions and classes, refer to **`causal_success_utils.py`**. # # For the broader motivation, theoretical background, and interpretation of results, see **`README.md`**. # @@ -566,13 +541,12 @@ def run_policy(policy_name: str, cate_values=None): # %% [markdown] # ## Bayesian Inference API # -# In addition to the simulation and descriptive statistics, the project includes a +# On top of the simulation and descriptive statistics, the project includes a # **Bayesian regression layer** that estimates the effect of luck on log-capital -# while controlling for talent. -# -# All Bayesian functions live in `causal_success_utils.py` and rely on **PyMC** -# and **ArviZ**. They are **optional**: if these libraries are not installed, you -# can still run the simulation and summary functions. +# while controlling for talent. All of the Bayesian functions live in +# `causal_success_utils.py` and depend on **PyMC** and **ArviZ**. They are +# optional: if those libraries are not installed, you can still run the +# simulation and summary functions on their own. # # ### Overview of the Model # @@ -580,8 +554,10 @@ def run_policy(policy_name: str, cate_values=None): # # $$\log(\text{capital}_i) = \alpha + \beta_{\text{luck}} \cdot \text{lucky_events}_i + \beta_{\text{intensity}} \cdot \text{talent_intensity}_i + \beta_{\text{iq}} \cdot \text{talent_iq}_i + \beta_{\text{networking}} \cdot \text{talent_networking}_i + \varepsilon_i$$ # -# - `beta_luck` is the **Primary Quantity of Interest**: the (log-scale) effect of one additional lucky event, holding talent constant. -# - Priors are **weakly informative**, centered at 0. +# The primary quantity of interest is `beta_luck`, the log-scale effect of one +# additional lucky event with talent held constant. All priors are weakly +# informative and centered at 0, so the data is allowed to dominate the +# inference. # # ### `fit_bayesian_luck_model` # @@ -608,26 +584,18 @@ def run_policy(policy_name: str, cate_values=None): # ) # ``` # -# **Arguments:** -# -# - `df: pd.DataFrame`: output from `get_results_dataframe` -# - `draws: int`: posterior draws per chain (default 1000) -# - `tune: int`: warm-up / burn-in iterations (default 1000) -# - `target_accept: float`: NUTS target acceptance rate (default 0.9) -# - `random_seed: int`: random seed -# -# **Returns:** -# -# - `model`: PyMC model object -# - `idata`: ArviZ `InferenceData` with posterior samples -# -# > Note: If PyMC or ArviZ are not installed, this function will raise an -# > `ImportError`. +# The function takes a DataFrame `df` produced by `get_results_dataframe`, the +# number of posterior draws per chain (`draws`, default 1000), the number of +# warm-up iterations (`tune`, default 1000), the NUTS target acceptance rate +# (`target_accept`, default 0.9), and a `random_seed`. It returns a tuple +# containing the PyMC model object and an ArviZ `InferenceData` object holding +# the posterior samples. Note that if PyMC or ArviZ are not installed, this +# function will raise an `ImportError`. # # ### `summarize_bayesian_fit` # -# Get a tidy summary table (posterior mean, standard deviation, and credible -# intervals) for the main parameters. +# This helper returns a tidy summary table with posterior means, standard +# deviations, and credible intervals for the main parameters. # # ```python # from causal_success_utils import summarize_bayesian_fit @@ -636,21 +604,14 @@ def run_policy(policy_name: str, cate_values=None): # print(summary) # ``` # -# By default, it summarizes: -# -# - `alpha` -# - `beta_luck` -# - `beta_intensity` -# - `beta_iq` -# - `beta_networking` -# - `sigma` -# -# You can also pass a custom `var_names` list if you want to restrict the summary. +# By default it summarizes `alpha`, `beta_luck`, `beta_intensity`, `beta_iq`, +# `beta_networking`, and `sigma`. You can also pass a custom `var_names` list +# if you want to restrict the summary to a subset of parameters. # # ### `posterior_predictive_check` # -# Run a basic posterior predictive check (PPC) by simulating log-capital from the -# model and comparing to the observed log-capital. +# Running a basic posterior predictive check (PPC) simulates log-capital from +# the fitted model and compares it against the observed log-capital. # # ```python # from causal_success_utils import posterior_predictive_check @@ -665,11 +626,7 @@ def run_policy(policy_name: str, cate_values=None): # print("Predicted mean log-capital (first 5):", y_pred_mean[:5]) # ``` # -# **Returns a dictionary with:** -# -# - `"y_obs"`: observed log-capital -# - `"y_pred_mean"`: posterior predictive mean log-capital per agent -# - `"y_pred_std"`: posterior predictive standard deviation per agent -# -# This is useful for checking how well the model captures the distribution of -# outcomes. +# The returned dictionary contains `"y_obs"` (observed log-capital), +# `"y_pred_mean"` (posterior predictive mean log-capital per agent), and +# `"y_pred_std"` (posterior predictive standard deviation per agent). This is +# useful for checking how well the model captures the distribution of outcomes. diff --git a/research/A_Causal_Analysis_of_Success_in_Modern_Society/causal_success.example.ipynb b/research/A_Causal_Analysis_of_Success_in_Modern_Society/causal_success.example.ipynb new file mode 100644 index 000000000..bd0366d2e --- /dev/null +++ b/research/A_Causal_Analysis_of_Success_in_Modern_Society/causal_success.example.ipynb @@ -0,0 +1,1326 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# %load_ext autoreload\n", + "# %autoreload 2\n", + "\n", + "import logging\n", + "import sys\n", + "\n", + "import numpy as np\n", + "import pandas as pd\n", + "import seaborn as sns\n", + "import matplotlib.pyplot as plt\n", + "\n", + "# Initialize logger.\n", + "logging.basicConfig(level=logging.INFO)\n", + "_LOG = logging.getLogger(__name__)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# %matplotlib inline\n", + "\n", + "# Make sure the project root is importable (works in Docker and locally).\n", + "import os\n", + "\n", + "PROJECT_ROOT = \"/app\" if os.path.exists(\"/app\") else os.getcwd()\n", + "if PROJECT_ROOT not in sys.path:\n", + " sys.path.insert(0, PROJECT_ROOT)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# A Causal Analysis of Success in Modern Society\n", + "\n", + "## Tutorial: Talent, Luck, and Causal Inference\n", + "\n", + "Author: Krishna Kishore Buddi\n", + "Course: MSML610\n", + "Instructor: Prof. GP Saggese\n", + "Institution: University of Maryland\n", + "\n", + "## What this notebook does\n", + "\n", + "This notebook walks through the entire analysis pipeline for the project *“A Causal Analysis of Success in Modern Society.”*\n", + "You will simulate a population of agents with different talents, expose them\n", + "to good and bad events that compound over time, measure how unequal the final\n", + "outcomes become, and then use modern causal inference tools (Double Machine\n", + "Learning and Causal Forests) to separate **talent** from **luck**.\n", + "\n", + "The goal is not to perfectly model the real world. Instead, the goal is to understand a simple but powerful mechanism:\n", + "\n", + "> If abilities are roughly “normal” but success is extremely unequal, then **random multiplicative events** must be doing a lot of the work.\n", + "\n", + "The notebook is meant to be **interactive**. Run each section in order, look\n", + "at the printed summaries and plots, and then tweak the parameters (number of\n", + "agents, number of events, event magnitudes) to see what changes.\n", + "\n", + "For a higher-level narrative and more theory, `README.md` has the big-picture\n", + "motivation and results, the file\n", + "`all.learn_Causal_Analysis_of_Success_in_60_minutes.how_to_guide.md` is the\n", + "detailed written tutorial, and `causal_success.API.ipynb` walks through the\n", + "function-level documentation of `causal_success_utils.py`." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Section 1: Environment Setup and Package Imports\n", + "\n", + "We start by setting up the Python environment and importing the core libraries used throughout the tutorial. NumPy handles numerical computations, Pandas provides tools for working with tabular data, and Matplotlib/Seaborn support visualization. For the causal analysis, we rely on scikit-learn for general machine learning routines and EconML for modern double machine learning and causal forest estimators.\n", + "\n", + "This section simply ensures that all dependencies are available and\n", + "configured, so the later parts of the notebook can focus on the model, the\n", + "simulation, and the interpretation of results rather than on technical setup\n", + "details." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from scipy import stats\n", + "from scipy.stats import mannwhitneyu\n", + "\n", + "from causal_success_utils import (\n", + " create_population,\n", + " run_simulation,\n", + " calculate_gini,\n", + " get_results_dataframe,\n", + " fit_dml_model,\n", + " fit_causal_forest,\n", + " compare_allocation_policies,\n", + ")\n", + "\n", + "# Configure plotting.\n", + "sns.set_style(\"whitegrid\")\n", + "plt.rcParams[\"figure.figsize\"] = (14, 6)\n", + "plt.rcParams[\"font.size\"] = 10\n", + "\n", + "_LOG.info(\"Environment configured successfully\")\n", + "_LOG.info(\"Project root: %s\", PROJECT_ROOT)\n", + "_LOG.info(\"NumPy version: %s\", np.__version__)\n", + "_LOG.info(\"Pandas version: %s\", pd.__version__)\n", + "_LOG.info(\"causal_success_utils module imported successfully\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "lines_to_next_cell": 2 + }, + "outputs": [], + "source": [ + "# Experimental Configuration.\n", + "\n", + "# Population parameters.\n", + "N_AGENTS = 100\n", + "\n", + "# Time parameters.\n", + "N_ROUNDS = 200\n", + "\n", + "# Event parameters.\n", + "LUCKY_EVENTS_PER_ROUND = 10\n", + "UNLUCKY_EVENTS_PER_ROUND = 10\n", + "EVENTS_PER_ROUND = LUCKY_EVENTS_PER_ROUND + UNLUCKY_EVENTS_PER_ROUND\n", + "\n", + "# Event impact parameters (lucky events: on average +35% with moderate spread).\n", + "LUCKY_MEAN = 0.35\n", + "LUCKY_STD = 0.12\n", + "\n", + "# Unlucky events: on average -10% with smaller spread.\n", + "UNLUCKY_MEAN = 0.10\n", + "UNLUCKY_STD = 0.04\n", + "\n", + "# Random seed for reproducibility.\n", + "RANDOM_SEED = 42\n", + "\n", + "_LOG.info(\"Experimental configuration loaded\")\n", + "_LOG.info(\"Agents: %s\", N_AGENTS)\n", + "_LOG.info(\"Rounds: %s\", N_ROUNDS)\n", + "_LOG.info(\"Events per round: %s\", EVENTS_PER_ROUND)\n", + "_LOG.info(\"Random seed: %s\", RANDOM_SEED)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Section 2: Theoretical Framework\n", + "\n", + "This section lays out the model that drives the simulation. We describe how\n", + "talent is represented, how random events affect people over time, and how we\n", + "frame the causal question about luck and success.\n", + "\n", + "### 2.1 Model Specification\n", + "\n", + "Each agent \\(i\\) is described by a talent vector \\(T_i\\) with several\n", + "components. These dimensions are not meant to be perfect psychological\n", + "constructs, but convenient knobs that capture different ways people can be\n", + "“good at” navigating opportunities.\n", + "\n", + "**Intensity (\\(t_{\\text{intensity}}\\))** stands in for effort, persistence,\n", + "and general activity level. In the model, this drives **exposure to events**.\n", + "High-intensity agents show up more often, talk to more people, and try more\n", + "things, so they are more likely to bump into both good and bad events. This\n", + "is our formalization of the “surface area of luck” idea.\n", + "\n", + "**IQ (\\(t_{\\text{iq}}\\))** represents cognitive ability and problem-solving\n", + "skill. Where intensity determines how many opportunities you see, IQ affects\n", + "the **probability of turning a lucky event into an actual gain**. An agent\n", + "with high intensity but low IQ may see many chances but fail to convert them,\n", + "while high IQ with very low intensity simply means you're not in the right\n", + "place at the right time.\n", + "\n", + "**Networking (\\(t_{\\text{networking}}\\))** measures social capital, i.e., the\n", + "strength and reach of an agent’s relationships. In the simulation, this lets\n", + "opportunities **spill over** from one agent to another. A lucky event that\n", + "hits one person can sometimes partially benefit someone else with strong\n", + "connections, mirroring referrals, recommendations, and \"who you know\"\n", + "effects.\n", + "\n", + "**Initial Capital (\\(C_{0}\\))** is the starting wealth level. All agents\n", + "begin with the same value in the baseline setup, typically \\(C_0 = 1\\), which\n", + "isolates the role of random events and talent. Initial capital gives everyone\n", + "a baseline but does **not** affect event probabilities directly.\n", + "\n", + "Taken together, these components give each agent a fixed talent profile that\n", + "shapes how they interact with randomness over time.\n", + "\n", + "### 2.2 Event Mechanics\n", + "\n", + "At each time period, agents may experience **events** that change their\n", + "capital. Events have three key ingredients. First, a **type**, either\n", + "beneficial (\"lucky\") or detrimental (\"unlucky\"). Second, an **impact\n", + "magnitude \\(\\Delta\\)**. Lucky events are sampled from a normal distribution\n", + "with a positive mean (e.g., 25 to 35%), then clipped to a reasonable range\n", + "such as 5 to 50%. Unlucky events are sampled similarly with a smaller\n", + "positive mean (interpreted as a loss) and clipped to 5 to 30%. Third, an\n", + "**assignment probability**: who actually receives each event is determined\n", + "probabilistically from talent, mostly intensity, with networking affecting\n", + "spillovers.\n", + "\n", + "Capital evolves **multiplicatively**. A beneficial event applies\n", + "\\(C_{i,t+1} = C_{i,t} \\times (1 + \\Delta)\\), while a detrimental event\n", + "applies \\(C_{i,t+1} = C_{i,t} \\times (1 - \\Delta)\\).\n", + "\n", + "This multiplicative structure is the core of the model. Under additive\n", + "dynamics, everyone’s capital shifts by similar absolute amounts, and initial\n", + "gaps tend to persist but not explode. Under multiplicative dynamics,\n", + "**percentage changes** are what matter, so a 20% gain on \\$1 and a 20% gain\n", + "on \\$1000 look very different in absolute terms. Over many periods, small\n", + "differences in event histories can lead to large differences in outcomes.\n", + "\n", + "We also enforce a small capital floor (e.g., \\$0.01) to avoid negative or\n", + "zero values, which keeps the model numerically stable and lets us safely take\n", + "logarithms.\n", + "\n", + "### 2.3 Causal Inference Framework\n", + "\n", + "The central causal question is:\n", + "\n", + "> *What is the effect of experiencing additional beneficial events on final success, after accounting for differences in talent?*\n", + "\n", + "The difficulty is that **treatment is not randomly assigned**. More talented\n", + "agents may both receive more opportunities and be better at using them. If we\n", + "simply regress outcomes on the number of lucky events, we would mix up three\n", + "things at once: the true causal effect of lucky events, the fact that\n", + "high-talent agents get more opportunities, and the fact that high-talent\n", + "agents would do well even with fewer events.\n", + "\n", + "To untangle these pieces, we define the **treatment variable \\(T\\)** as the\n", + "count of beneficial (lucky) events an agent experiences over the simulation.\n", + "The **outcome variable \\(Y\\)** is the final log capital,\n", + "\\(\\log(C_{\\text{final}})\\). Using the logarithm makes multiplicative effects\n", + "more additive and stabilizes variance, so a one-unit change in \\(Y\\) roughly\n", + "corresponds to a percentage change in wealth. The **confounders \\(X\\)** are\n", + "the talent dimensions (intensity, IQ, networking) and any other features\n", + "that influence both how many lucky events an agent receives and how well\n", + "they convert those events into capital. With this setup, the target quantity\n", + "is the **causal effect of \\(T\\) on \\(Y\\)**, holding \\(X\\) fixed.\n", + "\n", + "Two complementary tools handle this. **Double Machine Learning (DML)** first\n", + "models how \\(T\\) depends on \\(X\\) (who tends to get more opportunities) and\n", + "how \\(Y\\) depends on \\(X\\) (who tends to do well given their abilities),\n", + "removes the part of \\(T\\) and \\(Y\\) that can be explained by \\(X\\), and then\n", + "estimates the effect of the remaining residual variation in \\(T\\) on the\n", + "residual in \\(Y\\). This corrects for confounding under fairly general\n", + "conditions and yields an estimate of the **average treatment effect** of an\n", + "additional lucky event. **Causal Forests (CF)** extend the same idea to let\n", + "the treatment effect vary with \\(X\\), so instead of one global effect we\n", + "obtain a **Conditional Average Treatment Effect (CATE)** for each agent or\n", + "subgroup. This reveals heterogeneity: some combinations of intensity, IQ,\n", + "and networking benefit more from extra opportunities than others.\n", + "\n", + "Together, DML and Causal Forests answer two questions at once. On average,\n", + "how much does one more lucky event change final outcomes? And for which\n", + "types of agents is that extra event especially valuable? The remaining\n", + "sections put this framework into practice using the simulated data generated\n", + "by our agent-based model." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Section 3: Population Construction\n", + "\n", + "In this section, we build the synthetic population that drives the rest of the analysis.\n", + "\n", + "We work with a population of **100 agents**, each with a set of talent dimensions drawn from a normal distribution centered at 0.5 with a moderate spread. This choice mirrors a common empirical pattern: most human abilities cluster around an average level, with fewer people at the extremes.\n", + "\n", + "Because our talent dimensions represent probabilities or normalized scores,\n", + "we **clip all values to the \\([0, 1]\\) range**. This keeps the interpretation\n", + "straightforward: 0 means \"very low\" on that dimension, 1 means \"very high,\"\n", + "and values near 0.5 represent typical, \"average\" capability.\n", + "\n", + "At this stage, all agents also receive the **same initial capital** (usually \\(C_0 = 1\\)). Any inequality that emerges later in the tutorial will therefore come from differences in event histories and talent interactions, not from unequal starting points. This makes it easier to see how randomness and ability combine to create unequal outcomes over time." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "agents = create_population(n_agents=N_AGENTS, seed=RANDOM_SEED)\n", + "\n", + "print(f\"Population initialized: {len(agents)} agents\")\n", + "print(f\"Each agent has {len(agents[0].talent)} talent dimensions\")\n", + "\n", + "fig, axes = plt.subplots(1, 3, figsize=(15, 4))\n", + "\n", + "talent_data = {\n", + " \"Intensity\": [a.talent[\"intensity\"] for a in agents],\n", + " \"IQ\": [a.talent[\"iq\"] for a in agents],\n", + " \"Networking\": [a.talent[\"networking\"] for a in agents],\n", + "}\n", + "\n", + "for idx, (dimension_name, values) in enumerate(talent_data.items()):\n", + " axes[idx].hist(\n", + " values, bins=15, edgecolor=\"black\", alpha=0.7, color=f\"C{idx}\"\n", + " )\n", + " mean_val = np.mean(values)\n", + " axes[idx].axvline(\n", + " mean_val,\n", + " color=\"red\",\n", + " linestyle=\"--\",\n", + " linewidth=2,\n", + " label=f\"Mean: {mean_val:.3f}\",\n", + " )\n", + " axes[idx].set_xlabel(dimension_name, fontsize=11)\n", + " axes[idx].set_ylabel(\"Frequency\", fontsize=11)\n", + " axes[idx].set_title(\n", + " f\"{dimension_name} Distribution\", fontsize=12, fontweight=\"bold\"\n", + " )\n", + " axes[idx].legend(fontsize=10)\n", + " axes[idx].grid(axis=\"y\", alpha=0.3)\n", + "\n", + "plt.tight_layout()\n", + "plt.show()\n", + "\n", + "print(\"\\nTalent Dimension Statistics:\")\n", + "print(\"=\" * 60)\n", + "for dimension_name, values in talent_data.items():\n", + " print(\n", + " f\"{dimension_name:12} | Mean: {np.mean(values):.4f} | Std: {np.std(values):.4f} | Min: {np.min(values):.4f} | Max: {np.max(values):.4f}\"\n", + " )\n", + "\n", + "print(\"\\nAll distributions approximate normality with means near 0.5\")\n", + "print(\n", + " \"This provides a baseline of rough equality from which divergence will emerge\"\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Section 4: Simulation Implementation\n", + "\n", + "The simulation proceeds in discrete time steps. Each period, a fixed number of events occur. Events are classified as beneficial or detrimental with specified probabilities. Event assignment depends on agent characteristics, while impact magnitudes are drawn from distributions.\n", + "\n", + "We implement helper functions for event generation, assignment, and simulation execution." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Run the simulation using configured parameters.\n", + "print(\"Starting simulation...\")\n", + "print(f\" - Agents: {N_AGENTS}\")\n", + "print(f\" - Time periods: {N_ROUNDS}\")\n", + "print(f\" - Lucky events per period: {LUCKY_EVENTS_PER_ROUND}\")\n", + "print(f\" - Unlucky events per period: {UNLUCKY_EVENTS_PER_ROUND}\")\n", + "print()\n", + "\n", + "agents = run_simulation(\n", + " agents=agents,\n", + " n_periods=N_ROUNDS,\n", + " n_lucky_events_per_period=LUCKY_EVENTS_PER_ROUND,\n", + " n_unlucky_events_per_period=UNLUCKY_EVENTS_PER_ROUND,\n", + " lucky_mean=LUCKY_MEAN,\n", + " lucky_std=LUCKY_STD,\n", + " unlucky_mean=UNLUCKY_MEAN,\n", + " unlucky_std=UNLUCKY_STD,\n", + " seed=RANDOM_SEED,\n", + " verbose=True,\n", + ")\n", + "\n", + "print(\"\\nSimulation complete!\")\n", + "print(f\" Total agents: {len(agents)}\")\n", + "print(f\" Mean lucky events: {np.mean([a.lucky_events for a in agents]):.1f}\")\n", + "print(\n", + " f\" Mean unlucky events: {np.mean([a.unlucky_events for a in agents]):.1f}\"\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Section 5: Descriptive Analysis of Simulation Results\n", + "\n", + "After simulation completion, we examine the resulting distribution of outcomes. Converting the agent population to a DataFrame facilitates statistical analysis and visualization." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "df_results = get_results_dataframe(agents)\n", + "\n", + "print(\"Simulation Outcomes Summary\")\n", + "print(\"=\" * 70)\n", + "print(f\"\\nPopulation size: {len(df_results)} agents\")\n", + "\n", + "print(\"\\nCapital Distribution Statistics:\")\n", + "capital_stats = df_results[\"capital\"].describe()\n", + "for stat_name, stat_value in capital_stats.items():\n", + " print(f\" {stat_name:10}: ${stat_value:10.2f}\")\n", + "\n", + "print(\"\\nInequality Metrics:\")\n", + "print(\n", + " f\" Range (max/min): {df_results['capital'].max() / df_results['capital'].min():.2f}x\"\n", + ")\n", + "print(\n", + " f\" 90th/10th percentile ratio: {df_results['capital'].quantile(0.9) / df_results['capital'].quantile(0.1):.2f}x\"\n", + ")\n", + "print(\n", + " f\" Coefficient of variation: {df_results['capital'].std() / df_results['capital'].mean():.3f}\"\n", + ")\n", + "\n", + "print(\"\\nEvent Experience Distribution:\")\n", + "print(\" Beneficial events:\")\n", + "print(f\" Mean: {df_results['lucky_events'].mean():.2f}\")\n", + "print(f\" Std: {df_results['lucky_events'].std():.2f}\")\n", + "print(\n", + " f\" Range: {df_results['lucky_events'].min():.0f} to {df_results['lucky_events'].max():.0f}\"\n", + ")\n", + "\n", + "print(\" Detrimental events:\")\n", + "print(f\" Mean: {df_results['unlucky_events'].mean():.2f}\")\n", + "print(f\" Std: {df_results['unlucky_events'].std():.2f}\")\n", + "print(\n", + " f\" Range: {df_results['unlucky_events'].min():.0f} to {df_results['unlucky_events'].max():.0f}\"\n", + ")\n", + "\n", + "print(\" Net events (lucky - unlucky):\")\n", + "print(f\" Mean: {df_results['net_events'].mean():.2f}\")\n", + "print(f\" Std: {df_results['net_events'].std():.2f}\")\n", + "\n", + "print(\"\\nSample of Results (first 10 agents):\")\n", + "print(\n", + " df_results[\n", + " [\n", + " \"id\",\n", + " \"talent_norm\",\n", + " \"capital\",\n", + " \"lucky_events\",\n", + " \"unlucky_events\",\n", + " \"net_events\",\n", + " ]\n", + " ]\n", + " .head(10)\n", + " .to_string(index=False)\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Section 6: Distribution Analysis - From Normal to Power-Law\n", + "\n", + "This section visualizes the central finding: despite normal talent distributions, success follows a power-law pattern. We construct three complementary visualizations:\n", + "\n", + "1. Talent distribution histogram (should be approximately normal)\n", + "2. Success distribution on logarithmic scale (reveals power-law characteristics)\n", + "3. Lorenz curve quantifying inequality" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Calculate Gini coefficient using imported function\n", + "capital_values = df_results[\"capital\"].values\n", + "gini_coefficient = calculate_gini(capital_values)\n", + "\n", + "print(f\"Gini Coefficient: {gini_coefficient:.3f}\")\n", + "print(f\"Interpretation: {gini_coefficient:.1%} inequality\")\n", + "if gini_coefficient < 0.30:\n", + " print(\" → Low inequality\")\n", + "elif gini_coefficient < 0.50:\n", + " print(\" → Moderate inequality\")\n", + "else:\n", + " print(\" → High inequality\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "fig, axes = plt.subplots(1, 3, figsize=(18, 5))\n", + "\n", + "# Panel 1: Talent Distribution\n", + "talent_norms = df_results[\"talent_norm\"].values\n", + "axes[0].hist(\n", + " talent_norms, bins=20, edgecolor=\"black\", alpha=0.7, color=\"skyblue\"\n", + ")\n", + "axes[0].axvline(\n", + " talent_norms.mean(),\n", + " color=\"red\",\n", + " linestyle=\"--\",\n", + " linewidth=2,\n", + " label=f\"Mean: {talent_norms.mean():.3f}\",\n", + ")\n", + "axes[0].axvline(\n", + " np.median(talent_norms),\n", + " color=\"orange\",\n", + " linestyle=\":\",\n", + " linewidth=2,\n", + " label=f\"Median: {np.median(talent_norms):.3f}\",\n", + ")\n", + "axes[0].set_xlabel(\"Talent Score (Euclidean Norm)\", fontsize=11)\n", + "axes[0].set_ylabel(\"Frequency\", fontsize=11)\n", + "axes[0].set_title(\"Talent Distribution: Normal\", fontsize=12, fontweight=\"bold\")\n", + "axes[0].legend(fontsize=10)\n", + "axes[0].grid(axis=\"y\", alpha=0.3)\n", + "\n", + "# Panel 2: Success Distribution (Log Scale)\n", + "capital_vals = df_results[\"capital\"].values\n", + "axes[1].hist(\n", + " np.log10(capital_vals), bins=25, edgecolor=\"black\", alpha=0.7, color=\"coral\"\n", + ")\n", + "axes[1].set_xlabel(\"Log₁₀(Capital)\", fontsize=11)\n", + "axes[1].set_ylabel(\"Frequency\", fontsize=11)\n", + "axes[1].set_title(\n", + " \"Success Distribution: Power-Law\", fontsize=12, fontweight=\"bold\"\n", + ")\n", + "axes[1].grid(axis=\"y\", alpha=0.3)\n", + "axes[1].text(\n", + " 0.05,\n", + " 0.95,\n", + " f\"Skewness: {stats.skew(np.log10(capital_vals)):.2f}\",\n", + " transform=axes[1].transAxes,\n", + " verticalalignment=\"top\",\n", + " bbox=dict(boxstyle=\"round\", facecolor=\"wheat\", alpha=0.5),\n", + ")\n", + "\n", + "# Panel 3: Lorenz Curve\n", + "sorted_capital = np.sort(capital_vals)\n", + "cumsum = np.cumsum(sorted_capital)\n", + "cumsum_normalized = cumsum / cumsum[-1]\n", + "pop_share = np.linspace(0, 1, len(cumsum_normalized))\n", + "\n", + "axes[2].plot(\n", + " [0, 1], [0, 1], \"k--\", label=\"Perfect Equality\", linewidth=2, alpha=0.7\n", + ")\n", + "axes[2].plot(\n", + " pop_share, cumsum_normalized, \"b-\", label=\"Actual Distribution\", linewidth=2\n", + ")\n", + "axes[2].fill_between(\n", + " pop_share, cumsum_normalized, pop_share, alpha=0.3, color=\"blue\"\n", + ")\n", + "axes[2].set_xlabel(\"Cumulative Population Share\", fontsize=11)\n", + "axes[2].set_ylabel(\"Cumulative Wealth Share\", fontsize=11)\n", + "axes[2].set_title(\n", + " \"Lorenz Curve: Inequality Visualization\", fontsize=12, fontweight=\"bold\"\n", + ")\n", + "axes[2].legend(fontsize=10, loc=\"upper left\")\n", + "axes[2].grid(True, alpha=0.3)\n", + "axes[2].set_xlim(0, 1)\n", + "axes[2].set_ylim(0, 1)\n", + "\n", + "plt.tight_layout()\n", + "plt.show()\n", + "\n", + "gini = calculate_gini(capital_vals)\n", + "top10_share = (\n", + " df_results.nlargest(10, \"capital\")[\"capital\"].sum()\n", + " / df_results[\"capital\"].sum()\n", + ")\n", + "top20_share = (\n", + " df_results.nlargest(20, \"capital\")[\"capital\"].sum()\n", + " / df_results[\"capital\"].sum()\n", + ")\n", + "\n", + "print(\"\\nInequality Quantification:\")\n", + "print(\"=\" * 60)\n", + "print(f\"Gini Coefficient: {gini:.4f}\")\n", + "print(\" Interpretation: 0 = perfect equality, 1 = perfect inequality\")\n", + "print(f\" Observed value of {gini:.4f} indicates substantial inequality\")\n", + "print(\"\\nWealth Concentration:\")\n", + "print(f\" Top 10% control: {top10_share:.1%} of total wealth\")\n", + "print(f\" Top 20% control: {top20_share:.1%} of total wealth\")\n", + "print(\n", + " f\" Bottom 50% control: {df_results.nsmallest(50, 'capital')['capital'].sum() / df_results['capital'].sum():.1%} of total wealth\"\n", + ")\n", + "print(\"\\nThese patterns mirror real-world wealth distributions despite\")\n", + "print(\"starting from equality and using only random processes.\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Section 7: Correlation Analysis - Talent versus Luck\n", + "\n", + "We now examine which factors correlate more strongly with final outcomes. Standard Pearson correlations quantify linear relationships between variables. We compare correlations between:\n", + "\n", + "1. Talent and log(capital)\n", + "2. Beneficial events and log(capital)\n", + "3. Net events (beneficial minus detrimental) and log(capital)\n", + "\n", + "The log transformation of capital improves linearity and interpretability." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "log_capital = np.log(df_results[\"capital\"])\n", + "\n", + "corr_talent = df_results[\"talent_norm\"].corr(log_capital)\n", + "corr_luck = df_results[\"lucky_events\"].corr(log_capital)\n", + "corr_net = df_results[\"net_events\"].corr(log_capital)\n", + "corr_intensity = df_results[\"talent_intensity\"].corr(log_capital)\n", + "corr_iq = df_results[\"talent_iq\"].corr(log_capital)\n", + "corr_network = df_results[\"talent_networking\"].corr(log_capital)\n", + "\n", + "print(\"Correlation Analysis with Log(Capital)\")\n", + "print(\"=\" * 70)\n", + "print(\"\\nTalent Measures:\")\n", + "print(f\" Overall talent (norm): {corr_talent:.4f}\")\n", + "print(f\" Intensity dimension: {corr_intensity:.4f}\")\n", + "print(f\" IQ dimension: {corr_iq:.4f}\")\n", + "print(f\" Networking dimension: {corr_network:.4f}\")\n", + "\n", + "print(\"\\nLuck Measures:\")\n", + "print(f\" Beneficial events: {corr_luck:.4f}\")\n", + "print(f\" Net events (lucky-unlucky): {corr_net:.4f}\")\n", + "\n", + "print(\"\\nComparative Analysis:\")\n", + "print(\n", + " f\" Luck correlation / Talent correlation = {corr_luck / corr_talent:.2f}x\"\n", + ")\n", + "print(\n", + " f\"\\nKey Finding: Beneficial events are {corr_luck / corr_talent:.1f} times more correlated\"\n", + ")\n", + "print(\"with success than overall talent. This quantifies the dominance of\")\n", + "print(\"stochastic factors over ability in determining outcomes.\")\n", + "\n", + "fig, axes = plt.subplots(1, 2, figsize=(14, 5))\n", + "\n", + "# Panel 1: Talent vs Success\n", + "axes[0].scatter(\n", + " df_results[\"talent_norm\"],\n", + " df_results[\"capital\"],\n", + " alpha=0.6,\n", + " s=50,\n", + " c=\"steelblue\",\n", + " edgecolor=\"black\",\n", + " linewidth=0.5,\n", + ")\n", + "z = np.polyfit(df_results[\"talent_norm\"], df_results[\"capital\"], 1)\n", + "p = np.poly1d(z)\n", + "axes[0].plot(\n", + " df_results[\"talent_norm\"].sort_values(),\n", + " p(df_results[\"talent_norm\"].sort_values()),\n", + " \"r--\",\n", + " alpha=0.8,\n", + " linewidth=2,\n", + " label=\"Linear Fit\",\n", + ")\n", + "axes[0].set_xlabel(\"Talent Score\", fontsize=11)\n", + "axes[0].set_ylabel(\"Final Capital ($)\", fontsize=11)\n", + "axes[0].set_title(\n", + " f\"Talent vs Success (r = {corr_talent:.3f})\", fontsize=12, fontweight=\"bold\"\n", + ")\n", + "axes[0].set_yscale(\"log\")\n", + "axes[0].grid(True, alpha=0.3)\n", + "axes[0].legend(fontsize=10)\n", + "\n", + "# Panel 2: Luck vs Success\n", + "axes[1].scatter(\n", + " df_results[\"lucky_events\"],\n", + " df_results[\"capital\"],\n", + " alpha=0.6,\n", + " s=50,\n", + " c=\"coral\",\n", + " edgecolor=\"black\",\n", + " linewidth=0.5,\n", + ")\n", + "z = np.polyfit(df_results[\"lucky_events\"], df_results[\"capital\"], 1)\n", + "p = np.poly1d(z)\n", + "axes[1].plot(\n", + " df_results[\"lucky_events\"].sort_values(),\n", + " p(df_results[\"lucky_events\"].sort_values()),\n", + " \"r--\",\n", + " alpha=0.8,\n", + " linewidth=2,\n", + " label=\"Linear Fit\",\n", + ")\n", + "axes[1].set_xlabel(\"Number of Beneficial Events\", fontsize=11)\n", + "axes[1].set_ylabel(\"Final Capital ($)\", fontsize=11)\n", + "axes[1].set_title(\n", + " f\"Luck vs Success (r = {corr_luck:.3f})\", fontsize=12, fontweight=\"bold\"\n", + ")\n", + "axes[1].set_yscale(\"log\")\n", + "axes[1].grid(True, alpha=0.3)\n", + "axes[1].legend(fontsize=10)\n", + "\n", + "plt.tight_layout()\n", + "plt.show()\n", + "\n", + "print(\"\\nVisualization Insights:\")\n", + "print(\"The left panel shows weak correlation between talent and outcomes.\")\n", + "print(\n", + " \"The right panel shows strong correlation between beneficial events and outcomes.\"\n", + ")\n", + "print(\"Note the logarithmic vertical scale indicating multiplicative effects.\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Section 8: Top Performers Characterization\n", + "\n", + "We now examine the highest-achieving agents to test whether they possess exceptional talent or simply experienced favorable event sequences. If success were purely meritocratic, we would expect top performers to rank highly in talent. If randomness dominates, top performers should have average talent but above-average beneficial event counts." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "df_results[\"talent_rank\"] = df_results[\"talent_norm\"].rank(ascending=False)\n", + "df_results[\"capital_rank\"] = df_results[\"capital\"].rank(ascending=False)\n", + "\n", + "top_10 = df_results.nlargest(10, \"capital\").copy()\n", + "top_20 = df_results.nlargest(20, \"capital\").copy()\n", + "\n", + "print(\"Top Performers Analysis\")\n", + "print(\"=\" * 80)\n", + "print(\"\\nTop 10 Agents by Final Capital:\")\n", + "display_cols = [\n", + " \"id\",\n", + " \"capital\",\n", + " \"talent_norm\",\n", + " \"talent_rank\",\n", + " \"lucky_events\",\n", + " \"unlucky_events\",\n", + " \"net_events\",\n", + "]\n", + "print(top_10[display_cols].to_string(index=False))\n", + "\n", + "print(\"\\nAggregate Statistics for Top 10:\")\n", + "print(f\" Average talent rank: {top_10['talent_rank'].mean():.1f} out of 100\")\n", + "print(f\" Median talent rank: {top_10['talent_rank'].median():.1f} out of 100\")\n", + "print(f\" Average beneficial events: {top_10['lucky_events'].mean():.2f}\")\n", + "print(f\" Average detrimental events: {top_10['unlucky_events'].mean():.2f}\")\n", + "print(f\" Average net events: {top_10['net_events'].mean():.2f}\")\n", + "\n", + "print(\"\\nComparison to Population:\")\n", + "print(\n", + " f\" Population average talent rank: {df_results['talent_rank'].mean():.1f}\"\n", + ")\n", + "print(\n", + " f\" Population average beneficial events: {df_results['lucky_events'].mean():.2f}\"\n", + ")\n", + "print(f\" Population average net events: {df_results['net_events'].mean():.2f}\")\n", + "\n", + "print(\"\\nInterpretation:\")\n", + "avg_talent_rank = top_10[\"talent_rank\"].mean()\n", + "if avg_talent_rank > 40:\n", + " print(\n", + " f\" Top performers have BELOW AVERAGE talent (rank {avg_talent_rank:.0f}/100)\"\n", + " )\n", + "elif avg_talent_rank > 25:\n", + " print(\n", + " f\" Top performers have AVERAGE talent (rank {avg_talent_rank:.0f}/100)\"\n", + " )\n", + "else:\n", + " print(\n", + " f\" Top performers have ABOVE AVERAGE talent (rank {avg_talent_rank:.0f}/100)\"\n", + " )\n", + "\n", + "print(\n", + " f\" However, they experienced {top_10['lucky_events'].mean():.1f} beneficial events\"\n", + ")\n", + "print(f\" versus population average of {df_results['lucky_events'].mean():.1f}\")\n", + "print(\"\\n This demonstrates success is more strongly determined by fortunate\")\n", + "print(\" circumstances than by exceptional ability.\")\n", + "\n", + "# Statistical test\n", + "top_lucky = top_10[\"lucky_events\"].values\n", + "rest_lucky = df_results[~df_results[\"id\"].isin(top_10[\"id\"])][\n", + " \"lucky_events\"\n", + "].values\n", + "statistic, pvalue = mannwhitneyu(top_lucky, rest_lucky, alternative=\"greater\")\n", + "print(\"\\nMann-Whitney U test (top 10 vs others for beneficial events):\")\n", + "print(f\" U-statistic: {statistic:.2f}\")\n", + "print(f\" p-value: {pvalue:.6f}\")\n", + "if pvalue < 0.001:\n", + " print(\" Result: Highly significant difference (p < 0.001)\")\n", + "print(\n", + " \" Conclusion: Top performers experienced significantly more beneficial events.\"\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Section 9: Causal Inference Analysis - Double Machine Learning\n", + "\n", + "We now move beyond correlation to causal estimation. The challenge is confounding: talent affects both who receives beneficial events (treatment) and who can capitalize on them (outcome). Simply regressing outcomes on event counts conflates these pathways.\n", + "\n", + "Double Machine Learning (DML) addresses this by using flexible machine learning models to partial out the confounding influence of talent. The method proceeds in stages:\n", + "\n", + "1. Model the relationship between confounders (talent) and treatment (events)\n", + "2. Model the relationship between confounders and outcome (capital)\n", + "3. Use the residuals from these models to estimate the causal effect\n", + "\n", + "This approach provides consistent estimates even when the confounding relationships are complex and nonlinear." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(\"Fitting Double Machine Learning Model...\")\n", + "print(\" This may take 30-60 seconds depending on computational resources\")\n", + "\n", + "dml_model, ate_estimates, ate_mean, ate_std = fit_dml_model(\n", + " df_results, random_state=RANDOM_SEED\n", + ")\n", + "\n", + "print(\"\\n\" + \"=\" * 70)\n", + "print(\"DOUBLE MACHINE LEARNING RESULTS\")\n", + "print(\"=\" * 70)\n", + "\n", + "print(\"\\nAverage Treatment Effect (ATE):\")\n", + "print(f\" Point Estimate: {ate_mean:.5f}\")\n", + "print(f\" Standard Deviation: {ate_std:.5f}\")\n", + "\n", + "pct_increase = (np.exp(ate_mean) - 1) * 100\n", + "print(\"\\nInterpretation:\")\n", + "print(\n", + " f\" Each additional beneficial event increases log(capital) by {ate_mean:.5f}\"\n", + ")\n", + "print(\n", + " f\" This corresponds to approximately {pct_increase:.2f}% increase in capital\"\n", + ")\n", + "\n", + "print(\"\\nConcrete Example:\")\n", + "example_capital = 10000\n", + "after_one_event = example_capital * np.exp(ate_mean)\n", + "gain = after_one_event - example_capital\n", + "print(f\" Starting capital: ${example_capital:,}\")\n", + "print(f\" After one additional beneficial event: ${after_one_event:,.2f}\")\n", + "print(f\" Absolute gain: ${gain:,.2f}\")\n", + "\n", + "after_five_events = example_capital * np.exp(5 * ate_mean)\n", + "print(f\" After five additional beneficial events: ${after_five_events:,.2f}\")\n", + "print(\n", + " f\" Total gain from five events: ${after_five_events - example_capital:,.2f}\"\n", + ")\n", + "\n", + "print(\"\\nStatistical Significance:\")\n", + "if ate_mean > 2 * ate_std:\n", + " print(\n", + " \" The effect is statistically significant (estimate > 2 standard deviations)\"\n", + " )\n", + " print(\n", + " \" We can confidently conclude beneficial events have positive causal impact\"\n", + " )\n", + "else:\n", + " print(\" Statistical significance is moderate\")\n", + "\n", + "print(\"\\nKey Insight:\")\n", + "print(\n", + " \" This causal estimate controls for talent differences. Even among agents\"\n", + ")\n", + "print(\n", + " \" with identical talent, those who experience more beneficial events achieve\"\n", + ")\n", + "print(\n", + " \" substantially higher outcomes. This quantifies the pure effect of luck.\"\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Section 10: Heterogeneous Treatment Effects - Causal Forests\n", + "\n", + "While DML provides an average treatment effect, real-world impacts often vary across individuals. Some agents may benefit more from additional opportunities than others due to their particular combination of characteristics. Causal Forests estimate these Conditional Average Treatment Effects (CATE), revealing heterogeneity.\n", + "\n", + "This analysis answers questions like: Do high-IQ agents benefit more from opportunities? Do networking capabilities amplify treatment effects? Understanding heterogeneity informs targeting: resources should preferentially go to those who benefit most." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(\"Fitting Causal Forest Model...\")\n", + "print(\" Estimating heterogeneous treatment effects across the population\")\n", + "print(\" This may take 60-90 seconds\")\n", + "\n", + "cf_model, cate_estimates = fit_causal_forest(\n", + " df_results, random_state=RANDOM_SEED\n", + ")\n", + "df_results[\"cate\"] = cate_estimates\n", + "\n", + "print(\"\\n\" + \"=\" * 70)\n", + "print(\"CAUSAL FOREST RESULTS: Heterogeneous Treatment Effects\")\n", + "print(\"=\" * 70)\n", + "\n", + "print(\"\\nCATE Distribution Statistics:\")\n", + "cate_stats = pd.Series(cate_estimates).describe()\n", + "for stat_name, stat_value in cate_stats.items():\n", + " print(f\" {stat_name:10}: {stat_value:.6f}\")\n", + "\n", + "print(\"\\nHeterogeneity Metrics:\")\n", + "print(f\" Range (max - min): {cate_estimates.max() - cate_estimates.min():.6f}\")\n", + "print(\n", + " f\" Interquartile range: {np.percentile(cate_estimates, 75) - np.percentile(cate_estimates, 25):.6f}\"\n", + ")\n", + "print(\n", + " f\" Coefficient of variation: {cate_estimates.std() / abs(cate_estimates.mean()):.3f}\"\n", + ")\n", + "\n", + "print(\"\\nInterpretation:\")\n", + "print(\n", + " f\" Standard deviation of {cate_estimates.std():.6f} indicates substantial variation\"\n", + ")\n", + "print(\" in how different agents benefit from beneficial events.\")\n", + "print(\n", + " \"\\n Some agents (high CATE) benefit greatly from additional opportunities.\"\n", + ")\n", + "print(\" Other agents (low CATE) show modest benefits.\")\n", + "print(\" This heterogeneity has important implications for targeting.\")\n", + "\n", + "# Identify high and low CATE agents\n", + "high_cate = df_results.nlargest(10, \"cate\")\n", + "low_cate = df_results.nsmallest(10, \"cate\")\n", + "\n", + "print(\"\\nCharacteristics of High-CATE Agents (top 10):\")\n", + "print(\n", + " f\" Average IQ: {high_cate['talent_iq'].mean():.3f} vs population {df_results['talent_iq'].mean():.3f}\"\n", + ")\n", + "print(\n", + " f\" Average intensity: {high_cate['talent_intensity'].mean():.3f} vs population {df_results['talent_intensity'].mean():.3f}\"\n", + ")\n", + "print(\n", + " f\" Average networking: {high_cate['talent_networking'].mean():.3f} vs population {df_results['talent_networking'].mean():.3f}\"\n", + ")\n", + "\n", + "print(\"\\nCharacteristics of Low-CATE Agents (bottom 10):\")\n", + "print(\n", + " f\" Average IQ: {low_cate['talent_iq'].mean():.3f} vs population {df_results['talent_iq'].mean():.3f}\"\n", + ")\n", + "print(\n", + " f\" Average intensity: {low_cate['talent_intensity'].mean():.3f} vs population {df_results['talent_intensity'].mean():.3f}\"\n", + ")\n", + "print(\n", + " f\" Average networking: {low_cate['talent_networking'].mean():.3f} vs population {df_results['talent_networking'].mean():.3f}\"\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "lines_to_next_cell": 2 + }, + "outputs": [], + "source": [ + "fig, axes = plt.subplots(1, 3, figsize=(18, 5))\n", + "\n", + "# Panel 1: CATE Distribution\n", + "axes[0].hist(\n", + " df_results[\"cate\"],\n", + " bins=25,\n", + " edgecolor=\"black\",\n", + " alpha=0.7,\n", + " color=\"mediumseagreen\",\n", + ")\n", + "axes[0].axvline(\n", + " df_results[\"cate\"].mean(),\n", + " color=\"red\",\n", + " linestyle=\"--\",\n", + " linewidth=2,\n", + " label=f\"Mean: {df_results['cate'].mean():.5f}\",\n", + ")\n", + "axes[0].axvline(\n", + " df_results[\"cate\"].median(),\n", + " color=\"orange\",\n", + " linestyle=\":\",\n", + " linewidth=2,\n", + " label=f\"Median: {df_results['cate'].median():.5f}\",\n", + ")\n", + "axes[0].set_xlabel(\"Conditional Average Treatment Effect\", fontsize=11)\n", + "axes[0].set_ylabel(\"Frequency\", fontsize=11)\n", + "axes[0].set_title(\n", + " \"Distribution of Treatment Effects\", fontsize=12, fontweight=\"bold\"\n", + ")\n", + "axes[0].legend(fontsize=10)\n", + "axes[0].grid(axis=\"y\", alpha=0.3)\n", + "\n", + "# Panel 2: CATE vs Talent\n", + "axes[1].scatter(\n", + " df_results[\"talent_norm\"],\n", + " df_results[\"cate\"],\n", + " alpha=0.6,\n", + " s=50,\n", + " c=\"mediumseagreen\",\n", + " edgecolor=\"black\",\n", + " linewidth=0.5,\n", + ")\n", + "z = np.polyfit(df_results[\"talent_norm\"], df_results[\"cate\"], 1)\n", + "p = np.poly1d(z)\n", + "axes[1].plot(\n", + " df_results[\"talent_norm\"].sort_values(),\n", + " p(df_results[\"talent_norm\"].sort_values()),\n", + " \"r--\",\n", + " alpha=0.8,\n", + " linewidth=2,\n", + " label=\"Linear Fit\",\n", + ")\n", + "axes[1].set_xlabel(\"Talent Score\", fontsize=11)\n", + "axes[1].set_ylabel(\"Treatment Effect (CATE)\", fontsize=11)\n", + "axes[1].set_title(\n", + " \"Treatment Effect by Talent Level\", fontsize=12, fontweight=\"bold\"\n", + ")\n", + "axes[1].grid(True, alpha=0.3)\n", + "axes[1].legend(fontsize=10)\n", + "\n", + "# Panel 3: CATE vs Current Success\n", + "axes[2].scatter(\n", + " df_results[\"capital\"],\n", + " df_results[\"cate\"],\n", + " alpha=0.6,\n", + " s=50,\n", + " c=\"mediumseagreen\",\n", + " edgecolor=\"black\",\n", + " linewidth=0.5,\n", + ")\n", + "axes[2].set_xlabel(\"Final Capital ($)\", fontsize=11)\n", + "axes[2].set_ylabel(\"Treatment Effect (CATE)\", fontsize=11)\n", + "axes[2].set_title(\n", + " \"Treatment Effect by Success Level\", fontsize=12, fontweight=\"bold\"\n", + ")\n", + "axes[2].set_xscale(\"log\")\n", + "axes[2].grid(True, alpha=0.3)\n", + "\n", + "plt.tight_layout()\n", + "plt.show()\n", + "\n", + "print(\"\\nVisualization Insights:\")\n", + "print(\"Left panel: CATE distribution shows heterogeneity across population\")\n", + "print(\n", + " \"Middle panel: Relationship between baseline talent and treatment responsiveness\"\n", + ")\n", + "print(\n", + " \"Right panel: Whether current success level predicts benefit from opportunities\"\n", + ")\n", + "print(\"\\nThese patterns inform optimal resource allocation strategies.\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "lines_to_next_cell": 2 + }, + "source": [ + "## Section 11: Policy Simulation and Comparison\n", + "\n", + "We now apply our causal estimates to evaluate alternative resource allocation policies. Given a fixed budget, how should resources be distributed to maximize total welfare, minimize inequality, or achieve other objectives?\n", + "\n", + "We compare five allocation strategies:\n", + "\n", + "1. **Egalitarian:** Equal distribution regardless of characteristics\n", + "2. **Meritocratic:** Proportional to measured talent\n", + "3. **Random:** Stochastic allocation\n", + "4. **Success-Based:** Proportional to current capital (winner-take-more)\n", + "5. **CATE-Optimal:** Proportional to estimated treatment effects\n", + "\n", + "For each policy, we simulate adding resources and evaluate resulting outcomes." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "policy_comparison = compare_allocation_policies(df_results)\n", + "\n", + "print(\"Policy Comparison: Resource Allocation Strategies\")\n", + "print(\"=\" * 100)\n", + "print(policy_comparison.to_string(index=False))\n", + "\n", + "print(\"\\n\" + \"=\" * 100)\n", + "print(\"POLICY EVALUATION\")\n", + "print(\"=\" * 100)\n", + "\n", + "best_total = policy_comparison.loc[\n", + " policy_comparison[\"Total Capital\"].idxmax(), \"Policy\"\n", + "]\n", + "best_equality = policy_comparison.loc[\n", + " policy_comparison[\"Gini Coefficient\"].idxmin(), \"Policy\"\n", + "]\n", + "best_bottom = policy_comparison.loc[\n", + " policy_comparison[\"Bottom 50% Share\"].idxmax(), \"Policy\"\n", + "]\n", + "\n", + "print(\"\\nWelfare Maximization:\")\n", + "print(f\" Highest total capital: {best_total}\")\n", + "print(\n", + " f\" Amount: ${policy_comparison.loc[policy_comparison['Policy'] == best_total, 'Total Capital'].values[0]:.2f}\"\n", + ")\n", + "\n", + "print(\"\\nEquality Optimization:\")\n", + "print(f\" Lowest Gini coefficient: {best_equality}\")\n", + "print(\n", + " f\" Gini: {policy_comparison.loc[policy_comparison['Policy'] == best_equality, 'Gini Coefficient'].values[0]:.4f}\"\n", + ")\n", + "\n", + "print(\"\\nBottom-Up Distribution:\")\n", + "print(f\" Highest bottom 50% share: {best_bottom}\")\n", + "print(\n", + " f\" Share: {policy_comparison.loc[policy_comparison['Policy'] == best_bottom, 'Bottom 50% Share'].values[0]:.1%}\"\n", + ")\n", + "\n", + "print(\"\\nKey Findings:\")\n", + "print(\" 1. CATE-optimal allocation leverages causal estimates for targeting\")\n", + "print(\" 2. Pure meritocracy often underperforms due to measurement error\")\n", + "print(\" 3. Success-based allocation amplifies existing inequality\")\n", + "print(\n", + " \" 4. Egalitarian approaches provide reasonable welfare with better equality\"\n", + ")\n", + "print(\n", + " \" 5. Random allocation can outperform sophisticated targeting if measurement is poor\"\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Section 12: Comprehensive Results Summary\n", + "\n", + "We conclude by consolidating all major findings into a comprehensive summary suitable for presentation or reporting." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(\"=\" * 80)\n", + "print(\"COMPREHENSIVE SIMULATION ANALYSIS SUMMARY\")\n", + "print(\"=\" * 80)\n", + "print()\n", + "\n", + "print(\"1. EXPERIMENTAL DESIGN\")\n", + "print(f\" Population size: {N_AGENTS} agents\")\n", + "print(f\" Time horizon: {N_ROUNDS} periods\")\n", + "print(f\" Events per period: {EVENTS_PER_ROUND}\")\n", + "print(f\" Total events: {N_ROUNDS * EVENTS_PER_ROUND}\")\n", + "print(\" Initial capital: $1.00 per agent\")\n", + "print()\n", + "\n", + "print(\"2. EMERGENT INEQUALITY\")\n", + "print(f\" Gini coefficient: {gini:.4f}\")\n", + "print(\n", + " \" Interpretation: Moderate overall inequality emerged, alongside extreme dispersion in top outcomes\"\n", + ")\n", + "print(f\" Top 10% wealth share: {top10_share * 100:.1f}%\")\n", + "print(f\" Top 20% wealth share: {top20_share * 100:.1f}%\")\n", + "print(f\" Capital range: {df_results['capital'].max() / df_results['capital'].min():.1f}x (max/min)\")\n", + "print()\n", + "\n", + "print(\"3. CORRELATION ANALYSIS\")\n", + "print(f\" Talent → Log(Capital): r = {corr_talent:.4f}\")\n", + "print(f\" Beneficial Events → Log(Capital): r = {corr_luck:.4f}\")\n", + "print(f\" Relative strength (magnitude): {abs(corr_luck) / max(abs(corr_talent), 1e-12):.2f}x\")\n", + "print(\n", + " \" Conclusion: Event exposure is more strongly associated with outcomes than talent in this run\"\n", + ")\n", + "print()\n", + "\n", + "print(\"4. TOP PERFORMERS CHARACTERIZATION\")\n", + "print(\n", + " f\" Average talent rank of top 10: {top_10['talent_rank'].mean():.1f} / {N_AGENTS}\"\n", + ")\n", + "print(\n", + " f\" Population average talent rank: {df_results['talent_rank'].mean():.1f} / {N_AGENTS}\"\n", + ")\n", + "print(f\" Avg beneficial events (top 10): {top_10['lucky_events'].mean():.2f}\")\n", + "print(f\" Population avg beneficial events: {df_results['lucky_events'].mean():.2f}\")\n", + "print(\n", + " \" Conclusion: Top outcomes align more with favorable event histories than exceptional talent\"\n", + ")\n", + "print()\n", + "\n", + "print(\"5. CAUSAL INFERENCE RESULTS\")\n", + "print(\" See DML and Causal Forest sections above for causal effect estimates\")\n", + "print()\n", + "\n", + "print(\"6. POLICY IMPLICATIONS\")\n", + "print(\n", + " \" Under the current simulation, egalitarian allocation performs best on welfare and inequality.\"\n", + ")\n", + "print(\n", + " \" Targeted allocation may outperform under alternative objectives or parameter regimes.\"\n", + ")\n", + "print()\n", + "\n", + "print(\"=\" * 80)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Conclusion\n", + "\n", + "This analysis shows how a very simple world can produce very unequal outcomes.\n", + "\n", + "Everyone starts with the same initial capital and broadly similar talents. Over time, however, they experience **random beneficial and detrimental events** whose effects compound multiplicatively. That combination — normal talent, random shocks, and compounding — is enough to generate highly skewed, power-law-like success distributions.\n", + "\n", + "### Empirical patterns\n", + "\n", + "Across typical runs of the simulation, we see that:\n", + "\n", + "1. **Normal inputs, heavy-tailed outputs**\n", + " Talent is roughly normal, but final capital is strongly right-skewed with a long tail of big winners.\n", + "\n", + "2. **Luck dominates correlations**\n", + " The correlation between the number of lucky events and log(final capital) is much stronger than the correlation between talent and log(final capital). In many runs, the “luck vs talent” correlation ratio is on the order of 10:1.\n", + "\n", + "3. **Top performers are not the top talents**\n", + " The agents with the highest final capital usually have **average** talent but unusually many lucky events. Exceptional success tends to reflect being “lucky among the good enough” rather than being uniquely gifted.\n", + "\n", + "4. **Inequality emerges quickly**\n", + " Even over 80 periods, Gini coefficients in the 0.30–0.50 range are common, despite identical starting wealth.\n", + "\n", + "### Causal estimates\n", + "\n", + "Simple correlations can be misleading because talent affects both exposure\n", + "to events and the ability to exploit them. To get closer to causality, the\n", + "notebook uses **Double Machine Learning (DML)** and **Causal Forests**. DML\n", + "estimates the **average causal effect** of one additional lucky event on\n", + "log(final capital), controlling for talent as a confounder. Causal Forests\n", + "then estimate **heterogeneous effects (CATEs)**, showing how the effect of\n", + "luck varies with traits like IQ, intensity, and networking.\n", + "\n", + "Typical results suggest that each additional lucky event raises expected final capital by roughly **10-15%**, even after adjusting for talent, and that agents with higher IQ or networking often benefit more from extra opportunities.\n", + "\n", + "### Policy implications\n", + "\n", + "Because outcomes are so sensitive to random events, purely meritocratic allocation rules (e.g., “give more resources to those who are already ahead”) tend to **reinforce inequality** rather than maximize total success.\n", + "\n", + "The policy experiments in this project point to three consistent findings.\n", + "**Broad, egalitarian allocation** of resources often performs surprisingly\n", + "well in aggregate. **Performance-based allocation** amplifies inequality and\n", + "is the least efficient in many runs. And **randomized or diversified\n", + "allocation** strategies can be competitive with, or even superior to, naive\n", + "merit-based rules when luck plays a large role.\n", + "\n", + "### Takeaways\n", + "\n", + "For individuals, the model is a reminder to stay humble about success and compassionate about failure: both are more influenced by chance than we usually admit.\n", + "\n", + "For policymakers and institutions, it highlights the value of **expanding opportunity** rather than trying to perfectly identify “the best” in advance. When randomness and compounding dominate, it is often better to give many people a chance and let luck and talent interact over time.\n", + "\n", + "Finally, for researchers and students, this project illustrates how **agent-based simulation** and **causal machine learning** can work together: simulation creates a controlled world with known mechanisms, and causal tools help recover those mechanisms from data — much like in real empirical work." + ] + } + ], + "metadata": { + "jupytext": { + "formats": "ipynb,py:percent" + }, + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.13" + }, + "nbformat": 4, + "nbformat_minor": 5 + }, + "nbformat": 4, + "nbformat_minor": 4 +} \ No newline at end of file diff --git a/research/A_Causal_Analysis_of_Success_in_Modern_Society/causal_success_example.py b/research/A_Causal_Analysis_of_Success_in_Modern_Society/causal_success.example.py similarity index 67% rename from research/A_Causal_Analysis_of_Success_in_Modern_Society/causal_success_example.py rename to research/A_Causal_Analysis_of_Success_in_Modern_Society/causal_success.example.py index 8b35b0fdf..507bf30e7 100644 --- a/research/A_Causal_Analysis_of_Success_in_Modern_Society/causal_success_example.py +++ b/research/A_Causal_Analysis_of_Success_in_Modern_Society/causal_success.example.py @@ -1,6 +1,7 @@ # --- # jupyter: # jupytext: +# formats: ipynb,py:percent # text_representation: # extension: .py # format_name: percent @@ -18,7 +19,6 @@ import logging import sys -from pathlib import Path import numpy as np import pandas as pd @@ -51,28 +51,25 @@ # # ## What this notebook does # -# This notebook walks through the entire analysis pipeline for the project *“A Causal Analysis of Success in Modern Society.”* -# You will: -# -# - simulate a population of agents with different talents, -# - expose them to good and bad events that compound over time, -# - measure how unequal the final outcomes become, -# - and use modern causal inference tools (Double Machine Learning and Causal Forests) to separate **talent** from **luck**. +# This notebook walks through the entire analysis pipeline for the project *“A Causal Analysis of Success in Modern Society.”* +# You will simulate a population of agents with different talents, expose them +# to good and bad events that compound over time, measure how unequal the final +# outcomes become, and then use modern causal inference tools (Double Machine +# Learning and Causal Forests) to separate **talent** from **luck**. # # The goal is not to perfectly model the real world. Instead, the goal is to understand a simple but powerful mechanism: # # > If abilities are roughly “normal” but success is extremely unequal, then **random multiplicative events** must be doing a lot of the work. # -# This notebook is meant to be **interactive**: -# -# - Run each section in order. -# - Look at the printed summaries and plots. -# - Then tweak parameters (number of agents, number of events, event magnitudes) and see what changes. +# The notebook is meant to be **interactive**. Run each section in order, look +# at the printed summaries and plots, and then tweak the parameters (number of +# agents, number of events, event magnitudes) to see what changes. # -# For a higher-level narrative and more theory: -# - See `README.md` for the big-picture motivation and results. -# - See `causal_success_tutorial.md` for a detailed written tutorial. -# - See `causal_success_API.md` for function-level documentation of `causal_success_utils.py`. +# For a higher-level narrative and more theory, `README.md` has the big-picture +# motivation and results, the file +# `all.learn_Causal_Analysis_of_Success_in_60_minutes.how_to_guide.md` is the +# detailed written tutorial, and `causal_success.API.ipynb` walks through the +# function-level documentation of `causal_success_utils.py`. # # %% [markdown] @@ -87,27 +84,20 @@ # # %% -import importlib -import os - from scipy import stats -from sklearn.ensemble import RandomForestRegressor -from econml.dml import LinearDML, CausalForestDML - -import causal_success_utils - -importlib.reload(causal_success_utils) +from scipy.stats import mannwhitneyu -# Import everything the notebook uses from the utils module. from causal_success_utils import ( create_population, run_simulation, calculate_gini, get_results_dataframe, + fit_dml_model, + fit_causal_forest, + compare_allocation_policies, ) -# Configure plotting and numpy. -np.random.seed(42) +# Configure plotting. sns.set_style("whitegrid") plt.rcParams["figure.figsize"] = (14, 6) plt.rcParams["font.size"] = 10 @@ -149,138 +139,76 @@ _LOG.info("Events per round: %s", EVENTS_PER_ROUND) _LOG.info("Random seed: %s", RANDOM_SEED) -# %% -# =============================== -# Re-run simulation using config -# =============================== - -# Safety check: ensure configuration cell has been run -assert "N_AGENTS" in globals(), "Experimental configuration cell was not run." -assert "RANDOM_SEED" in globals(), "Experimental configuration cell was not run." - -# 1) Build population using the configured number of agents and seed -agents = create_population(n_agents=N_AGENTS, seed=RANDOM_SEED) - -# 2) Run simulation using ONLY the config values defined above -agents = run_simulation( - agents=agents, - n_periods=N_ROUNDS, - n_lucky_events_per_period=LUCKY_EVENTS_PER_ROUND, - n_unlucky_events_per_period=UNLUCKY_EVENTS_PER_ROUND, - lucky_mean=LUCKY_MEAN, - lucky_std=LUCKY_STD, - unlucky_mean=UNLUCKY_MEAN, - unlucky_std=UNLUCKY_STD, - seed=RANDOM_SEED, - verbose=True, -) - -# 3) Create results dataframe and derived quantities -df_results = get_results_dataframe(agents) -df_results["log_capital"] = np.log(df_results["capital"]) - -# Inequality metrics -gini = calculate_gini(df_results["capital"].values) -top10_share = ( - df_results.nlargest(max(1, len(df_results) // 10), "capital")[ - "capital" - ].sum() - / df_results["capital"].sum() -) -top20_share = ( - df_results.nlargest(max(1, len(df_results) // 5), "capital")["capital"].sum() - / df_results["capital"].sum() -) -cap_range = df_results["capital"].max() / df_results["capital"].min() - -# Correlations: talent vs outcomes and luck vs outcomes -talent_corr = df_results["talent_norm"].corr(df_results["log_capital"]) -luck_corr = df_results["lucky_events"].corr(df_results["log_capital"]) -relative_strength = abs(luck_corr) / max(abs(talent_corr), 1e-12) - -# 4) Top performers summary -top_n = 10 -top_df = df_results.nlargest(top_n, "capital").copy() - -# Rank talent so rank=1 is highest talent -df_results["talent_rank"] = df_results["talent_norm"].rank(ascending=False) - -avg_top_talent_rank = top_df.merge(df_results[["id", "talent_rank"]], on="id")[ - "talent_rank" -].mean() -avg_pop_talent_rank = df_results["talent_rank"].mean() - -avg_top_lucky = top_df["lucky_events"].mean() -avg_pop_lucky = df_results["lucky_events"].mean() - -print("Simulation rerun completed with configured parameters.") -print(f" Gini coefficient: {gini:.4f}") -print(f" Top 10% wealth share: {top10_share:.3f}") -print(f" Top 20% wealth share: {top20_share:.3f}") -print(f" Capital range (max/min): {cap_range:.1f}x") -print(f" Corr(talent, log capital): {talent_corr:.3f}") -print(f" Corr(lucky events, log capital): {luck_corr:.3f}") -print(f" Relative strength |luck|/|talent|: {relative_strength:.2f}x") # %% [markdown] # ## Section 2: Theoretical Framework # -# In this section we spell out the model that drives the simulation: how we represent “talent,” how random events affect people over time, and how we frame the causal question about luck and success. -# -# --- +# This section lays out the model that drives the simulation. We describe how +# talent is represented, how random events affect people over time, and how we +# frame the causal question about luck and success. # # ### 2.1 Model Specification # -# Each agent \(i\) is described by a talent vector \(T_i\) with several components. These dimensions are not meant to be perfect psychological constructs, but convenient knobs that capture different ways people can be “good at” navigating opportunities. -# -# - **Intensity (\(t_{\text{intensity}}\))** -# Intensity stands in for effort, persistence, and general activity level. In the model, this drives **exposure to events**: high-intensity agents “show up” more often, talk to more people, and try more things, so they are more likely to bump into both good and bad events. This is our formalization of the “surface area of luck” idea. -# -# - **IQ (\(t_{\text{iq}}\))** -# IQ represents cognitive ability and problem-solving skill. Intensity determines how many opportunities you see; IQ affects the **probability of turning a lucky event into an actual gain**. An agent with high intensity but low IQ may see many chances but fail to convert them; high IQ but very low intensity may simply not be in the right place at the right time. -# -# - **Networking (\(t_{\text{networking}}\))** -# Networking measures social capital: the strength and reach of an agent’s relationships. In the simulation, this allows opportunities to **spill over** from one agent to another. A lucky event that hits one person can sometimes partially benefit someone else with strong connections, mirroring referrals, recommendations, and “who you know” effects. -# -# - **Initial Capital (\(C_{0}\))** -# All agents begin with the same initial capital in the baseline setup, typically \(C_0 = 1\). This isolates the role of random events and talent. Initial capital gives everyone a baseline but, in the core model, it does **not** affect event probabilities directly. -# -# Together, these components give each agent a fixed talent profile that shapes how they interact with randomness over time. -# -# --- +# Each agent \(i\) is described by a talent vector \(T_i\) with several +# components. These dimensions are not meant to be perfect psychological +# constructs, but convenient knobs that capture different ways people can be +# “good at” navigating opportunities. +# +# **Intensity (\(t_{\text{intensity}}\))** stands in for effort, persistence, +# and general activity level. In the model, this drives **exposure to events**. +# High-intensity agents show up more often, talk to more people, and try more +# things, so they are more likely to bump into both good and bad events. This +# is our formalization of the “surface area of luck” idea. +# +# **IQ (\(t_{\text{iq}}\))** represents cognitive ability and problem-solving +# skill. Where intensity determines how many opportunities you see, IQ affects +# the **probability of turning a lucky event into an actual gain**. An agent +# with high intensity but low IQ may see many chances but fail to convert them, +# while high IQ with very low intensity simply means you're not in the right +# place at the right time. +# +# **Networking (\(t_{\text{networking}}\))** measures social capital, i.e., the +# strength and reach of an agent’s relationships. In the simulation, this lets +# opportunities **spill over** from one agent to another. A lucky event that +# hits one person can sometimes partially benefit someone else with strong +# connections, mirroring referrals, recommendations, and "who you know" +# effects. +# +# **Initial Capital (\(C_{0}\))** is the starting wealth level. All agents +# begin with the same value in the baseline setup, typically \(C_0 = 1\), which +# isolates the role of random events and talent. Initial capital gives everyone +# a baseline but does **not** affect event probabilities directly. +# +# Taken together, these components give each agent a fixed talent profile that +# shapes how they interact with randomness over time. # # ### 2.2 Event Mechanics # -# At each time period, agents may experience **events** that change their capital. Events have three key ingredients: -# -# - A **type**: -# - Beneficial (“lucky”) -# - Detrimental (“unlucky”) -# -# - An **impact magnitude \(\Delta\)**: -# - Lucky events: sampled from a normal distribution with a positive mean (e.g., 25–35%), then clipped to a reasonable range (e.g., 5–50%). -# - Unlucky events: sampled from a normal distribution with a smaller positive mean (interpreted as a loss) and clipped similarly (e.g., 5–30%). -# -# - An **assignment probability**: -# - Who actually receives each event is determined probabilistically, based on talent (primarily intensity, with networking affecting spillovers). -# -# Capital evolves **multiplicatively**: -# -# - Beneficial event: -# \[ -# C_{i,t+1} = C_{i,t} \times (1 + \Delta) -# \] -# -# - Detrimental event: -# \[ -# C_{i,t+1} = C_{i,t} \times (1 - \Delta) -# \] -# -# This multiplicative structure is the core of the model. Under additive dynamics, everyone’s capital shifts by similar absolute amounts, and initial gaps tend to persist but not explode. Under multiplicative dynamics, **percentage changes** are what matter, so a 20% gain on \$1 and a 20% gain on \$1000 look very different in absolute terms. Over many periods, small differences in event histories can lead to large differences in outcomes. -# -# We also enforce a small capital floor (e.g., \$0.01) to avoid negative or zero values, which keeps the model numerically stable and allows us to safely take logarithms. -# -# --- +# At each time period, agents may experience **events** that change their +# capital. Events have three key ingredients. First, a **type**, either +# beneficial ("lucky") or detrimental ("unlucky"). Second, an **impact +# magnitude \(\Delta\)**. Lucky events are sampled from a normal distribution +# with a positive mean (e.g., 25 to 35%), then clipped to a reasonable range +# such as 5 to 50%. Unlucky events are sampled similarly with a smaller +# positive mean (interpreted as a loss) and clipped to 5 to 30%. Third, an +# **assignment probability**: who actually receives each event is determined +# probabilistically from talent, mostly intensity, with networking affecting +# spillovers. +# +# Capital evolves **multiplicatively**. A beneficial event applies +# \(C_{i,t+1} = C_{i,t} \times (1 + \Delta)\), while a detrimental event +# applies \(C_{i,t+1} = C_{i,t} \times (1 - \Delta)\). +# +# This multiplicative structure is the core of the model. Under additive +# dynamics, everyone’s capital shifts by similar absolute amounts, and initial +# gaps tend to persist but not explode. Under multiplicative dynamics, +# **percentage changes** are what matter, so a 20% gain on \$1 and a 20% gain +# on \$1000 look very different in absolute terms. Over many periods, small +# differences in event histories can lead to large differences in outcomes. +# +# We also enforce a small capital floor (e.g., \$0.01) to avoid negative or +# zero values, which keeps the model numerically stable and lets us safely take +# logarithms. # # ### 2.3 Causal Inference Framework # @@ -288,45 +216,42 @@ # # > *What is the effect of experiencing additional beneficial events on final success, after accounting for differences in talent?* # -# The difficulty is that **treatment is not randomly assigned**. More talented agents may both receive more opportunities and be better at using them. If we simply regress outcomes on the number of lucky events, we would mix up three things: -# -# 1. The true causal effect of lucky events -# 2. The fact that high-talent agents get more opportunities -# 3. The fact that high-talent agents would do well even with fewer events -# -# To disentangle these pieces, we define: -# -# - **Treatment variable \(T\)** -# The count of beneficial (lucky) events an agent experiences over the simulation. -# -# - **Outcome variable \(Y\)** -# Final log capital, \(\log(C_{\text{final}})\). -# Using the logarithm makes multiplicative effects more additive and stabilizes variance, so a one-unit change in \(Y\) roughly corresponds to a percentage change in wealth. -# -# - **Confounders \(X\)** -# The talent dimensions: intensity, IQ, networking, and any other features that influence both how many lucky events an agent gets and how well they convert those events into capital. -# -# With this setup, the target quantity is the **causal effect of \(T\) on \(Y\)**, holding \(X\) fixed. -# -# We use two complementary tools: -# -# 1. **Double Machine Learning (DML)** -# - Model how treatment \(T\) depends on talents \(X\) (who tends to get more opportunities). -# - Model how outcome \(Y\) depends on talents \(X\) (who tends to do well given their abilities). -# - Remove the part of \(T\) and \(Y\) that can be explained by \(X\), then estimate the effect of the remaining (residual) variation in \(T\) on the residual in \(Y\). -# This procedure corrects for confounding under fairly general conditions and gives an estimate of the **average treatment effect** of an additional lucky event. -# -# 2. **Causal Forests (CF)** -# - Extend the idea above to allow the treatment effect to vary with \(X\). -# - Instead of one global effect, we obtain a **Conditional Average Treatment Effect (CATE)** for each agent or subgroup. -# This reveals heterogeneity: some combinations of intensity, IQ, and networking benefit more from extra opportunities than others. -# -# Together, DML and causal forests let us answer both: -# -# - “On average, how much does one more lucky event change final outcomes?” -# - “For which types of agents is that extra event especially valuable?” -# -# The remaining sections of thetutorial put this framework into practice using the simulated data generated by our agent-based model. +# The difficulty is that **treatment is not randomly assigned**. More talented +# agents may both receive more opportunities and be better at using them. If we +# simply regress outcomes on the number of lucky events, we would mix up three +# things at once: the true causal effect of lucky events, the fact that +# high-talent agents get more opportunities, and the fact that high-talent +# agents would do well even with fewer events. +# +# To untangle these pieces, we define the **treatment variable \(T\)** as the +# count of beneficial (lucky) events an agent experiences over the simulation. +# The **outcome variable \(Y\)** is the final log capital, +# \(\log(C_{\text{final}})\). Using the logarithm makes multiplicative effects +# more additive and stabilizes variance, so a one-unit change in \(Y\) roughly +# corresponds to a percentage change in wealth. The **confounders \(X\)** are +# the talent dimensions (intensity, IQ, networking) and any other features +# that influence both how many lucky events an agent receives and how well +# they convert those events into capital. With this setup, the target quantity +# is the **causal effect of \(T\) on \(Y\)**, holding \(X\) fixed. +# +# Two complementary tools handle this. **Double Machine Learning (DML)** first +# models how \(T\) depends on \(X\) (who tends to get more opportunities) and +# how \(Y\) depends on \(X\) (who tends to do well given their abilities), +# removes the part of \(T\) and \(Y\) that can be explained by \(X\), and then +# estimates the effect of the remaining residual variation in \(T\) on the +# residual in \(Y\). This corrects for confounding under fairly general +# conditions and yields an estimate of the **average treatment effect** of an +# additional lucky event. **Causal Forests (CF)** extend the same idea to let +# the treatment effect vary with \(X\), so instead of one global effect we +# obtain a **Conditional Average Treatment Effect (CATE)** for each agent or +# subgroup. This reveals heterogeneity: some combinations of intensity, IQ, +# and networking benefit more from extra opportunities than others. +# +# Together, DML and Causal Forests answer two questions at once. On average, +# how much does one more lucky event change final outcomes? And for which +# types of agents is that extra event especially valuable? The remaining +# sections put this framework into practice using the simulated data generated +# by our agent-based model. # # %% [markdown] @@ -336,18 +261,16 @@ # # We work with a population of **100 agents**, each with a set of talent dimensions drawn from a normal distribution centered at 0.5 with a moderate spread. This choice mirrors a common empirical pattern: most human abilities cluster around an average level, with fewer people at the extremes. # -# Because our talent dimensions represent probabilities or normalized scores, we **clip all values to the \([0, 1]\) range**. This keeps the interpretation straightforward: -# -# - 0 means “very low” on that dimension -# - 1 means “very high” -# - values near 0.5 represent typical, “average” capability +# Because our talent dimensions represent probabilities or normalized scores, +# we **clip all values to the \([0, 1]\) range**. This keeps the interpretation +# straightforward: 0 means "very low" on that dimension, 1 means "very high," +# and values near 0.5 represent typical, "average" capability. # -# At this stage, all agents also receive the **same initial capital** (usually \(C_0 = 1\)). Any inequality that emerges later in the tutorial will therefore come from differences in event histories and talent interactions, not from unequal starting points. This makes it easier to see how randomness and ability combine to create unequal outcome over time. +# At this stage, all agents also receive the **same initial capital** (usually \(C_0 = 1\)). Any inequality that emerges later in the tutorial will therefore come from differences in event histories and talent interactions, not from unequal starting points. This makes it easier to see how randomness and ability combine to create unequal outcomes over time. # # %% -N_AGENTS = 100 -agents = create_population(n_agents=N_AGENTS, seed=42) +agents = create_population(n_agents=N_AGENTS, seed=RANDOM_SEED) print(f"Population initialized: {len(agents)} agents") print(f"Each agent has {len(agents[0].talent)} talent dimensions") @@ -403,32 +326,32 @@ # We implement helper functions for event generation, assignment, and simulation execution. # %% -# Run the simulation using our run_simulation function +# Run the simulation using configured parameters. print("Starting simulation...") print(f" - Agents: {N_AGENTS}") -print(" - Time periods: 80") -print(" - Lucky events per period: 5") -print(" - Unlucky events per period: 5") +print(f" - Time periods: {N_ROUNDS}") +print(f" - Lucky events per period: {LUCKY_EVENTS_PER_ROUND}") +print(f" - Unlucky events per period: {UNLUCKY_EVENTS_PER_ROUND}") print() agents = run_simulation( agents=agents, - n_periods=80, - n_lucky_events_per_period=5, - n_unlucky_events_per_period=5, - lucky_mean=0.25, - lucky_std=0.08, - unlucky_mean=0.15, - unlucky_std=0.05, - seed=42, - verbose=True, # Shows progress bar -) - -print("\n Simulation complete!") -print(f" Total agents: {len(agents)}") -print(f" Mean lucky events: {np.mean([a.lucky_events for a in agents]):.1f}") + n_periods=N_ROUNDS, + n_lucky_events_per_period=LUCKY_EVENTS_PER_ROUND, + n_unlucky_events_per_period=UNLUCKY_EVENTS_PER_ROUND, + lucky_mean=LUCKY_MEAN, + lucky_std=LUCKY_STD, + unlucky_mean=UNLUCKY_MEAN, + unlucky_std=UNLUCKY_STD, + seed=RANDOM_SEED, + verbose=True, +) + +print("\nSimulation complete!") +print(f" Total agents: {len(agents)}") +print(f" Mean lucky events: {np.mean([a.lucky_events for a in agents]):.1f}") print( - f" Mean unlucky events: {np.mean([a.unlucky_events for a in agents]):.1f}" + f" Mean unlucky events: {np.mean([a.unlucky_events for a in agents]):.1f}" ) # %% [markdown] @@ -623,7 +546,7 @@ # We now examine which factors correlate more strongly with final outcomes. Standard Pearson correlations quantify linear relationships between variables. We compare correlations between: # # 1. Talent and log(capital) -# 2. Beneficial events and log(capital) +# 2. Beneficial events and log(capital) # 3. Net events (beneficial minus detrimental) and log(capital) # # The log transformation of capital improves linearity and interpretability. @@ -795,8 +718,6 @@ print(" circumstances than by exceptional ability.") # Statistical test -from scipy.stats import mannwhitneyu - top_lucky = top_10["lucky_events"].values rest_lucky = df_results[~df_results["id"].isin(top_10["id"])][ "lucky_events" @@ -825,48 +746,13 @@ # This approach provides consistent estimates even when the confounding relationships are complex and nonlinear. # %% -Y = np.log(df_results["capital"].values + 1) -T = df_results["lucky_events"].values -X = df_results[["talent_intensity", "talent_iq", "talent_networking"]].values - -print("Causal Inference Setup") -print("=" * 70) -print("\nVariable Definitions:") -print(" Outcome (Y): Log-transformed final capital") -print(" Transformation reason: Normalization and interpretability") -print(f" Shape: {Y.shape}") -print(f" Range: [{Y.min():.3f}, {Y.max():.3f}]") - -print("\n Treatment (T): Count of beneficial events experienced") -print(f" Shape: {T.shape}") -print(f" Range: [{T.min():.0f}, {T.max():.0f}]") -print(f" Mean: {T.mean():.2f}") - -print("\n Confounders (X): Talent dimensions") -print(" Dimensions: Intensity, IQ, Networking") -print(f" Shape: {X.shape}") -print(" These affect both treatment assignment and outcome potential") - -print("\nFitting Double Machine Learning Model...") +print("Fitting Double Machine Learning Model...") print(" This may take 30-60 seconds depending on computational resources") -dml_model = LinearDML( - model_y=RandomForestRegressor( - n_estimators=100, max_depth=10, random_state=42 - ), - model_t=RandomForestRegressor( - n_estimators=100, max_depth=10, random_state=42 - ), - discrete_treatment=False, - random_state=42, +dml_model, ate_estimates, ate_mean, ate_std = fit_dml_model( + df_results, random_state=RANDOM_SEED ) -dml_model.fit(Y, T, X=X) - -ate_estimates = dml_model.const_marginal_effect(X) -ate_mean = ate_estimates.mean() -ate_std = ate_estimates.std() - print("\n" + "=" * 70) print("DOUBLE MACHINE LEARNING RESULTS") print("=" * 70) @@ -932,22 +818,9 @@ print(" Estimating heterogeneous treatment effects across the population") print(" This may take 60-90 seconds") -cf_model = CausalForestDML( - model_y=RandomForestRegressor( - n_estimators=100, max_depth=10, random_state=42 - ), - model_t=RandomForestRegressor( - n_estimators=100, max_depth=10, random_state=42 - ), - discrete_treatment=False, - n_estimators=100, - max_depth=10, - random_state=42, +cf_model, cate_estimates = fit_causal_forest( + df_results, random_state=RANDOM_SEED ) - -cf_model.fit(Y, T, X=X) - -cate_estimates = cf_model.effect(X) df_results["cate"] = cate_estimates print("\n" + "=" * 70) @@ -1113,79 +986,8 @@ # # For each policy, we simulate adding resources and evaluate resulting outcomes. -# %% -def compare_allocation_policies(df_results): - """ - Evaluate multiple resource allocation strategies. - - Parameters: - ----------- - df_results : DataFrame - Population data including talents, capitals, and CATE estimates - - Returns: - -------- - DataFrame - Policy comparison results including welfare and inequality metrics - """ - n_agents = len(df_results) - budget = n_agents * 1.0 - baseline_capital = df_results["capital"].values - - policies = {} - - # Policy 1: Egalitarian - policies["Egalitarian"] = np.ones(n_agents) * (budget / n_agents) - - # Policy 2: Meritocratic (proportional to talent) - talent_scores = ( - df_results[["talent_intensity", "talent_iq", "talent_networking"]] - .sum(axis=1) - .values - ) - talent_scores = np.maximum(talent_scores, 0.01) # Avoid division by zero - policies["Meritocratic"] = budget * (talent_scores / talent_scores.sum()) - - # Policy 3: Random - random_weights = np.random.random(n_agents) - policies["Random"] = budget * (random_weights / random_weights.sum()) - - # Policy 4: Success-based (proportional to current capital) - policies["Winner-Take-More"] = budget * ( - baseline_capital / baseline_capital.sum() - ) - - # Policy 5: CATE-optimal (proportional to treatment effect estimates) - cate_positive = np.maximum(df_results["cate"].values, 0.01) - policies["CATE-Optimal"] = budget * (cate_positive / cate_positive.sum()) - - results = [] - for policy_name, allocation in policies.items(): - # Model returns with diminishing marginal utility - returns = np.sqrt(allocation) - new_capital = baseline_capital + returns - - gini_coef = calculate_gini(new_capital) - - results.append( - { - "Policy": policy_name, - "Total Capital": new_capital.sum(), - "Mean Capital": new_capital.mean(), - "Median Capital": np.median(new_capital), - "Gini Coefficient": gini_coef, - "Top 10% Share": new_capital[np.argsort(new_capital)[-10:]].sum() - / new_capital.sum(), - "Bottom 50% Share": new_capital[ - np.argsort(new_capital)[:50] - ].sum() - / new_capital.sum(), - } - ) - - return pd.DataFrame(results) - +# %% policy_comparison = compare_allocation_policies(df_results) print("Policy Comparison: Resource Allocation Strategies") @@ -1240,8 +1042,6 @@ def compare_allocation_policies(df_results): # # We conclude by consolidating all major findings into a comprehensive summary suitable for presentation or reporting. -# %% - # %% print("=" * 80) print("COMPREHENSIVE SIMULATION ANALYSIS SUMMARY") @@ -1263,13 +1063,13 @@ def compare_allocation_policies(df_results): ) print(f" Top 10% wealth share: {top10_share * 100:.1f}%") print(f" Top 20% wealth share: {top20_share * 100:.1f}%") -print(f" Capital range: {cap_range:.1f}x (max/min)") +print(f" Capital range: {df_results['capital'].max() / df_results['capital'].min():.1f}x (max/min)") print() print("3. CORRELATION ANALYSIS") -print(f" Talent → Log(Capital): r = {talent_corr:.4f}") -print(f" Beneficial Events → Log(Capital): r = {luck_corr:.4f}") -print(f" Relative strength (magnitude): {relative_strength:.2f}x") +print(f" Talent → Log(Capital): r = {corr_talent:.4f}") +print(f" Beneficial Events → Log(Capital): r = {corr_luck:.4f}") +print(f" Relative strength (magnitude): {abs(corr_luck) / max(abs(corr_talent), 1e-12):.2f}x") print( " Conclusion: Event exposure is more strongly associated with outcomes than talent in this run" ) @@ -1277,13 +1077,13 @@ def compare_allocation_policies(df_results): print("4. TOP PERFORMERS CHARACTERIZATION") print( - f" Average talent rank of top 10: {avg_top_talent_rank:.1f} / {N_AGENTS}" + f" Average talent rank of top 10: {top_10['talent_rank'].mean():.1f} / {N_AGENTS}" ) print( - f" Population average talent rank: {avg_pop_talent_rank:.1f} / {N_AGENTS}" + f" Population average talent rank: {df_results['talent_rank'].mean():.1f} / {N_AGENTS}" ) -print(f" Avg beneficial events (top 10): {avg_top_lucky:.2f}") -print(f" Population avg beneficial events: {avg_pop_lucky:.2f}") +print(f" Avg beneficial events (top 10): {top_10['lucky_events'].mean():.2f}") +print(f" Population avg beneficial events: {df_results['lucky_events'].mean():.2f}") print( " Conclusion: Top outcomes align more with favorable event histories than exceptional talent" ) @@ -1315,36 +1115,40 @@ def compare_allocation_policies(df_results): # # Across typical runs of the simulation, we see that: # -# 1. **Normal inputs, heavy-tailed outputs** +# 1. **Normal inputs, heavy-tailed outputs** # Talent is roughly normal, but final capital is strongly right-skewed with a long tail of big winners. # -# 2. **Luck dominates correlations** +# 2. **Luck dominates correlations** # The correlation between the number of lucky events and log(final capital) is much stronger than the correlation between talent and log(final capital). In many runs, the “luck vs talent” correlation ratio is on the order of 10:1. # -# 3. **Top performers are not the top talents** +# 3. **Top performers are not the top talents** # The agents with the highest final capital usually have **average** talent but unusually many lucky events. Exceptional success tends to reflect being “lucky among the good enough” rather than being uniquely gifted. # -# 4. **Inequality emerges quickly** +# 4. **Inequality emerges quickly** # Even over 80 periods, Gini coefficients in the 0.30–0.50 range are common, despite identical starting wealth. # # ### Causal estimates # -# Simple correlations can be misleading because talent affects both exposure to events and the ability to exploit them. To get closer to causality, the notebook uses **Double Machine Learning (DML)** and **Causal Forests**: -# -# - DML estimates the **average causal effect** of one additional lucky event on log(final capital), controlling for talent as a confounder. -# - Causal Forests estimate **heterogeneous effects (CATEs)**, showing how the effect of luck varies with traits like IQ, intensity, and networking. +# Simple correlations can be misleading because talent affects both exposure +# to events and the ability to exploit them. To get closer to causality, the +# notebook uses **Double Machine Learning (DML)** and **Causal Forests**. DML +# estimates the **average causal effect** of one additional lucky event on +# log(final capital), controlling for talent as a confounder. Causal Forests +# then estimate **heterogeneous effects (CATEs)**, showing how the effect of +# luck varies with traits like IQ, intensity, and networking. # -# Typical results suggest that each additional lucky event raises expected final capital by roughly **10–15%**, even after adjusting for talent, and that agents with higher IQ or networking often benefit more from extra opportunities. +# Typical results suggest that each additional lucky event raises expected final capital by roughly **10-15%**, even after adjusting for talent, and that agents with higher IQ or networking often benefit more from extra opportunities. # # ### Policy implications # # Because outcomes are so sensitive to random events, purely meritocratic allocation rules (e.g., “give more resources to those who are already ahead”) tend to **reinforce inequality** rather than maximize total success. # -# The policy experiments in this project suggest that: -# -# - **Broad, egalitarian allocation** of resources often performs surprisingly well in aggregate. -# - **Performance-based allocation** amplifies inequality and is the least efficient in many runs. -# - **Randomized or diversified allocation** strategies can be competitive with, or even superior to, naive merit-based rules when luck plays a large role. +# The policy experiments in this project point to three consistent findings. +# **Broad, egalitarian allocation** of resources often performs surprisingly +# well in aggregate. **Performance-based allocation** amplifies inequality and +# is the least efficient in many runs. And **randomized or diversified +# allocation** strategies can be competitive with, or even superior to, naive +# merit-based rules when luck plays a large role. # # ### Takeaways # diff --git a/research/A_Causal_Analysis_of_Success_in_Modern_Society/causal_success_example.ipynb b/research/A_Causal_Analysis_of_Success_in_Modern_Society/causal_success_example.ipynb deleted file mode 100644 index b67cd824c..000000000 --- a/research/A_Causal_Analysis_of_Success_in_Modern_Society/causal_success_example.ipynb +++ /dev/null @@ -1,2224 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - " \u001b[1;31merror\u001b[0m: \u001b[1msubprocess-exited-with-error\u001b[0m\n", - " \n", - " \u001b[31m×\u001b[0m \u001b[32mBuilding wheel for econml \u001b[0m\u001b[1;32m(\u001b[0m\u001b[32mpyproject.toml\u001b[0m\u001b[1;32m)\u001b[0m did not run successfully.\n", - " \u001b[31m│\u001b[0m exit code: \u001b[1;36m1\u001b[0m\n", - " \u001b[31m╰─>\u001b[0m \u001b[31m[155 lines of output]\u001b[0m\n", - " \u001b[31m \u001b[0m running bdist_wheel\n", - " \u001b[31m \u001b[0m running build\n", - " \u001b[31m \u001b[0m running build_py\n", - " \u001b[31m \u001b[0m creating build/lib.linux-aarch64-cpython-312/econml\n", - " \u001b[31m \u001b[0m copying econml/_cate_estimator.py -> build/lib.linux-aarch64-cpython-312/econml\n", - " \u001b[31m \u001b[0m copying econml/__init__.py -> build/lib.linux-aarch64-cpython-312/econml\n", - " \u001b[31m \u001b[0m copying econml/_shap.py -> build/lib.linux-aarch64-cpython-312/econml\n", - " \u001b[31m \u001b[0m copying econml/utilities.py -> build/lib.linux-aarch64-cpython-312/econml\n", - " \u001b[31m \u001b[0m copying econml/dowhy.py -> build/lib.linux-aarch64-cpython-312/econml\n", - " \u001b[31m \u001b[0m copying econml/_version.py -> build/lib.linux-aarch64-cpython-312/econml\n", - " \u001b[31m \u001b[0m copying econml/_tree_exporter.py -> build/lib.linux-aarch64-cpython-312/econml\n", - " \u001b[31m \u001b[0m copying econml/_ortho_learner.py -> build/lib.linux-aarch64-cpython-312/econml\n", - " \u001b[31m \u001b[0m copying econml/federated_learning.py -> build/lib.linux-aarch64-cpython-312/econml\n", - " \u001b[31m \u001b[0m creating build/lib.linux-aarch64-cpython-312/econml/dr\n", - " \u001b[31m \u001b[0m copying econml/dr/__init__.py -> build/lib.linux-aarch64-cpython-312/econml/dr\n", - " \u001b[31m \u001b[0m copying econml/dr/_drlearner.py -> build/lib.linux-aarch64-cpython-312/econml/dr\n", - " \u001b[31m \u001b[0m creating build/lib.linux-aarch64-cpython-312/econml/data\n", - " \u001b[31m \u001b[0m copying econml/data/__init__.py -> build/lib.linux-aarch64-cpython-312/econml/data\n", - " \u001b[31m \u001b[0m copying econml/data/dgps.py -> build/lib.linux-aarch64-cpython-312/econml/data\n", - " \u001b[31m \u001b[0m copying econml/data/dynamic_panel_dgp.py -> build/lib.linux-aarch64-cpython-312/econml/data\n", - " \u001b[31m \u001b[0m creating build/lib.linux-aarch64-cpython-312/econml/metalearners\n", - " \u001b[31m \u001b[0m copying econml/metalearners/__init__.py -> build/lib.linux-aarch64-cpython-312/econml/metalearners\n", - " \u001b[31m \u001b[0m copying econml/metalearners/_metalearners.py -> build/lib.linux-aarch64-cpython-312/econml/metalearners\n", - " \u001b[31m \u001b[0m creating build/lib.linux-aarch64-cpython-312/econml/policy\n", - " \u001b[31m \u001b[0m copying econml/policy/_base.py -> build/lib.linux-aarch64-cpython-312/econml/policy\n", - " \u001b[31m \u001b[0m copying econml/policy/__init__.py -> build/lib.linux-aarch64-cpython-312/econml/policy\n", - " \u001b[31m \u001b[0m copying econml/policy/_drlearner.py -> build/lib.linux-aarch64-cpython-312/econml/policy\n", - " \u001b[31m \u001b[0m creating build/lib.linux-aarch64-cpython-312/econml/dml\n", - " \u001b[31m \u001b[0m copying econml/dml/causal_forest.py -> build/lib.linux-aarch64-cpython-312/econml/dml\n", - " \u001b[31m \u001b[0m copying econml/dml/__init__.py -> build/lib.linux-aarch64-cpython-312/econml/dml\n", - " \u001b[31m \u001b[0m copying econml/dml/dml.py -> build/lib.linux-aarch64-cpython-312/econml/dml\n", - " \u001b[31m \u001b[0m copying econml/dml/_rlearner.py -> build/lib.linux-aarch64-cpython-312/econml/dml\n", - " \u001b[31m \u001b[0m creating build/lib.linux-aarch64-cpython-312/econml/inference\n", - " \u001b[31m \u001b[0m copying econml/inference/__init__.py -> build/lib.linux-aarch64-cpython-312/econml/inference\n", - " \u001b[31m \u001b[0m copying econml/inference/_inference.py -> build/lib.linux-aarch64-cpython-312/econml/inference\n", - " \u001b[31m \u001b[0m copying econml/inference/_bootstrap.py -> build/lib.linux-aarch64-cpython-312/econml/inference\n", - " \u001b[31m \u001b[0m creating build/lib.linux-aarch64-cpython-312/econml/validate\n", - " \u001b[31m \u001b[0m copying econml/validate/__init__.py -> build/lib.linux-aarch64-cpython-312/econml/validate\n", - " \u001b[31m \u001b[0m copying econml/validate/drtester.py -> build/lib.linux-aarch64-cpython-312/econml/validate\n", - " \u001b[31m \u001b[0m copying econml/validate/sensitivity_analysis.py -> build/lib.linux-aarch64-cpython-312/econml/validate\n", - " \u001b[31m \u001b[0m copying econml/validate/utils.py -> build/lib.linux-aarch64-cpython-312/econml/validate\n", - " \u001b[31m \u001b[0m copying econml/validate/results.py -> build/lib.linux-aarch64-cpython-312/econml/validate\n", - " \u001b[31m \u001b[0m creating build/lib.linux-aarch64-cpython-312/econml/sklearn_extensions\n", - " \u001b[31m \u001b[0m copying econml/sklearn_extensions/__init__.py -> build/lib.linux-aarch64-cpython-312/econml/sklearn_extensions\n", - " \u001b[31m \u001b[0m copying econml/sklearn_extensions/model_selection.py -> build/lib.linux-aarch64-cpython-312/econml/sklearn_extensions\n", - " \u001b[31m \u001b[0m copying econml/sklearn_extensions/linear_model.py -> build/lib.linux-aarch64-cpython-312/econml/sklearn_extensions\n", - " \u001b[31m \u001b[0m creating build/lib.linux-aarch64-cpython-312/econml/cate_interpreter\n", - " \u001b[31m \u001b[0m copying econml/cate_interpreter/__init__.py -> build/lib.linux-aarch64-cpython-312/econml/cate_interpreter\n", - " \u001b[31m \u001b[0m copying econml/cate_interpreter/_interpreters.py -> build/lib.linux-aarch64-cpython-312/econml/cate_interpreter\n", - " \u001b[31m \u001b[0m creating build/lib.linux-aarch64-cpython-312/econml/orf\n", - " \u001b[31m \u001b[0m copying econml/orf/_ortho_forest.py -> build/lib.linux-aarch64-cpython-312/econml/orf\n", - " \u001b[31m \u001b[0m copying econml/orf/_causal_tree.py -> build/lib.linux-aarch64-cpython-312/econml/orf\n", - " \u001b[31m \u001b[0m copying econml/orf/__init__.py -> build/lib.linux-aarch64-cpython-312/econml/orf\n", - " \u001b[31m \u001b[0m creating build/lib.linux-aarch64-cpython-312/econml/tree\n", - " \u001b[31m \u001b[0m copying econml/tree/__init__.py -> build/lib.linux-aarch64-cpython-312/econml/tree\n", - " \u001b[31m \u001b[0m copying econml/tree/_tree_classes.py -> build/lib.linux-aarch64-cpython-312/econml/tree\n", - " \u001b[31m \u001b[0m creating build/lib.linux-aarch64-cpython-312/econml/iv\n", - " \u001b[31m \u001b[0m copying econml/iv/__init__.py -> build/lib.linux-aarch64-cpython-312/econml/iv\n", - " \u001b[31m \u001b[0m creating build/lib.linux-aarch64-cpython-312/econml/score\n", - " \u001b[31m \u001b[0m copying econml/score/rscorer.py -> build/lib.linux-aarch64-cpython-312/econml/score\n", - " \u001b[31m \u001b[0m copying econml/score/__init__.py -> build/lib.linux-aarch64-cpython-312/econml/score\n", - " \u001b[31m \u001b[0m copying econml/score/ensemble_cate.py -> build/lib.linux-aarch64-cpython-312/econml/score\n", - " \u001b[31m \u001b[0m creating build/lib.linux-aarch64-cpython-312/econml/grf\n", - " \u001b[31m \u001b[0m copying econml/grf/classes.py -> build/lib.linux-aarch64-cpython-312/econml/grf\n", - " \u001b[31m \u001b[0m copying econml/grf/_base_grftree.py -> build/lib.linux-aarch64-cpython-312/econml/grf\n", - " \u001b[31m \u001b[0m copying econml/grf/_base_grf.py -> build/lib.linux-aarch64-cpython-312/econml/grf\n", - " \u001b[31m \u001b[0m copying econml/grf/__init__.py -> build/lib.linux-aarch64-cpython-312/econml/grf\n", - " \u001b[31m \u001b[0m creating build/lib.linux-aarch64-cpython-312/econml/automated_ml\n", - " \u001b[31m \u001b[0m copying econml/automated_ml/__init__.py -> build/lib.linux-aarch64-cpython-312/econml/automated_ml\n", - " \u001b[31m \u001b[0m copying econml/automated_ml/_automated_ml.py -> build/lib.linux-aarch64-cpython-312/econml/automated_ml\n", - " \u001b[31m \u001b[0m creating build/lib.linux-aarch64-cpython-312/econml/panel\n", - " \u001b[31m \u001b[0m copying econml/panel/__init__.py -> build/lib.linux-aarch64-cpython-312/econml/panel\n", - " \u001b[31m \u001b[0m copying econml/panel/utilities.py -> build/lib.linux-aarch64-cpython-312/econml/panel\n", - " \u001b[31m \u001b[0m creating build/lib.linux-aarch64-cpython-312/econml/_ensemble\n", - " \u001b[31m \u001b[0m copying econml/_ensemble/__init__.py -> build/lib.linux-aarch64-cpython-312/econml/_ensemble\n", - " \u001b[31m \u001b[0m copying econml/_ensemble/_ensemble.py -> build/lib.linux-aarch64-cpython-312/econml/_ensemble\n", - " \u001b[31m \u001b[0m copying econml/_ensemble/_utilities.py -> build/lib.linux-aarch64-cpython-312/econml/_ensemble\n", - " \u001b[31m \u001b[0m creating build/lib.linux-aarch64-cpython-312/econml/solutions/causal_analysis\n", - " \u001b[31m \u001b[0m copying econml/solutions/causal_analysis/_causal_analysis.py -> build/lib.linux-aarch64-cpython-312/econml/solutions/causal_analysis\n", - " \u001b[31m \u001b[0m copying econml/solutions/causal_analysis/__init__.py -> build/lib.linux-aarch64-cpython-312/econml/solutions/causal_analysis\n", - " \u001b[31m \u001b[0m creating build/lib.linux-aarch64-cpython-312/econml/policy/_forest\n", - " \u001b[31m \u001b[0m copying econml/policy/_forest/_forest.py -> build/lib.linux-aarch64-cpython-312/econml/policy/_forest\n", - " \u001b[31m \u001b[0m copying econml/policy/_forest/__init__.py -> build/lib.linux-aarch64-cpython-312/econml/policy/_forest\n", - " \u001b[31m \u001b[0m copying econml/policy/_forest/_tree.py -> build/lib.linux-aarch64-cpython-312/econml/policy/_forest\n", - " \u001b[31m \u001b[0m creating build/lib.linux-aarch64-cpython-312/econml/iv/dr\n", - " \u001b[31m \u001b[0m copying econml/iv/dr/__init__.py -> build/lib.linux-aarch64-cpython-312/econml/iv/dr\n", - " \u001b[31m \u001b[0m copying econml/iv/dr/_dr.py -> build/lib.linux-aarch64-cpython-312/econml/iv/dr\n", - " \u001b[31m \u001b[0m creating build/lib.linux-aarch64-cpython-312/econml/iv/dml\n", - " \u001b[31m \u001b[0m copying econml/iv/dml/__init__.py -> build/lib.linux-aarch64-cpython-312/econml/iv/dml\n", - " \u001b[31m \u001b[0m copying econml/iv/dml/_dml.py -> build/lib.linux-aarch64-cpython-312/econml/iv/dml\n", - " \u001b[31m \u001b[0m creating build/lib.linux-aarch64-cpython-312/econml/iv/sieve\n", - " \u001b[31m \u001b[0m copying econml/iv/sieve/__init__.py -> build/lib.linux-aarch64-cpython-312/econml/iv/sieve\n", - " \u001b[31m \u001b[0m copying econml/iv/sieve/_tsls.py -> build/lib.linux-aarch64-cpython-312/econml/iv/sieve\n", - " \u001b[31m \u001b[0m creating build/lib.linux-aarch64-cpython-312/econml/panel/dml\n", - " \u001b[31m \u001b[0m copying econml/panel/dml/__init__.py -> build/lib.linux-aarch64-cpython-312/econml/panel/dml\n", - " \u001b[31m \u001b[0m copying econml/panel/dml/_dml.py -> build/lib.linux-aarch64-cpython-312/econml/panel/dml\n", - " \u001b[31m \u001b[0m running egg_info\n", - " \u001b[31m \u001b[0m writing econml.egg-info/PKG-INFO\n", - " \u001b[31m \u001b[0m writing dependency_links to econml.egg-info/dependency_links.txt\n", - " \u001b[31m \u001b[0m writing requirements to econml.egg-info/requires.txt\n", - " \u001b[31m \u001b[0m writing top-level names to econml.egg-info/top_level.txt\n", - " \u001b[31m \u001b[0m reading manifest file 'econml.egg-info/SOURCES.txt'\n", - " \u001b[31m \u001b[0m adding license file 'LICENSE'\n", - " \u001b[31m \u001b[0m writing manifest file 'econml.egg-info/SOURCES.txt'\n", - " \u001b[31m \u001b[0m copying econml/tree/_criterion.c -> build/lib.linux-aarch64-cpython-312/econml/tree\n", - " \u001b[31m \u001b[0m copying econml/tree/_splitter.c -> build/lib.linux-aarch64-cpython-312/econml/tree\n", - " \u001b[31m \u001b[0m copying econml/tree/_tree.c -> build/lib.linux-aarch64-cpython-312/econml/tree\n", - " \u001b[31m \u001b[0m copying econml/tree/_utils.c -> build/lib.linux-aarch64-cpython-312/econml/tree\n", - " \u001b[31m \u001b[0m copying econml/grf/_criterion.c -> build/lib.linux-aarch64-cpython-312/econml/grf\n", - " \u001b[31m \u001b[0m copying econml/grf/_utils.c -> build/lib.linux-aarch64-cpython-312/econml/grf\n", - " \u001b[31m \u001b[0m creating build/lib.linux-aarch64-cpython-312/econml/data/ihdp\n", - " \u001b[31m \u001b[0m copying econml/data/ihdp/example.csv -> build/lib.linux-aarch64-cpython-312/econml/data/ihdp\n", - " \u001b[31m \u001b[0m copying econml/data/ihdp/example_full.csv -> build/lib.linux-aarch64-cpython-312/econml/data/ihdp\n", - " \u001b[31m \u001b[0m copying econml/data/ihdp/sim.csv -> build/lib.linux-aarch64-cpython-312/econml/data/ihdp\n", - " \u001b[31m \u001b[0m creating build/lib.linux-aarch64-cpython-312/econml/data/input_dynamicdgp\n", - " \u001b[31m \u001b[0m copying econml/data/input_dynamicdgp/cov_new.jbl -> build/lib.linux-aarch64-cpython-312/econml/data/input_dynamicdgp\n", - " \u001b[31m \u001b[0m copying econml/data/input_dynamicdgp/gm_0.jbl -> build/lib.linux-aarch64-cpython-312/econml/data/input_dynamicdgp\n", - " \u001b[31m \u001b[0m copying econml/data/input_dynamicdgp/gm_1.jbl -> build/lib.linux-aarch64-cpython-312/econml/data/input_dynamicdgp\n", - " \u001b[31m \u001b[0m copying econml/data/input_dynamicdgp/gm_2.jbl -> build/lib.linux-aarch64-cpython-312/econml/data/input_dynamicdgp\n", - " \u001b[31m \u001b[0m copying econml/data/input_dynamicdgp/gm_3.jbl -> build/lib.linux-aarch64-cpython-312/econml/data/input_dynamicdgp\n", - " \u001b[31m \u001b[0m copying econml/data/input_dynamicdgp/gm_4.jbl -> build/lib.linux-aarch64-cpython-312/econml/data/input_dynamicdgp\n", - " \u001b[31m \u001b[0m copying econml/data/input_dynamicdgp/gm_5.jbl -> build/lib.linux-aarch64-cpython-312/econml/data/input_dynamicdgp\n", - " \u001b[31m \u001b[0m copying econml/data/input_dynamicdgp/gm_6.jbl -> build/lib.linux-aarch64-cpython-312/econml/data/input_dynamicdgp\n", - " \u001b[31m \u001b[0m copying econml/data/input_dynamicdgp/lognorm_neg_0.jbl -> build/lib.linux-aarch64-cpython-312/econml/data/input_dynamicdgp\n", - " \u001b[31m \u001b[0m copying econml/data/input_dynamicdgp/lognorm_neg_1.jbl -> build/lib.linux-aarch64-cpython-312/econml/data/input_dynamicdgp\n", - " \u001b[31m \u001b[0m copying econml/data/input_dynamicdgp/lognorm_neg_2.jbl -> build/lib.linux-aarch64-cpython-312/econml/data/input_dynamicdgp\n", - " \u001b[31m \u001b[0m copying econml/data/input_dynamicdgp/lognorm_neg_3.jbl -> build/lib.linux-aarch64-cpython-312/econml/data/input_dynamicdgp\n", - " \u001b[31m \u001b[0m copying econml/data/input_dynamicdgp/lognorm_neg_4.jbl -> build/lib.linux-aarch64-cpython-312/econml/data/input_dynamicdgp\n", - " \u001b[31m \u001b[0m copying econml/data/input_dynamicdgp/lognorm_neg_5.jbl -> build/lib.linux-aarch64-cpython-312/econml/data/input_dynamicdgp\n", - " \u001b[31m \u001b[0m copying econml/data/input_dynamicdgp/lognorm_pos_0.jbl -> build/lib.linux-aarch64-cpython-312/econml/data/input_dynamicdgp\n", - " \u001b[31m \u001b[0m copying econml/data/input_dynamicdgp/lognorm_pos_1.jbl -> build/lib.linux-aarch64-cpython-312/econml/data/input_dynamicdgp\n", - " \u001b[31m \u001b[0m copying econml/data/input_dynamicdgp/lognorm_pos_2.jbl -> build/lib.linux-aarch64-cpython-312/econml/data/input_dynamicdgp\n", - " \u001b[31m \u001b[0m copying econml/data/input_dynamicdgp/lognorm_pos_3.jbl -> build/lib.linux-aarch64-cpython-312/econml/data/input_dynamicdgp\n", - " \u001b[31m \u001b[0m copying econml/data/input_dynamicdgp/lognorm_pos_4.jbl -> build/lib.linux-aarch64-cpython-312/econml/data/input_dynamicdgp\n", - " \u001b[31m \u001b[0m copying econml/data/input_dynamicdgp/lognorm_pos_5.jbl -> build/lib.linux-aarch64-cpython-312/econml/data/input_dynamicdgp\n", - " \u001b[31m \u001b[0m copying econml/data/input_dynamicdgp/lognorm_pos_6.jbl -> build/lib.linux-aarch64-cpython-312/econml/data/input_dynamicdgp\n", - " \u001b[31m \u001b[0m copying econml/data/input_dynamicdgp/n_0.jbl -> build/lib.linux-aarch64-cpython-312/econml/data/input_dynamicdgp\n", - " \u001b[31m \u001b[0m copying econml/data/input_dynamicdgp/n_1.jbl -> build/lib.linux-aarch64-cpython-312/econml/data/input_dynamicdgp\n", - " \u001b[31m \u001b[0m copying econml/data/input_dynamicdgp/n_2.jbl -> build/lib.linux-aarch64-cpython-312/econml/data/input_dynamicdgp\n", - " \u001b[31m \u001b[0m copying econml/data/input_dynamicdgp/n_3.jbl -> build/lib.linux-aarch64-cpython-312/econml/data/input_dynamicdgp\n", - " \u001b[31m \u001b[0m copying econml/data/input_dynamicdgp/n_4.jbl -> build/lib.linux-aarch64-cpython-312/econml/data/input_dynamicdgp\n", - " \u001b[31m \u001b[0m copying econml/data/input_dynamicdgp/n_5.jbl -> build/lib.linux-aarch64-cpython-312/econml/data/input_dynamicdgp\n", - " \u001b[31m \u001b[0m copying econml/data/input_dynamicdgp/n_6.jbl -> build/lib.linux-aarch64-cpython-312/econml/data/input_dynamicdgp\n", - " \u001b[31m \u001b[0m copying econml/policy/_forest/_criterion.c -> build/lib.linux-aarch64-cpython-312/econml/policy/_forest\n", - " \u001b[31m \u001b[0m running build_ext\n", - " \u001b[31m \u001b[0m building 'econml.policy._forest._criterion' extension\n", - " \u001b[31m \u001b[0m creating build/temp.linux-aarch64-cpython-312/econml/policy/_forest\n", - " \u001b[31m \u001b[0m aarch64-linux-gnu-gcc -fno-strict-overflow -Wsign-compare -DNDEBUG -g -O2 -Wall -fPIC -DNPY_NO_DEPRECATED_API=NPY_1_7_API_VERSION -I/tmp/pip-build-env-skj2o37k/overlay/lib/python3.12/site-packages/numpy/_core/include -I/venv/include -I/usr/include/python3.12 -c econml/policy/_forest/_criterion.c -o build/temp.linux-aarch64-cpython-312/econml/policy/_forest/_criterion.o\n", - " \u001b[31m \u001b[0m In file included from /usr/include/python3.12/Python.h:23,\n", - " \u001b[31m \u001b[0m from econml/policy/_forest/_criterion.c:39:\n", - " \u001b[31m \u001b[0m /usr/include/stdlib.h:32:10: fatal error: stddef.h: No such file or directory\n", - " \u001b[31m \u001b[0m 32 | #include \n", - " \u001b[31m \u001b[0m | ^~~~~~~~~~\n", - " \u001b[31m \u001b[0m compilation terminated.\n", - " \u001b[31m \u001b[0m error: command '/usr/bin/aarch64-linux-gnu-gcc' failed with exit code 1\n", - " \u001b[31m \u001b[0m \u001b[31m[end of output]\u001b[0m\n", - " \n", - " \u001b[1;35mnote\u001b[0m: This error originates from a subprocess, and is likely not a problem with pip.\n", - "\u001b[31m ERROR: Failed building wheel for econml\u001b[0m\u001b[31m\n", - "\u001b[0m\u001b[31mERROR: Could not build wheels for econml, which is required to install pyproject.toml-based projects\u001b[0m\u001b[31m\n", - "\u001b[0m" - ] - } - ], - "source": [ - "%load_ext autoreload\n", - "%autoreload 2\n", - "\n", - "import logging\n", - "import sys\n", - "from pathlib import Path\n", - "\n", - "import numpy as np\n", - "import pandas as pd\n", - "import seaborn as sns\n", - "import matplotlib.pyplot as plt\n", - "\n", - "# Initialize logger.\n", - "logging.basicConfig(level=logging.INFO)\n", - "_LOG = logging.getLogger(__name__)" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [], - "source": [ - "%matplotlib inline\n", - "\n", - "# Make sure the project root is importable (works in Docker and locally).\n", - "import os\n", - "\n", - "PROJECT_ROOT = \"/app\" if os.path.exists(\"/app\") else os.getcwd()\n", - "if PROJECT_ROOT not in sys.path:\n", - " sys.path.insert(0, PROJECT_ROOT)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# A Causal Analysis of Success in Modern Society\n", - "\n", - "## Tutorial: Talent, Luck, and Causal Inference\n", - "\n", - "Author: Krishna Kishore Buddi\n", - "Course: MSML610\n", - "Instructor: Prof. GP Saggese\n", - "Institution: University of Maryland\n", - "\n", - "## What this notebook does\n", - "\n", - "This notebook walks through the entire analysis pipeline for the project *“A Causal Analysis of Success in Modern Society.”* \n", - "You will:\n", - "\n", - "- simulate a population of agents with different talents,\n", - "- expose them to good and bad events that compound over time,\n", - "- measure how unequal the final outcomes become,\n", - "- and use modern causal inference tools (Double Machine Learning and Causal Forests) to separate **talent** from **luck**.\n", - "\n", - "The goal is not to perfectly model the real world. Instead, the goal is to understand a simple but powerful mechanism:\n", - "\n", - "> If abilities are roughly “normal” but success is extremely unequal, then **random multiplicative events** must be doing a lot of the work.\n", - "\n", - "This notebook is meant to be **interactive**:\n", - "\n", - "- Run each section in order.\n", - "- Look at the printed summaries and plots.\n", - "- Then tweak parameters (number of agents, number of events, event magnitudes) and see what changes.\n", - "\n", - "For a higher-level narrative and more theory:\n", - "- See `README.md` for the big-picture motivation and results.\n", - "- See `causal_success_tutorial.md` for a detailed written tutorial.\n", - "- See `causal_success_API.md` for function-level documentation of `causal_success_utils.py`.\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Section 1: Environment Setup and Package Imports\n", - "\n", - "We start by setting up the Python environment and importing the core libraries used throughout the tutorial. NumPy handles numerical computations, Pandas provides tools for working with tabular data, and Matplotlib/Seaborn support visualization. For the causal analysis, we rely on scikit-learn for general machine learning routines and EconML for modern double machine learning and causal forest estimators.\n", - "\n", - "This section simply ensures that all dependencies are available and\n", - "configured, so the later parts of the notebook can focus on the model, the\n", - "simulation, and the interpretation of results rather than on technical setup\n", - "details.\n" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "ename": "ModuleNotFoundError", - "evalue": "No module named 'econml'", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[6], line 15\u001b[0m\n\u001b[1;32m 13\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mscipy\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m stats\n\u001b[1;32m 14\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01msklearn\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mensemble\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m RandomForestRegressor\n\u001b[0;32m---> 15\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01meconml\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mdml\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m LinearDML, CausalForestDML\n\u001b[1;32m 17\u001b[0m \u001b[38;5;66;03m# Reload the utils module to pick up any local changes during development\u001b[39;00m\n\u001b[1;32m 18\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01mimportlib\u001b[39;00m\n", - "\u001b[0;31mModuleNotFoundError\u001b[0m: No module named 'econml'" - ] - } - ], - "source": [ - "import importlib\n", - "import os\n", - "\n", - "from scipy import stats\n", - "from sklearn.ensemble import RandomForestRegressor\n", - "from econml.dml import LinearDML, CausalForestDML\n", - "\n", - "import causal_success_utils\n", - "\n", - "importlib.reload(causal_success_utils)\n", - "\n", - "# Import everything the notebook uses from the utils module.\n", - "from causal_success_utils import (\n", - " create_population,\n", - " run_simulation,\n", - " calculate_gini,\n", - " get_results_dataframe,\n", - ")\n", - "\n", - "# Configure plotting and numpy.\n", - "np.random.seed(42)\n", - "sns.set_style(\"whitegrid\")\n", - "plt.rcParams[\"figure.figsize\"] = (14, 6)\n", - "plt.rcParams[\"font.size\"] = 10\n", - "\n", - "_LOG.info(\"Environment configured successfully\")\n", - "_LOG.info(\"Project root: %s\", PROJECT_ROOT)\n", - "_LOG.info(\"NumPy version: %s\", np.__version__)\n", - "_LOG.info(\"Pandas version: %s\", pd.__version__)\n", - "_LOG.info(\"causal_success_utils module imported successfully\")" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Experimental configuration loaded\n", - " Agents: 100\n", - " Rounds: 200\n", - " Events per round: 20\n", - " Random seed: 42\n" - ] - } - ], - "source": [ - "# Experimental Configuration.\n", - "\n", - "# Population parameters.\n", - "N_AGENTS = 100\n", - "\n", - "# Time parameters.\n", - "N_ROUNDS = 200\n", - "\n", - "# Event parameters.\n", - "LUCKY_EVENTS_PER_ROUND = 10\n", - "UNLUCKY_EVENTS_PER_ROUND = 10\n", - "EVENTS_PER_ROUND = LUCKY_EVENTS_PER_ROUND + UNLUCKY_EVENTS_PER_ROUND\n", - "\n", - "# Event impact parameters (lucky events: on average +35% with moderate spread).\n", - "LUCKY_MEAN = 0.35\n", - "LUCKY_STD = 0.12\n", - "\n", - "# Unlucky events: on average -10% with smaller spread.\n", - "UNLUCKY_MEAN = 0.10\n", - "UNLUCKY_STD = 0.04\n", - "\n", - "# Random seed for reproducibility.\n", - "RANDOM_SEED = 42\n", - "\n", - "_LOG.info(\"Experimental configuration loaded\")\n", - "_LOG.info(\"Agents: %s\", N_AGENTS)\n", - "_LOG.info(\"Rounds: %s\", N_ROUNDS)\n", - "_LOG.info(\"Events per round: %s\", EVENTS_PER_ROUND)\n", - "_LOG.info(\"Random seed: %s\", RANDOM_SEED)" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Running simulation: 100%|████████████████████████████████████████████████████████| 200/200 [00:00<00:00, 356.09period/s]" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Simulation rerun completed with configured parameters.\n", - " Gini coefficient: 0.7071\n", - " Top 10% wealth share: 0.599\n", - " Top 20% wealth share: 0.762\n", - " Capital range (max/min): 293.6x\n", - " Corr(talent, log capital): 0.435\n", - " Corr(lucky events, log capital): 0.871\n", - " Relative strength |luck|/|talent|: 2.00x\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\n" - ] - } - ], - "source": [ - "# ===============================\n", - "# Re-run simulation using config\n", - "# ===============================\n", - "\n", - "# Safety check: ensure configuration cell has been run\n", - "assert \"N_AGENTS\" in globals(), \"Experimental configuration cell was not run.\"\n", - "assert \"RANDOM_SEED\" in globals(), \"Experimental configuration cell was not run.\"\n", - "\n", - "# 1) Build population using the configured number of agents and seed\n", - "agents = create_population(n_agents=N_AGENTS, seed=RANDOM_SEED)\n", - "\n", - "# 2) Run simulation using ONLY the config values defined above\n", - "agents = run_simulation(\n", - " agents=agents,\n", - " n_periods=N_ROUNDS,\n", - " n_lucky_events_per_period=LUCKY_EVENTS_PER_ROUND,\n", - " n_unlucky_events_per_period=UNLUCKY_EVENTS_PER_ROUND,\n", - " lucky_mean=LUCKY_MEAN,\n", - " lucky_std=LUCKY_STD,\n", - " unlucky_mean=UNLUCKY_MEAN,\n", - " unlucky_std=UNLUCKY_STD,\n", - " seed=RANDOM_SEED,\n", - " verbose=True,\n", - ")\n", - "\n", - "# 3) Create results dataframe and derived quantities\n", - "df_results = get_results_dataframe(agents)\n", - "df_results[\"log_capital\"] = np.log(df_results[\"capital\"])\n", - "\n", - "# Inequality metrics\n", - "gini = calculate_gini(df_results[\"capital\"].values)\n", - "top10_share = (\n", - " df_results.nlargest(max(1, len(df_results) // 10), \"capital\")[\n", - " \"capital\"\n", - " ].sum()\n", - " / df_results[\"capital\"].sum()\n", - ")\n", - "top20_share = (\n", - " df_results.nlargest(max(1, len(df_results) // 5), \"capital\")[\"capital\"].sum()\n", - " / df_results[\"capital\"].sum()\n", - ")\n", - "cap_range = df_results[\"capital\"].max() / df_results[\"capital\"].min()\n", - "\n", - "# Correlations: talent vs outcomes and luck vs outcomes\n", - "talent_corr = df_results[\"talent_norm\"].corr(df_results[\"log_capital\"])\n", - "luck_corr = df_results[\"lucky_events\"].corr(df_results[\"log_capital\"])\n", - "relative_strength = abs(luck_corr) / max(abs(talent_corr), 1e-12)\n", - "\n", - "# 4) Top performers summary\n", - "top_n = 10\n", - "top_df = df_results.nlargest(top_n, \"capital\").copy()\n", - "\n", - "# Rank talent so rank=1 is highest talent\n", - "df_results[\"talent_rank\"] = df_results[\"talent_norm\"].rank(ascending=False)\n", - "\n", - "avg_top_talent_rank = top_df.merge(df_results[[\"id\", \"talent_rank\"]], on=\"id\")[\n", - " \"talent_rank\"\n", - "].mean()\n", - "avg_pop_talent_rank = df_results[\"talent_rank\"].mean()\n", - "\n", - "avg_top_lucky = top_df[\"lucky_events\"].mean()\n", - "avg_pop_lucky = df_results[\"lucky_events\"].mean()\n", - "\n", - "print(\"Simulation rerun completed with configured parameters.\")\n", - "print(f\" Gini coefficient: {gini:.4f}\")\n", - "print(f\" Top 10% wealth share: {top10_share:.3f}\")\n", - "print(f\" Top 20% wealth share: {top20_share:.3f}\")\n", - "print(f\" Capital range (max/min): {cap_range:.1f}x\")\n", - "print(f\" Corr(talent, log capital): {talent_corr:.3f}\")\n", - "print(f\" Corr(lucky events, log capital): {luck_corr:.3f}\")\n", - "print(f\" Relative strength |luck|/|talent|: {relative_strength:.2f}x\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Section 2: Theoretical Framework\n", - "\n", - "In this section we spell out the model that drives the simulation: how we represent “talent,” how random events affect people over time, and how we frame the causal question about luck and success.\n", - "\n", - "---\n", - "\n", - "### 2.1 Model Specification\n", - "\n", - "Each agent \\(i\\) is described by a talent vector \\(T_i\\) with several components. These dimensions are not meant to be perfect psychological constructs, but convenient knobs that capture different ways people can be “good at” navigating opportunities.\n", - "\n", - "- **Intensity (\\(t_{\\text{intensity}}\\))** \n", - " Intensity stands in for effort, persistence, and general activity level. In the model, this drives **exposure to events**: high-intensity agents “show up” more often, talk to more people, and try more things, so they are more likely to bump into both good and bad events. This is our formalization of the “surface area of luck” idea.\n", - "\n", - "- **IQ (\\(t_{\\text{iq}}\\))** \n", - " IQ represents cognitive ability and problem-solving skill. Intensity determines how many opportunities you see; IQ affects the **probability of turning a lucky event into an actual gain**. An agent with high intensity but low IQ may see many chances but fail to convert them; high IQ but very low intensity may simply not be in the right place at the right time.\n", - "\n", - "- **Networking (\\(t_{\\text{networking}}\\))** \n", - " Networking measures social capital: the strength and reach of an agent’s relationships. In the simulation, this allows opportunities to **spill over** from one agent to another. A lucky event that hits one person can sometimes partially benefit someone else with strong connections, mirroring referrals, recommendations, and “who you know” effects.\n", - "\n", - "- **Initial Capital (\\(C_{0}\\))** \n", - " All agents begin with the same initial capital in the baseline setup, typically \\(C_0 = 1\\). This isolates the role of random events and talent. Initial capital gives everyone a baseline but, in the core model, it does **not** affect event probabilities directly.\n", - "\n", - "Together, these components give each agent a fixed talent profile that shapes how they interact with randomness over time.\n", - "\n", - "---\n", - "\n", - "### 2.2 Event Mechanics\n", - "\n", - "At each time period, agents may experience **events** that change their capital. Events have three key ingredients:\n", - "\n", - "- A **type**: \n", - " - Beneficial (“lucky”) \n", - " - Detrimental (“unlucky”)\n", - "\n", - "- An **impact magnitude \\(\\Delta\\)**: \n", - " - Lucky events: sampled from a normal distribution with a positive mean (e.g., 25–35%), then clipped to a reasonable range (e.g., 5–50%). \n", - " - Unlucky events: sampled from a normal distribution with a smaller positive mean (interpreted as a loss) and clipped similarly (e.g., 5–30%).\n", - "\n", - "- An **assignment probability**: \n", - " - Who actually receives each event is determined probabilistically, based on talent (primarily intensity, with networking affecting spillovers).\n", - "\n", - "Capital evolves **multiplicatively**:\n", - "\n", - "- Beneficial event:\n", - " \\[\n", - " C_{i,t+1} = C_{i,t} \\times (1 + \\Delta)\n", - " \\]\n", - "\n", - "- Detrimental event:\n", - " \\[\n", - " C_{i,t+1} = C_{i,t} \\times (1 - \\Delta)\n", - " \\]\n", - "\n", - "This multiplicative structure is the core of the model. Under additive dynamics, everyone’s capital shifts by similar absolute amounts, and initial gaps tend to persist but not explode. Under multiplicative dynamics, **percentage changes** are what matter, so a 20% gain on \\$1 and a 20% gain on \\$1000 look very different in absolute terms. Over many periods, small differences in event histories can lead to large differences in outcomes.\n", - "\n", - "We also enforce a small capital floor (e.g., \\$0.01) to avoid negative or zero values, which keeps the model numerically stable and allows us to safely take logarithms.\n", - "\n", - "---\n", - "\n", - "### 2.3 Causal Inference Framework\n", - "\n", - "The central causal question is:\n", - "\n", - "> *What is the effect of experiencing additional beneficial events on final success, after accounting for differences in talent?*\n", - "\n", - "The difficulty is that **treatment is not randomly assigned**. More talented agents may both receive more opportunities and be better at using them. If we simply regress outcomes on the number of lucky events, we would mix up three things:\n", - "\n", - "1. The true causal effect of lucky events \n", - "2. The fact that high-talent agents get more opportunities \n", - "3. The fact that high-talent agents would do well even with fewer events\n", - "\n", - "To disentangle these pieces, we define:\n", - "\n", - "- **Treatment variable \\(T\\)** \n", - " The count of beneficial (lucky) events an agent experiences over the simulation.\n", - "\n", - "- **Outcome variable \\(Y\\)** \n", - " Final log capital, \\(\\log(C_{\\text{final}})\\). \n", - " Using the logarithm makes multiplicative effects more additive and stabilizes variance, so a one-unit change in \\(Y\\) roughly corresponds to a percentage change in wealth.\n", - "\n", - "- **Confounders \\(X\\)** \n", - " The talent dimensions: intensity, IQ, networking, and any other features that influence both how many lucky events an agent gets and how well they convert those events into capital.\n", - "\n", - "With this setup, the target quantity is the **causal effect of \\(T\\) on \\(Y\\)**, holding \\(X\\) fixed.\n", - "\n", - "We use two complementary tools:\n", - "\n", - "1. **Double Machine Learning (DML)** \n", - " - Model how treatment \\(T\\) depends on talents \\(X\\) (who tends to get more opportunities). \n", - " - Model how outcome \\(Y\\) depends on talents \\(X\\) (who tends to do well given their abilities). \n", - " - Remove the part of \\(T\\) and \\(Y\\) that can be explained by \\(X\\), then estimate the effect of the remaining (residual) variation in \\(T\\) on the residual in \\(Y\\). \n", - " This procedure corrects for confounding under fairly general conditions and gives an estimate of the **average treatment effect** of an additional lucky event.\n", - "\n", - "2. **Causal Forests (CF)** \n", - " - Extend the idea above to allow the treatment effect to vary with \\(X\\). \n", - " - Instead of one global effect, we obtain a **Conditional Average Treatment Effect (CATE)** for each agent or subgroup. \n", - " This reveals heterogeneity: some combinations of intensity, IQ, and networking benefit more from extra opportunities than others.\n", - "\n", - "Together, DML and causal forests let us answer both:\n", - "\n", - "- “On average, how much does one more lucky event change final outcomes?”\n", - "- “For which types of agents is that extra event especially valuable?”\n", - "\n", - "The remaining sections of thetutorial put this framework into practice using the simulated data generated by our agent-based model.\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Section 3: Population Construction\n", - "\n", - "In this section, we build the synthetic population that drives the rest of the analysis.\n", - "\n", - "We work with a population of **100 agents**, each with a set of talent dimensions drawn from a normal distribution centered at 0.5 with a moderate spread. This choice mirrors a common empirical pattern: most human abilities cluster around an average level, with fewer people at the extremes.\n", - "\n", - "Because our talent dimensions represent probabilities or normalized scores, we **clip all values to the \\([0, 1]\\) range**. This keeps the interpretation straightforward:\n", - "\n", - "- 0 means “very low” on that dimension \n", - "- 1 means “very high” \n", - "- values near 0.5 represent typical, “average” capability\n", - "\n", - "At this stage, all agents also receive the **same initial capital** (usually \\(C_0 = 1\\)). Any inequality that emerges later in the tutorial will therefore come from differences in event histories and talent interactions, not from unequal starting points. This makes it easier to see how randomness and ability combine to create unequal outcome over time.\n" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Population initialized: 100 agents\n", - "Each agent has 4 talent dimensions\n" - ] - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAABdIAAAGGCAYAAAB/pnNVAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8pXeV/AAAACXBIWXMAAA9hAAAPYQGoP6dpAAC5O0lEQVR4nOzdd2BT5foH8G+SDqBNuguWMgVa9lKQWiwoijJUQFQEGSIIwpUlgoOpWFwIAnLZ24GACAqoOPGCP1CGbLyM0haQdEDSQZuenN8fJec2dGWdnCT9frjeticn7/u8J+PJeXLOe1SiKIogIiIiIiIiIiIiIqIyqZUOgIiIiIiIiIiIiIjIk7GQTkRERERERERERERUARbSiYiIiIiIiIiIiIgqwEI6EREREREREREREVEFWEgnIiIiIiIiIiIiIqoAC+lERERERERERERERBVgIZ2IiIiIiIiIiIiIqAIspBMRERERERERERERVYCFdCIiIiIiIiIiIiKiCrCQTuTFnn32WcTFxSEuLg5paWlKh1MppeO19H3//fdLy7Zu3SotX7hwodtjUnqbEBGR51M6VzB/EhFRVfN///d/Up6ZOnWqy9b1VAsXLpTGsHXrVrf3X1ZeT0tLk5Y9++yzbo9J6W1CnslP6QCIXG3hwoVYtGgRAKBPnz6YO3euQ+2cOnUKe/bsAQB06NABHTt2dFmMctu6dSvS09MBAEOGDIFOp3N5+6+++qr0t0ajQbVq1RAZGYlGjRqhV69e6N69OzQajUv7XbNmDYxGIwDgX//6l0vblos3P4+IiKqKyj475OTkYMOGDdizZw8uXryImzdvIiIiAm3atMEzzzxj83s786ftmD+JiNyrZC4EgGXLliEpKUn6e+rUqfjyyy8BADNnzsSAAQMc7gcAtFothg4d6njAVKa0tDQ88MAD0t9qtRoBAQEIDQ1F/fr10aVLF/Tv3x/BwcEu7XfPnj04deoUgOLPUrGxsS5tXw4GgwFr164FANSuXRt9+/ZVOCLyBiykE5Xj1KlT0geJsWPHeuQO3BtvvCHtGEdHR0vLv/zySxw4cABAcRJzdSH9doIgIDc3F7m5uUhJScEPP/yANm3aYNGiRYiKiqo0XlutW7dO+oLAkULAxo0bAQCBgYF239dRlT2PnN0mREQkr//+978YMWIELl++bLX86tWr2L17N3bv3o0hQ4bgtddes7tt5s/yMX8SESlryZIlVoV0V7G8t9euXdtnCunNmjWTcmVkZKTC0Vgzm824efMmrl69iqtXr+L333/HypUrsXDhQrRt21Zar1+/fujUqRMAoEGDBnb3s2fPHumLlg4dOthdSFcirxsMBun52KFDh1KFdGe3CfkmFtKJvFhcXJzSIaBp06Z44403kJubiz///BMbN25ETk4Ojhw5gtGjR+PTTz+Fv78/AOXizcvLQ40aNXDXXXcp0n9FPOExJCKisuXm5uKFF16QiuhNmjTBiBEjEBkZib1792Lt2rUQBAFr165F3bp1MWjQIJvbZv50DvMnEZG8Dh8+jP3790uFxKrCbDbDZDLZdR+tVuuRuRIo/jK8sLAQf//9N9avX4/U1FTo9XqMHDkSW7duRZ06dQAAMTExiImJcXt8ls8anpjXldom5Nk4RzpVGSXnt9qyZQvWrFmDBx98EC1atMCjjz6K/fv3S+vef//9VqdeL1q0qMx5QFNTU/HGG2+ga9euaNGiBTp16oTx48fj3LlzVn3fPo/oV199hV69eqFFixbo3r07du7cabV+dnY2pk+fLrXbtm1bdO/eHRMnTpSONAdKzyNmmZut5DoPPPCAtE5KSor0++07+9evX0ezZs0QFxeH3r1727xdLR8akpKSMHHiRGzYsAF+fsXf0R07dgzbtm0rN16Lb7/9FgMGDED79u3RokUL3HvvvRgwYADee+89iKIobT/L0XTA/+ZrtSTc2+el++677/DYY4+hRYsWWLlypdV9Ss7xerudO3eid+/eaNmyJXr06IEdO3ZY3T516lSpnf/7v/+Tlpc1V6wtz6OK5njdvXs3nn32Wdx1111o0aIFHnjgAcyePRvXrl0rN6bffvsNCxYswH333YeWLVvi6aefxunTp8sdLxERlW/Tpk3Se3NoaCg2bNiARx99FAkJCZgyZQpefPFFad3FixejoKDA5raZP4sxfxIRea4lS5bYtJ4t+8WW/XGL9PR0q/xiNBrRtGlTxMXFWU0b88UXX5SZP+69917ExcXh3nvvtYpl//79GDlyJDp27IgWLVogKSkJU6dOxcWLF63WK1kf2Lx5Mz7++GN07doVzZs3x5EjR8od6+LFi6X79e3bF0ajsdw50h3JMxs3bkS3bt3QqlUrPPHEE9i/f3+5OdQWd911FxISEjBkyBBs27ZNKpwbDAZ89NFHZW6PkvOBnz59GqNHj0anTp3QvHlzdOzYEY899himT5+Oy5cvS/OYW45GB4DBgweXirfkY33mzBkMGzYMbdu2xQsvvADAtmufnDp1Cs8++yxat26NxMREzJ8/H0VFRdLt5V2/pay51qdOnWo1Bc6BAwdKrVPRHOknTpzASy+9hHvvvVf6DPbSSy/h+PHjVuvZWwsiz8cj0qlKWrJkCVJTU6W/z5w5gzFjxuCnn35CSEiITW2cOHECQ4cOhcFgkJZlZWVh165d+OWXX7B27Vq0atWq1P2++uorq74vXryISZMmIT4+Hg0bNgQAjB8/Hr///ru0jslkwsWLF3Hx4kXUqVMHHTp0sHvMQPFcrB06dMCBAwfwxx9/4PLly9I3rD///DMEQQAA9OrVy6H2geIj7Pr06YMvvvgCAPDNN9+gf//+5a5/4MABjB8/HmazWVqWkZGBjIwMHDp0CBMmTLA7hoMHD2Lbtm0QRdGu+3333Xc4e/as9Pe5c+fw8ssvQ6VSObVNHPHee+9hxYoVVsvS0tKwceNGfPfdd/j000+lD0ElzZw50+r5dfjwYbz44ov47rvvpAINERHZ5vvvv5d+79u3b6nPCIMGDcK///1vmEwmZGVl4fDhw7jnnnsc6ov50zWYP4mInNeiRQscP34c//d//4fDhw9bTQFyO0f3i2+n1WrRpEkTnD59GidOnIDJZIK/vz8OHz4srXPkyBF07NgRqampyMjIAAC0b99eun3jxo148803rfLY1atX8eWXX+K7777DmjVryozl3//+t1UOKM/nn38uFZ/j4uKwatUqaLXaSu8H2JZn1qxZg+TkZGmdY8eOYcSIEahXr55NfVQmODgYL730EiZPngyg+HNOYWEhAgICylw/Ozsbw4YNQ1ZWlrTs+vXruH79Ok6fPo2HH34YdevWtSsGg8GAwYMH4/r163bdLz09HYMGDUJOTg4A4ObNm1iyZAmysrIwe/Zsu9py1g8//IBx48ZZnbmQkZGBb7/9Fj/++CMWLFhgVaS3sKUWRJ6PR6RTlZSamooRI0ZgyZIliI+PB1B8+vbXX38NAFiwYAFGjRolrd+3b19s3LgRGzduRL9+/SCKIqZOnSp9WHjuueewatUqvPzyy9BoNMjLy8Orr75a5o5oamoqnnjiCSxdulQ6Tc5sNks7zjk5OdK3ts2aNcOSJUuwfPlyzJo1C927d0eNGjXKHZdlbramTZtKyxYsWCDFHh0djX79+gEARFGUxgsAP/74o/R7jx497NiapbVp00b63XLBkfL89NNPUhFg4sSJWLNmDT788EOMHj0ajRo1gkqlQlJSEjZu3Gg1X6xlTJa56EpKS0tDixYtsGDBAixevNjm0+zOnj2LwYMHY9myZXj00Uel5XPnzrX79D6g8udReY4ePSoVAQIDAzFlyhQsWbJEmh9Wr9dj1qxZZd736tWrePnll7Fo0SLccccdAIo/dPz22292x09EVNWVPJKuZG61CA0Nld5rgeL51J3B/FmM+ZOISFmdOnWSctLHH39c7nr27Bf369fPKvdERUVJ7+0LFiwAANx9990AgIKCAikPljw63FJUP3TokLTMkquuXLmC5ORkiKIItVqN0aNHY9myZXj44YcBFO/vV7SP3rt3byxbtgzvvPMOatasWWqd7777DjNnzgQANGzYEKtXr0ZoaGi52+Z2leUZg8GA+fPnS+s/88wzWLZsGbp37+7054uSSn4pkp+fX+pI/ZKOHDkiFdF79eqF1atXY/HixZgyZQo6dOgAtVqN6OhobNy4Effdd590vzfeeEN6bJs1a2bVptFohEajwZtvvomVK1fiiSeesCnu9PR0tGnTBv/+978xbtw46cLsn3/+uUNnkI0aNUp63gHFn/MsMb/xxhvl3i8vLw+vv/669PlmwIABWLZsGZ555hkAxQdBvv7668jLyyt138pqQeQdeHgFVUkPPPAAXn75ZQDF32RajtpKSUkBALRs2RJ///23tH5MTIzVzuSpU6ekI6+aNm0qfdvYtm1btGrVCocPH8Z///tfnDhxAi1atLDqOz4+HnPmzAEAhIWFSVPKXLp0CQDg5+cHlUoFURQRFhaGevXqoV69evDz88PTTz9d4bgsp4mX/Fa8RYsWVhf6ePjhh/HWW2/BaDRix44dGDlyJAoLC6UE3qZNmzKP1LJHyR12yzfG5Sl5lFe9evUQHx+PsLAw9OjRA+PHjwcAREREICIiwuqb8op27mvUqIEVK1bY9cEGANq1a4fXX38dAJCYmCgdta/X63H06FG7572r7HlUnpKnww8cOBDPPfccgOLHJikpSXq8rl+/XmqMAwYMwIgRIwAAFy5cwAcffADgf89tIiKyXckcFh4eXuY6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OZNZ586dYTKZoFKp0KlTp1K333nnnQgICMDly5electud+jQIbRt2xYDBw6Ull26dMnlscbGxiIqKgr79++XvpXPycnB0aNHMWDAgDLvc88992DHjh1Wy1599VU0bNgQgwYNKnVWk+XIgP379yMzMxP3338/AKBFixYICAjAhQsXcNdddwEoPrIvPT2dOYiIyAcU/etfCJgyBVBVWkovTcHcnZiYWOp2X8jdmzZtQrVq1aSjyy25e8SIETbn7vz84isaqW57TFUqlXSmGREReTEv3e+2JXeLooi8vDzUqFFDymOenrvL2++25G5LXlar1VbraTQaqdCvZO72qkL6l19+iaCgIDz00EMVrteqVSskJyejQYMG0rzrAwcOxI4dO6RvKmwliqJd38jY066c7XsaTxyvKIpA8f8gR0RiiZ+eNG45lHzr8vWxlmTr89oTn/+2KBm3Wq3Gzp07AVgnNMuYgoKC8NxzzyE5ORlmsxnt27eH0WjEoUOHEBwcjD59+qBu3brYtm0bfv31V8TGxmL79u04duwYYmNjrfoq+fP2fgBgw4YN2LNnD9asWVNu7IMHD8aSJUtQr1491K5dGx999BGio6PxwAMPSO0MHToU3bp1w6BBgxAUFCR9221RvXp1hIaGolGjRlIMW7ZswZ133onw8HAcOXIEc+bMwZAhQ9CgQQNpOzz99NNYuHAhatWqhZiYGKxatQoA0L179zIf/4qeH970fCEiIs+i0Wiwa9cu6ffbBQcHS7lbFMUyc3e9evWwbds27N27F7Gxsfjqq6+k3G2PDRs24Pvvv8fatWvLvF2lUlnl7tjYWCxYsADR0dFW188aMmQIHnzwQQwaNAjBwcFo1KiRVfGgRo0aCA0NtbrAd8ncffjwYbz99tsYOnQoGjZsCKB4HnWdToepU6dizJgxCAwMxKZNm5Ceno4uXbrYNU4iIiJn2Ju727VrB71ej5MnT0Kr1XpF7i6Zo4HSubthw4aoV68epk+fjilTpiA0NBR79uzBf/7zHyxduhSAsrnbqwrpW7ZsQe/evSucRweA1VQx8fHxaN26Nbp27Ypdu3ahf//+dvVpMBhKfQviCpZvSORq39N44niNRiMEQYBgMqHIZHJ5+5byl1kQYDQacePGDZf34Ql0oggVANEDH2O52fq8LiwshNlsLn6+CYK7wnOapbBribl69eoA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WTNY5l7knz6GiIiIiIjodmqlAyAiIiIiIiIiIiIi8mQspBMRERERERERERERVYCFdCJyzl13AbGxUHfsqHQkREREvuGN74F/fY3gub8rHQkRERHJ5da+NO66S+lIiMhGnCOdiJxz9SqQnq50FERERL7j+k2osvOhFs1KR0JERERy4b40kdfhEelERERERERERERERBVgIZ2IiIiIiIiIiIiIqAIspBMRERERERERERERVYCFdCIiIiIiIiIfdvDgQYwaNQqJiYmIi4vDnj17rG6fOnUq4uLirP4bPnx4pe1u3LgR999/P1q2bIn+/fvjr7/+kmsIREREimMhnYiIiIiIiMiH5eXlIS4uDjNmzCh3nc6dO+O3336T/ps3b16Fbe7cuRPJyckYM2YMvvzyS8THx2P48OHIzMx0dfhEREQewU/pAIiIiMj3HTx4ECtXrsTx48eh1+uxePFidOvWDQBgMpkwf/58/Prrr0hNTUVwcDASEhIwadIk1KxZU+HIiYiIvF9SUhKSkpIqXCcgIABRUVE2t7l69Wo8+eST6NevHwBg1qxZ+Pnnn7FlyxaMHDnSqXiJiIg8EQvpREREJDvLkXD9+vXD2LFjrW67efMmTp48idGjRyM+Ph4GgwFz5szB6NGjsXXrVoUiJiIiqloOHDiATp06QafT4Z577sH48eMRFhZW5rqFhYU4ceIEXnjhBWmZWq1GQkICDh8+bHffoihCFEWHY/cGlvFVhbF6Ajm2t16vh8FgcElbAFC/qAh+AIqKinDxv/8FAKSkpKCoqAjirX9yECECouufi3yOux+3uWvYs+1YSCciIiLZVXQknFarxerVq62WTZs2Df3798fly5cRExPjjhCJiIiqrM6dO+PBBx9EbGwsUlNTMW/ePIwYMQKff/45NBpNqfWzs7MhCAIiIiKslkdEROD8+fN2928wGKBW+/bMs2azGUDVGKsncPX2zsjIwAsvvYDrededbstiZ3YWagLIzM7CU88/BQAoyC/A5auX0SCvAYJMQS7rqyTBJEAwCzAajbhx44bL2uVz3P24zV3Dsh1twUI6ETnn3XeBvDyI1aopHQkR+ZCcnByoVCrodDqlQyFyvwGtIBYUId9ciBpKx0JEVULPnj2l3y0XG+3WrZt0lLrcdDpdmQV7XyIIAoCqMVZP4OrtnZGRAeNNI+r0roPg6GCn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OMJsNmPr1q14/PHH4ednXS545ZVXULNmTUyaNAkAsGjRIrRp0wb16tWDwWDAypUrcfnyZfTv31+J0ImIiGTHQjoROSXkegbUZgGCSo0bavlOtSYi3zZkyBAMGDAA//73v/HII4/gr7/+wqZNmzB79mylQyNyv+x8QDBDlVcA6JQOhoiqkn379uHy5cvo169fqduuXLliNY2OwWDAtGnToNfrERISgubNm+Ozzz5Do0aN3BkykdfSZeZCbRZhVqtgiAhSOhwisgEL6UTklDdmD0V49jVkhUVhxIxPlA7Ho5gKC5GSkiJrHxVdFI3Im7Rq1QqLFi3CvHnzsHjxYsTGxuK1117Do48+qnRoRO43bQ9U2fnQhgYCi/gaICL3SUxMxJkzZ8q8bf369VZ/v/baa3jttdfcERaRT5o85guEZeQiOzII0z4bqnQ4RGQDFtKJiGRQkHMDFy+cx/jXZiIwMFC2fsK1NbBh9QoW08kndO3aFV27dlU6DCIiIiIiIqJSWEgnIpKBqSAfZpUfIu/pi4iYerL0kZv1D/T7t8BgMLCQTkREREREREQkIxbSiYhkVCMsCrroWNna18vWMhERERERERERWagrX4WIiIiIiIiIiIiIqOpiIZ2IiIiIiIiIiIiIqAIspBMRERERERERERERVYCFdCIiIiIiIiIiIiKiCrCQTkRERERERERERERUARbSiYiIiIiIiIiIiIgq4Kd0AETk3d6fvBgacxEElUbpUIiIiHzDa0kQBTNy8nOhVToWIiIiksXC9x6DWjDDrOExrkTegoV0InLKP3fUAwCIoggYDApHQ0RE5ANidIAowsy0SkRE5LOu1QlTOgQishO/9iIiIiIiIiIiIiIiqoDHF9IXLlyIuLg4q/8efvjhCu+za9cuPPzww2jZsiV69+6NX375xU3REhEREREREREREZGv8YqpXRo3bozVq1dLf2s05c/FfOjQIUyaNAkTJ05E165dsWPHDowZMwZbt25FkyZN3BEuUZXScf9uBBTeREFANXzXrJPS4RAREXm//6QABUXwNxcCD4QoHQ0RERHJ4K4fzsK/oAimQD/88QDrVUTewCsK6RqNBlFRUTatu27dOnTu3BnPP/88AGD8+PHYt28fNmzYgNmzZ8sZJlGV9MQXixCefQ1ZYVH4bgYL6URERE779C+osvNRPTQQeCBe6WiI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L7ccw1aWxLGlDktj2INcamktRjdfX3j6e0Dj64Wyy9bVYUkce2gthq3vh6Vx7MERtbjCZ8Wd3hNzcexVBwCcu6KDj49vm+7d8jnu9kV9RT1qPWptWlZLdFd08GvnB12VDrWXRMYQgPqr9airrQNa+Zm1KY6FHBHDUXGajSFifVsdw0Z6H1/o/Rv+blymW7/3N6xzt67FwTGsjiPy57y+oh6eCk+cPXsWBoPBtoTNKC0thZfSS9LtcX1FPXy9Hd+7FYKLd/jy8nLccccd2LBhA+Lj443T33nnHRw4cACbNm1q8pqYmBgsXLgQ999/v3HaunXrsGzZMvz0008WxdVoNDhy5IjtBRAREdkoNjYW3t7ezk5DUtb0+xuxdxMRkatwt97N424iImrrLOndLn9Gevv27aFUKpvc4KSioqLJb78bdezYsclvwc3N3xxPT0/ExsbCw8PDrmddEhERWUoQBBgMBnh6uny7tpk1/f5G7N1ERORs7tq7edxNRERtlZje7fLd3dvbG3379sXevXtx1113AWj4ytbevXvxxBNPNPuauLg47Nu3D2PHjjVO++mnnxAXF2dxXA8PD7c6g4CIiMidWdPvb8TeTUREZB0edxMREbXO5W82CgBPPvkkPv30U2zbtg2nT5/GnDlzUFdXh/T0dADAtGnTsHjxYuP8Y8aMwffff4+VK1fi9OnTyMrKwtGjRy0+ECciIiLHa63fExERkXR43E1ERGSey5+RDgDDhg1DZWUl3n//fahUKkRFReGjjz4yfmXs4sWL8PD47+8EEhISsGjRIixduhRLlixBjx49sGzZMkRERDirBCIiImpFa/2eiIiIpMPjbiIiIvNc/majRERERERERERERETO5BaXdiEiIiIiIiIiIiIichYOpBMRERERERERERERmcGBdCIiIiIiIiIiIiIiMziQTkRERERERERERERkBgfSJbRu3ToMGTIEsbGxGDlyJA4fPtzivJ9++ilGjx6NpKQkJCUlYezYsWbnd0Vi6t29ezfS09ORmJiIuLg4PPDAA9i+fbvjkrUTMTVfr6CgAJGRkXjhhRckztC+xNS7detWREZGmvyJjY11YLb2IfY9VqvVyMzMREpKCmJiYvDPf/4Te/bscVC2thNTb0ZGRpP3ODIyEs8++6wDM7ad2Pf4448/xj//+U/069cPqampmD9/Purr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Tz7BkiVLrFklRkqlEs8++yy2bduGxYsX44cffsDixYuxd+9eAA2/iCByd7y0CxE1kZaWhtGjR2P58uWoqKhAUlIS8vPz0b17d2zatAlLly5FZmYmamtrERoaiqSkpGa/Cm5OQkICtm/fjnPnzsHDwwMRERH48MMPTW6Ycj0PDw8sWLAAS5YswdixY6HRaPDNN9/g1ltvBdBwc5Xbb78dly5danIXdCIiIjKvd+/e2Lp1K5YtW4asrCyoVCoYDAb06NEDn332Gbp16+bsFImIiJyucbB41qxZxmne3t5Ys2YNsrKy8OGHH0KlUuGmm25CdHS0yWVRn3nmGZSWlmL69OlQq9WYOHEiJk2aBKDhMmu7du0yGUhvvPTajSebBQQEID8/HwsXLsTs2bNhMBiQkJCAtWvX4uabbxZdU2pqKpYuXYqXXnoJPj4+mDBhguhlNMrIyIBarcb69euRn5+PgQMH4tVXX8XLL7/c5PrqRO5IIQiC4OwkiIhsVVNTg8GDB2PSpEl46qmnnJ0OERGR28vNzUVWVhZWrFiBgQMHOjsdIiIickNLly7FqlWrUFRUBF9fX2enQ2QTnpFORG6tpqYGp0+fxvr166FQKJCenu7slIiIiGThueeew7FjxzBp0iR88skn6NOnj7NTIiIiIhd2+vRpfP7554iPj4eXlxf279+PvLw8PPbYYxxEJ1ngGelE5NaKioowZswY3HzzzZg5cybuvvtuZ6dERERERERE1OacP38er7/+On7//XdcvXoVnTp1wvDhwzFp0iR4evJcXnJ/HEgnIiIiIiIiIiIiIjKDt8wlIiIiIiIiIiIiIjKDA+lERERERERERERERGZwIJ2IiIiIiIiIiIiIyAwOpBMRERERERERERERmcGBdCIiIiIiIiIiIiIiMziQTkRERERERERERERkBgfSiYiIiIiIiIiIiIjM4EA6EREREREREREREZEZHEgnIiIiIiIiIiIiIjLj/wPXXdHbWNL+TwAAAABJRU5ErkJggg==", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "Talent Dimension Statistics:\n", - "============================================================\n", - "Intensity | Mean: 0.4956 | Std: 0.1346 | Min: 0.1925 | Max: 0.8212\n", - "IQ | Mean: 0.4980 | Std: 0.1458 | Min: 0.1802 | Max: 0.9371\n", - "Networking | Mean: 0.4879 | Std: 0.1371 | Min: 0.1150 | Max: 0.9358\n", - "\n", - "All distributions approximate normality with means near 0.5\n", - "This provides a baseline of rough equality from which divergence will emerge\n" - ] - } - ], - "source": [ - "N_AGENTS = 100\n", - "agents = create_population(n_agents=N_AGENTS, seed=42)\n", - "\n", - "print(f\"Population initialized: {len(agents)} agents\")\n", - "print(f\"Each agent has {len(agents[0].talent)} talent dimensions\")\n", - "\n", - "fig, axes = plt.subplots(1, 3, figsize=(15, 4))\n", - "\n", - "talent_data = {\n", - " \"Intensity\": [a.talent[\"intensity\"] for a in agents],\n", - " \"IQ\": [a.talent[\"iq\"] for a in agents],\n", - " \"Networking\": [a.talent[\"networking\"] for a in agents],\n", - "}\n", - "\n", - "for idx, (dimension_name, values) in enumerate(talent_data.items()):\n", - " axes[idx].hist(\n", - " values, bins=15, edgecolor=\"black\", alpha=0.7, color=f\"C{idx}\"\n", - " )\n", - " mean_val = np.mean(values)\n", - " axes[idx].axvline(\n", - " mean_val,\n", - " color=\"red\",\n", - " linestyle=\"--\",\n", - " linewidth=2,\n", - " label=f\"Mean: {mean_val:.3f}\",\n", - " )\n", - " axes[idx].set_xlabel(dimension_name, fontsize=11)\n", - " axes[idx].set_ylabel(\"Frequency\", fontsize=11)\n", - " axes[idx].set_title(\n", - " f\"{dimension_name} Distribution\", fontsize=12, fontweight=\"bold\"\n", - " )\n", - " axes[idx].legend(fontsize=10)\n", - " axes[idx].grid(axis=\"y\", alpha=0.3)\n", - "\n", - "plt.tight_layout()\n", - "plt.show()\n", - "\n", - "print(\"\\nTalent Dimension Statistics:\")\n", - "print(\"=\" * 60)\n", - "for dimension_name, values in talent_data.items():\n", - " print(\n", - " f\"{dimension_name:12} | Mean: {np.mean(values):.4f} | Std: {np.std(values):.4f} | Min: {np.min(values):.4f} | Max: {np.max(values):.4f}\"\n", - " )\n", - "\n", - "print(\"\\nAll distributions approximate normality with means near 0.5\")\n", - "print(\n", - " \"This provides a baseline of rough equality from which divergence will emerge\"\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Section 4: Simulation Implementation\n", - "\n", - "The simulation proceeds in discrete time steps. Each period, a fixed number of events occur. Events are classified as beneficial or detrimental with specified probabilities. Event assignment depends on agent characteristics, while impact magnitudes are drawn from distributions.\n", - "\n", - "We implement helper functions for event generation, assignment, and simulation execution." - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Starting simulation...\n", - " - Agents: 100\n", - " - Time periods: 80\n", - " - Lucky events per period: 5\n", - " - Unlucky events per period: 5\n", - "\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Running simulation: 100%|██████████████████████████████████████████████████████████| 80/80 [00:00<00:00, 653.03period/s]" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - " Simulation complete!\n", - " Total agents: 100\n", - " Mean lucky events: 2.3\n", - " Mean unlucky events: 4.0\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\n" - ] - } - ], - "source": [ - "# Run the simulation using our run_simulation function\n", - "print(\"Starting simulation...\")\n", - "print(f\" - Agents: {N_AGENTS}\")\n", - "print(\" - Time periods: 80\")\n", - "print(\" - Lucky events per period: 5\")\n", - "print(\" - Unlucky events per period: 5\")\n", - "print()\n", - "\n", - "agents = run_simulation(\n", - " agents=agents,\n", - " n_periods=80,\n", - " n_lucky_events_per_period=5,\n", - " n_unlucky_events_per_period=5,\n", - " lucky_mean=0.25,\n", - " lucky_std=0.08,\n", - " unlucky_mean=0.15,\n", - " unlucky_std=0.05,\n", - " seed=42,\n", - " verbose=True, # Shows progress bar\n", - ")\n", - "\n", - "print(\"\\n Simulation complete!\")\n", - "print(f\" Total agents: {len(agents)}\")\n", - "print(f\" Mean lucky events: {np.mean([a.lucky_events for a in agents]):.1f}\")\n", - "print(\n", - " f\" Mean unlucky events: {np.mean([a.unlucky_events for a in agents]):.1f}\"\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Section 5: Descriptive Analysis of Simulation Results\n", - "\n", - "After simulation completion, we examine the resulting distribution of outcomes. Converting the agent population to a DataFrame facilitates statistical analysis and visualization." - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Simulation Outcomes Summary\n", - "======================================================================\n", - "\n", - "Population size: 100 agents\n", - "\n", - "Capital Distribution Statistics:\n", - " count : $ 100.00\n", - " mean : $ 0.89\n", - " std : $ 0.37\n", - " min : $ 0.33\n", - " 25% : $ 0.62\n", - " 50% : $ 0.82\n", - " 75% : $ 1.09\n", - " max : $ 2.57\n", - "\n", - "Inequality Metrics:\n", - " Range (max/min): 7.79x\n", - " 90th/10th percentile ratio: 2.48x\n", - " Coefficient of variation: 0.413\n", - "\n", - "Event Experience Distribution:\n", - " Beneficial events:\n", - " Mean: 2.32\n", - " Std: 1.56\n", - " Range: 0 to 7\n", - " Detrimental events:\n", - " Mean: 4.00\n", - " Std: 2.03\n", - " Range: 0 to 11\n", - " Net events (lucky - unlucky):\n", - " Mean: -1.68\n", - " Std: 2.23\n", - "\n", - "Sample of Results (first 10 agents):\n", - " id talent_norm capital lucky_events unlucky_events net_events\n", - " 0 1.338422 0.508831 1 4 -3\n", - " 1 1.243707 0.488271 1 7 -6\n", - " 2 1.312190 0.795865 4 5 -1\n", - " 3 1.384921 0.977459 3 5 -2\n", - " 4 1.425736 0.400109 3 9 -6\n", - " 5 1.254172 0.910872 3 4 -1\n", - " 6 1.365554 2.573136 6 1 5\n", - " 7 1.361125 0.586568 2 4 -2\n", - " 8 1.313800 1.405200 2 1 1\n", - " 9 1.393687 1.231012 5 5 0\n" - ] - } - ], - "source": [ - "df_results = get_results_dataframe(agents)\n", - "\n", - "print(\"Simulation Outcomes Summary\")\n", - "print(\"=\" * 70)\n", - "print(f\"\\nPopulation size: {len(df_results)} agents\")\n", - "\n", - "print(\"\\nCapital Distribution Statistics:\")\n", - "capital_stats = df_results[\"capital\"].describe()\n", - "for stat_name, stat_value in capital_stats.items():\n", - " print(f\" {stat_name:10}: ${stat_value:10.2f}\")\n", - "\n", - "print(\"\\nInequality Metrics:\")\n", - "print(\n", - " f\" Range (max/min): {df_results['capital'].max() / df_results['capital'].min():.2f}x\"\n", - ")\n", - "print(\n", - " f\" 90th/10th percentile ratio: {df_results['capital'].quantile(0.9) / df_results['capital'].quantile(0.1):.2f}x\"\n", - ")\n", - "print(\n", - " f\" Coefficient of variation: {df_results['capital'].std() / df_results['capital'].mean():.3f}\"\n", - ")\n", - "\n", - "print(\"\\nEvent Experience Distribution:\")\n", - "print(\" Beneficial events:\")\n", - "print(f\" Mean: {df_results['lucky_events'].mean():.2f}\")\n", - "print(f\" Std: {df_results['lucky_events'].std():.2f}\")\n", - "print(\n", - " f\" Range: {df_results['lucky_events'].min():.0f} to {df_results['lucky_events'].max():.0f}\"\n", - ")\n", - "\n", - "print(\" Detrimental events:\")\n", - "print(f\" Mean: {df_results['unlucky_events'].mean():.2f}\")\n", - "print(f\" Std: {df_results['unlucky_events'].std():.2f}\")\n", - "print(\n", - " f\" Range: {df_results['unlucky_events'].min():.0f} to {df_results['unlucky_events'].max():.0f}\"\n", - ")\n", - "\n", - "print(\" Net events (lucky - unlucky):\")\n", - "print(f\" Mean: {df_results['net_events'].mean():.2f}\")\n", - "print(f\" Std: {df_results['net_events'].std():.2f}\")\n", - "\n", - "print(\"\\nSample of Results (first 10 agents):\")\n", - "print(\n", - " df_results[\n", - " [\n", - " \"id\",\n", - " \"talent_norm\",\n", - " \"capital\",\n", - " \"lucky_events\",\n", - " \"unlucky_events\",\n", - " \"net_events\",\n", - " ]\n", - " ]\n", - " .head(10)\n", - " .to_string(index=False)\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Section 6: Distribution Analysis - From Normal to Power-Law\n", - "\n", - "This section visualizes the central finding: despite normal talent distributions, success follows a power-law pattern. We construct three complementary visualizations:\n", - "\n", - "1. Talent distribution histogram (should be approximately normal)\n", - "2. Success distribution on logarithmic scale (reveals power-law characteristics)\n", - "3. Lorenz curve quantifying inequality" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Gini Coefficient: 0.217\n", - "Interpretation: 21.7% inequality\n", - " → Low inequality\n" - ] - } - ], - "source": [ - "# Calculate Gini coefficient using imported function\n", - "capital_values = df_results[\"capital\"].values\n", - "gini_coefficient = calculate_gini(capital_values)\n", - "\n", - "print(f\"Gini Coefficient: {gini_coefficient:.3f}\")\n", - "print(f\"Interpretation: {gini_coefficient:.1%} inequality\")\n", - "if gini_coefficient < 0.30:\n", - " print(\" → Low inequality\")\n", - "elif gini_coefficient < 0.50:\n", - " print(\" → Moderate inequality\")\n", - "else:\n", - " print(\" → High inequality\")" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAABv4AAAHqCAYAAADMEzkrAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8pXeV/AAAACXBIWXMAAA9hAAAPYQGoP6dpAAEAAElEQVR4nOzdd3QUVRvH8e+mk1BCCb0jhN6L9K4U6aAgRURFUEAsKKh0IRRREJCiNAEVQUBQQUS6VGkKUnwRDKGGdNLLvn+sGbMkgYSUTcLvc05OdnbaMzOb7J37zL3XZDabzYiIiIiIiIiIiIiIiIhItmZn6wBEREREREREREREREREJO2U+BMRERERERERERERERHJAZT4ExEREREREREREREREckBlPgTERERERERERERERERyQGU+BMRERERERERERERERHJAZT4ExEREREREREREREREckBlPgTERERERERERERERERyQGU+BMRERERERERERERERHJAZT4ExEREREREREREREREckBlPgTyQBHjhzB09MTT09Pxo4da+twMkT88bVp0ybT953c+R07dqzx/pEjRzI9LlueE7k/W382RETk0TB//nzj+2bjxo2Zvv+BAwca+/fx8QHAx8fHeG/gwIGZHpOtz4mIiIjIo6BNmzZGmStedqqf3LhxoxHr/PnzbR2OlaTq+7JSvKqPlKQ42DoAEVtr06YN165dS9GyX3zxBY0aNcrgiB5OcHAwq1atAqBEiRL07NkzReuNHTuWTZs2GdMODg64ublRpEgRqlevTp8+fahbt26WiNXWdu7cyblz5wDo0aMHJUuWtHFEqZfweptMJrZu3UrFihWN+QMHDuTo0aMAfPbZZ7Ro0cImcYqISNrdvHmTBQsWcPDgQW7fvo2zszMFChSgQoUKVK9enREjRtg6xCzLx8eHtm3bGtN2dnY4OTnh7u5O2bJladWqFX369CF37tzput/sWNbIruW6hO693vGcnJwoVqwYLVq0YPjw4RQsWNAG0WWehOXEESNGMHLkSBtHJCJibf78+SxYsACwfE/OmDHDxhFlHYGBgaxZs4Y9e/bwzz//EBkZSdGiRalcuTJdu3albdu2mEwmW4eZoRLWZ3h5eWXLMklm8fHxMb7zq1SpQrt27dJ12/HlKhcXFw4dOoSrq6vVMmazmRYtWnD79m0Avvzy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1zJ16lTMZrPx3s2bN9m0aRM7duxg5cqV1KxZM9F6ydVBPOz/4oy8r4+KirJ6EP3VV19Ncvzh+AeW0uq1116zOpbOnTsza9Ys4uLi2L59u9XDMgkTO127dgUevk4sPY0YMcLqGPbv389bb73FV199Zby3fv16JkyYYJXQvXbtGitXrmTv3r2sW7fO+F797bffeOmll4zvtatXrzJ16lQqV66cLvFu3LjR6iF8sDwodOnSJU6ePGnVKCC99O7d22glunXrVh5//HFjXnwdTO7cuWnVqlWy2yhcuDANGzbk8OHDREZGsmvXLrp06QJYd/NZtmxZqlWrlux2Ulr2fxgpLctklIzef1auj5TMocSfSAoVKlSIN998k7Jly5InTx7s7Oy4ceMGM2fOxN/fn0WLFj0w8Td58mSjgNO9e3eeeuopfHx8mDVrFmFhYbz77rvs3r07UXcJ165do23btvTp04etW7fyww8/APD111/TpEkThg0bRqtWrXjttdcAy8C88a318uTJ89DHbGdnR82aNY1Cxr0tru71yy+/AJA3b17Gjx+Ph4cHt27d4uTJkwQEBACkOtarV6/SpUsXunTpQkBAAEWKFOHWrVsPjN3b25v33nuP4sWLs2jRIs6cOcPdu3f56KOPrJ4cSonChQuzdu1alixZwr59+wDrbmDv163WypUrjS/ZYsWK8dZbb2Eymfjwww+5fv06x44dY+XKlQwdOjTRuhEREcyePZu7d+8yffp0oqOj+fHHH5k4cWKarmu87t274+fnx40bN/jss8+YNGlSksuFhYXx3nvvGQXZfv360bp1a/bs2cOXX35JdHQ07733Ho0bN0702b169SrNmjWjX79+REdHJ0ou3rp1i9atW9OvXz+WL1/O4cOHiYiIYPny5fTp04d27doxc+ZM/v77b65du8aBAweMwmX8016FCxfGzc2NyMhIDh48yPLly7lz5w7r169n2LBhaT5PIiLZUZMmTYwudHbt2sWuXbtwdHSkRo0atG/fnr59+z5090zh4eG88847RtKvfv369O/fHxcXF44ePWokFW/dusWkSZOMpF+7du3o0aMHsbGxHDhwwBg7+PfffzeSfh4eHowePZoiRYqwZs0a9uzZw2+//WZ8V/7999/GjX+TJk0YMmQIsbGx+Pj4sHfvXmObp06dMhJtTz31FL169SIsLAxv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GML/7eoyNtJ6njn2v3lRAYnXjfD9b/69YkL/mxcTluYwCxQoYHSFYzabadWqVaIbwKtXrxIeHs6QIUOs3o+Ojja6BL106ZLRTUy82rVr33ffoaGhLFiwgD179uDr60tsbCwRERFcv37darmELexMJhOFChXCz8/PeG/WrFkpPt7UatSoEZs3byYgIIBvvvmG0aNHs379equxCl944QV69+7N9evXWbBgAe+88w5LlizBZDIxfvx4nnrqKRo0aJBhMYoAhIeH2zoEERERyYFmz4bz522z35Qm/v7++2/++OMPFi5cCICDgwOdOnViw4YNRuLv3LlzSbaaS6s7d+4wd+5cjh49ip+fH3FxcYSHhye6p3lYZrM52R4devTowZAhQ+jQoQPNmzenVatWNGvW7IHbLF68+AOTfpD4fq527dqsWrUqRXGn1KVLl3BwcKBWrVrGe/nz56dcuXJcunTJeC9XrlxG0g+gcOHCVveEIiK2EhUVxeeff862bduIiAA/P3B1LUvlyh4ZlvQD+Ppr+OMPy+sCBeDbby3V8NmBEn8i2dmGUpA3FoLtYWTW7yZNJN055oVc/z5xae9sPc9k/988p/yJ13Xx+G/+vRzc/pvn4Jouofbq1YspU6YAMHHixETzw8IsCcYlS5ZQpEgRq3lpGVh+5syZHDx4kHfeeYfSpUvj4uLCqFGjEo2P5+BgXSQwmUxGf+kZzdXVlTJlylCmTBlq167NE088wYYNG3j55ZeNZQoUKECBAgUoV64cFSpUoGXLlpw6dYo6depw+PBhdu3axfLlywHLjXtcXBxVq1ZlypQp9E7NY8wiIiIiIpns7bdh/PjMb/E3ZkzKl9+wYQMxMTE0b97ceM9sNuPk5MSECRPIkydPst1M3k9S9x0xMdb1G++88w6BgYG89957FC9eHCcnJ5555plE9zQP69KlS5QsWTLJedWqVeOXX35h3759HDx4kNGjR9OkSRM++eST+24zV66092oR30VowvNz77lJT7a8JxQRSc7t27fx8vLir7/+R0iIpevNihXb07fvMFxcHr6+7EFOnoRvvrG8trODVasgma+KLEmJP5HszN4Mjv/+FnkUVXnD8pOU3OUSd+GZUMstyc8rP9jyk46aN29OdHQ0JpMpySdEy5cvj5OTE9evX6dhw4ZJbqNChQrs2rXL6r3Tp0/fd78nT56k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mv+mP/4YnnrKdvFkFiX+RLKz3XngWjCUyGPrSERERERERERERETkEWI2m/npp59YunQpYWHR+PtDdHQe+vR5kzp16tk0tpMnYcGC/6bHjIGRI20XT2ZS4k9ERERERERERERERERSLDIykoULF7J7927Cw8HPD/Lm9eTll9+hcGEPm8b2998wYwbExlqmn3kGZs60aUiZSok/ERERERERERERERERSZFr167h5eXFlSv/EBwMAQFQrVoXnn56CI6Otk073b4NkydDeLhlukULS3efJpNNw8pUSvyJiIiIiIiIiIiIiIhIioSFhfHPP9e4cwfCw1146qmRNGnSwtZhERwMkyZZEpEA1arBDz+AwyOWCXvEDlckhxl1G1yBsNu2jkREREREREREREREHgFubhWpXv0l9u79nqFDx1G6dClbh0RkJHzwAfj4WKZLlIAdOyB3btvGZQtK/IlkZ7ljwR2wi7V1JCIiIiIiIiIiIiKSA/n7++Pu7g7Y8eefcPAgFC7ckddfb4eLi5OtwyM2FmbPhvPnLdPu7vDTT1C8uE3Dshkl/kSyswgXCIyw/BYRERERERERERERSUenTp1i9uzZtGnTgQoVBnLyJOTJA489ZgJsn/Qzm+HTT+HoUct0rlywZYulm89HlRJ/ItnZG6G2jkBEREREREREREREchiz2cy6dev48ssviYw0s2jRNzRtWpXHH6+XpbrP/PJL+Plny2sHB1izBpo3t21MtqbEn4iIiIiIiIiIiIiIiAAQEhLCnDlzOH78OHfvQkAAFClSn4YNK2WppN+PP8K6dZbXJhPMnw89e9o2pqxAiT8RERERERERERERERHh4sWLeHl5cfv2HQIDISjIROPGA3jqqT7Y2ZlsHZ7hwAFYsuS/6fffh2HDbBdPVqLEn4iIiIiIiIiIiIiIyCPMbDbz448/8vnnnxMeHoO/P8TE5KNfvzHUrFnL1uFZOXECPvrIMr4fwAsvwJQpto0pK1HiTyQ7+6AhRAeDY154/6itoxERERERERERERGRbCYiIoL58+ezb98+wsLA3x/y5avC4MHvULBgQVuHZ+X8efDygpgYy3T37rB0qU1DynKU+BPJzgocB/c4CLSzdSQiIiIiIiIiIiIikg3Z2dnh7e1DYCAEBkLNmt3p1es5HB2zVgrpyhVLy77ISMt0q1bwzTdgp+pxKzod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hmGQkZEBUODnTLyHjpF3O3bMQlzcRdSt25dLLrmIOnXqkp6ebnYs06Snw1tvBbNzp+t939/fYPz4DPr3zyU52bxceh15P0+tKOD1hT+Hw8F7773HV199RUJCAtWqVeP222/nkUce0Q+riIiIyFloDiUiIiK+YM6cOR7ru3LlylitVk6cOFGg/cSJE1StWvWM94mKisLf379A0a5hw4bEx8eTk5NDYGBgoR47LCwMf3+v/9it3Mo7wyI8PFxzYy+lY+RdbDYba9eupXv3W9ixA9auhbQ0gx49ehIWVrFcHyObDd54A2JjXWMQHGzw8cdw++0VTU6m15EvsNvtHunX62cgH330EfPmzWPMmDE0btyYP//8k2HDhhEaGkr//v3NjiciIiLilTSHEhEREV/QsWNHj/UdGBhIixYtWLduHddccw0ATqeTdevW0a9fvzPep3379nz99dc4nU78/r0g0/79+4mKiip00Q9cZ1boQ1bvlneMdJy8l46Rd9i2bRtjx47FZkti795QoBuVKkHjxq4z3crzMTpyBF55BY4fd22HhcFXX1no0sXcXKfS68i7eeq4eP0lJTdv3szVV19N165dqV27NjfccAOXX345W7duNTuaiIiIiNfSHEpERER8TfPmzc86V/nzzz9p3rx5kfscNGgQCxYsYPHixezZs4fXXnuNzMxMevbsCcDzzz/P+PHjT96+b9++JCUl8eabb7Jv3z5WrVrFhx9+yD333FO8JyUi4qMMw2DhwoW89NJLHD+exPHj8Nln86la1UH16manM9+ePa7r9+UV/apVg1Wr8Kqin5RfxTrj76233uKOO+6gfv36bo5zunbt2rFgwQL27dtHgwYN2LFjBxs3buTFF18scl++eiHLomY2ME5+tVD4irGnxic+Pp6UlBS39wsQGxuLPTfXI30XcI5hKe54F7b/cwl6OAGCISgzwSP9F5qH+//vhWh99bXsSzTWpUvjXXrON9aeHn/NoXyXXqdnd3JsKPmUIO/+JRlnTx0rb3uenuDu55idk8v+/fvP+hwdDgeHDh0iJCTknNfBio2NJdduL9Nj7wv0Pug7zDhW7nqcc/XjcDiKdc28m266CZvNxrvvvkt8fDzNmzdn2rRpJ5f6jIuLO3lmH0CNGjWYPn06MTEx3HrrrURHR9O/f38eeOCBoj8hEREflZaWxttvv836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NIcSERERERGR0mYYBvPnz+fTTz8lO9vgxAnw86vGoEEv0qSJin55du2C1193nfEHUKUKfP01dOpkbi6RoipW4W/48OFUqlSJN99887R97733HhkZGYwfP77E4UTk3HI+i6BCuo2cShFwvdlpRETkfDSHEhERETm32NhYvvjiC/bv3092dvZp+z/44AMTUomI+K7U1FTGjx/Pxo0bSUuDxESIjr6I/v2fJiws1Ox4XmPjRhgzBrKyXNt168KKFdC0qbm5RIqjWOsD/v7773Tt2vWM+7p06cL69etLkklECsn5TwXY9O9XERHxeppDiYiIiJzd1q1bufXWW1mxYgUrVqzg6NGj7Nq1i1WrVrFjxw4yMjLMjigi4lP++ecfnnjiCTZs2IjNBvHxFi6++F4eeeQVFf1OsXKl65p+eUW/1q3ht99U9BPfVazCX3Jy8lmXoQoODiYpKakkmURERETKJM2hRERERM5u3Lhx3HjjjXz99dcYhsGbb77JypUr+fTTT7FYLDzwwANmRxQR8RmxsbG88MILHDkST3w8ZGaG07fvSG699U78/Cxmx/MKhgELFsDEieB0utq6dYNffoHq1c3NJlISxSr81alTh19++eWM+9atW0etWrVKFEpERESkLNIcSkREROTsdu7cSffu3fHzc31clbfUZ/v27Rk6dKiWRBcRKYK6devSrFlnjh2DihWb8/jjE2nduo3ZsbyGwwFTpsDHH+e39e3rWt7zLH+vK+IzilX46927N7NmzeKjjz7CZrMBYLPZmDZtGrNmzeLOO+90a0gROYtQB1T596uIiHg9zaFEREREzs5isRAQEIDFYiEyMpIjR46c3Fe9enX2799vXjgRER9it8PGjRaiox+jQ4cBPP74KCIjI82O5TWysyEmBr77Lr/tuefgk0/A39+8XCLuUqwf44EDB3LgwAEmTJjAhAkTsFqtOByuwkOfPn2477773BpSRM6swlPxEAEVkuLNjiIiIoWgOZSIiIjI2TVq1IiDBw9y6aWX0rZtW2bMmMEFF1yAv78/U6dOpU6dOmZHFBHxWj///DPBwcE0a3Yxv/wC27ZB1aoVuO22O8yO5lVSUlzX89u507VttcKECfD44+bmEnGnYhX+LBYLr776KgMGDGDdunUkJycTERHBpZdeSv369d0cUURERKRs0BxKRERE5OzuvPPOk2f5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RER8k2EYfPvtt3z00UdkZtqx2SA3N4w+fZ6jdeu2ZsfzaklJMHo0/PVXftuQITB5MlitpsUSKbPcfo0/EREREREREREREZGyIisri/fff59Vq1aRkQE2G4SHN6N//xeIiqpqdjyvtncvvPkmxMe7tgMCYPx4eOwxc3OJlGXFKvxNmjSp0Le1WCw8+uijxXkYETmPH1qtws+Ri7OOFg8XEfEFmkOJiIiIFE5cXBxxcXE0a9aMihUrmh1HRMqxgwcPEhMTw4EDB0lJgcREaNXqNu64YyABATqv5lzWrIGJEyE727VdpQosWABXX21uLpGyrljvTLNnzyY3N5esLNfygkFBQWT/++qtUKECAadcwVQfWol4TnLN1mZHEBGRItAcSkREROTc5s+fz6RJk0hISABg4cKFtGjRgkcffZSOHTsyYMAAkxOKSHnicDgYOXIkBw/GkZgImZnB3HrrE1x66WVmR/NqTifMmwfz5+e3NW8O33wDDRqYl0ukvPArzp1mzJhBZGQkb775Jr///jt//PEHv//+O2+88QaRkZFMnz6dDRs2sGHDBtavX+/uzCIiIiI+SXMoERERkbObNWsWI0eOpEePHkyfPh3DME7u69ixI999952J6USkPLJarfTu/SjHj1uwWuvx8MNvq+h3HpmZruv5nVr0694dNmxQ0U+ktBTrjL+RI0cyePBgevXqdbItJCSEO+64g+zsbF5//XUWLlzotpAiIiIiZYHmUCIiIiJn9/HHH/PII4/wyCOP4HA4Cuxr0KAB+/btMymZiJRHTids3w5797ahS5fhXHppa4KDK5gdy6sdPeq6nl9srGvbYoEXXoBRo1zfi0jpKFbhb8eOHdSuXfuM++rUqcOuXbtKFEpECqfNkhfxz07FHhTKH7eNNjuOiIich+ZQIiIiImd37Ngx2rVrd8Z9AQEBZGRklHIiESlvNm3axJo1a7j//sf47TcLmzdDeDh069bR7Gheb+tWGDMGUlNd2xUrwvTp0KePublEyqNiFf5q1arFZ599xhVXXIHllFK9YRh8+umn1KxZ020BReTsGleYil91J84kP/5AhT8REW+nOZSIiIjI2dWsWZNt27bRqVOn0/b98ccf1K9fv/RDiUi54HQ6mTdvHvPnzycry+DQoTpUrXo7depASIjZ6bybYcC338LUqa6zJAFq14YlS6B9e3Oz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auNlSjpESp+Wlsa+/4Dadeoi+l0maieklPm6xGIg7X0a1LIAeb6Cyjsurkta/rmKK8O4yio2rktSSX+vqvM+Vsa6yiu216kZyFFQkPs+WFBUSjoUlJTKJEd7+fIllJRVyuQ7pCzjKkul3UdZv1tRKemoVat2qfKnkqiqOVRp8qGEhAQ0btxYav6EhIQSbTP/GLRpsxktWz7HmjVO0NNrByAX/ztMVAWIxWLk5uYiJyenTNoXqOzxHFV9PEdVH89R1Zefl5V1DqUgrmpZWSFxcXH4+uuvsWfPHhgYGAjTPTw8cOPGDezfv/+j68jKysKff/5ZnmESERFRDaKrqwtVVdXKDuOTMIciIiKiilbVcqjS5EM6OjpYs2YNhg0bJkwLCwuDv78/rly58tFtMn8iIiIieZV1DlXln/hr2LAhlJSUpF66nJiYKNUDqyjKysrQ1dWFoqIiK9tERERUJLFYDJFIBGXlKp8ifRRzKCIiIqooVTWHKk0+1LhxY6mn+5g/ERERUXkorxyqamVkMqiqqqJbt264evUqvvnmGwB5w0JdvXoV1tbWJVqHoqJilepxRkRERFTemEMRERHR5640+ZC+vj4iIyNhZ2cnTLty5Qr09fVLtE3mT0RERFTZFCs7gJKwt7fHvn37cPjwYTx9+hQ///wzMjIyMHr06MoOjYiIiKjKYg5FREREn7uP5UMLFiyAl5eXML+trS0uXbqEoKAgPH36FH5+fnjw4EGJO04RERERVbYq/8QfAAwZMgRJSUnYsGED4uPj0aVLF2zbtq3EwywQERERfY6YQxEREdHn7mP5UExMDBQV/79fvKGhITw9PeHj4wNvb2+0bdsW/v7+6NSpU2XtAhEREZFcFMRisbiygyAiIiIiIiIiIiIiIiKiT1MthvokIiIiIiIiIiIiIiIiouKx8EdERERERERERERERERUA7DwR0RERERERERERERERFQDsPBHREREREREREREREREVAOw8FcN3bhxA99//z3MzMygra2N33//vdj5z549C3t7e/Tq1QuGhoaYMGECLl26VEHRVm/yHuubN2/CysoKPXv2hJ6eHgYNGoSQkJCKCbaak/dYF3Tr1i107doVI0aMKMcIaxZ5j/e1a9egra0t9S8+Pr6CIq6+SnNtZ2VlYf369bCwsICOjg769euHAwcOVEC01Zu8x9rFxUXm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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "Inequality Quantification:\n", - "============================================================\n", - "Gini Coefficient: 0.2171\n", - " Interpretation: 0 = perfect equality, 1 = perfect inequality\n", - " Observed value of 0.2171 indicates substantial inequality\n", - "\n", - "Wealth Concentration:\n", - " Top 10% control: 18.4% of total wealth\n", - " Top 20% control: 32.1% of total wealth\n", - " Bottom 50% control: 34.5% of total wealth\n", - "\n", - "These patterns mirror real-world wealth distributions despite\n", - "starting from equality and using only random processes.\n" - ] - } - ], - "source": [ - "fig, axes = plt.subplots(1, 3, figsize=(18, 5))\n", - "\n", - "# Panel 1: Talent Distribution\n", - "talent_norms = df_results[\"talent_norm\"].values\n", - "axes[0].hist(\n", - " talent_norms, bins=20, edgecolor=\"black\", alpha=0.7, color=\"skyblue\"\n", - ")\n", - "axes[0].axvline(\n", - " talent_norms.mean(),\n", - " color=\"red\",\n", - " linestyle=\"--\",\n", - " linewidth=2,\n", - " label=f\"Mean: {talent_norms.mean():.3f}\",\n", - ")\n", - "axes[0].axvline(\n", - " np.median(talent_norms),\n", - " color=\"orange\",\n", - " linestyle=\":\",\n", - " linewidth=2,\n", - " label=f\"Median: {np.median(talent_norms):.3f}\",\n", - ")\n", - "axes[0].set_xlabel(\"Talent Score (Euclidean Norm)\", fontsize=11)\n", - "axes[0].set_ylabel(\"Frequency\", fontsize=11)\n", - "axes[0].set_title(\"Talent Distribution: Normal\", fontsize=12, fontweight=\"bold\")\n", - "axes[0].legend(fontsize=10)\n", - "axes[0].grid(axis=\"y\", alpha=0.3)\n", - "\n", - "# Panel 2: Success Distribution (Log Scale)\n", - "capital_vals = df_results[\"capital\"].values\n", - "axes[1].hist(\n", - " np.log10(capital_vals), bins=25, edgecolor=\"black\", alpha=0.7, color=\"coral\"\n", - ")\n", - "axes[1].set_xlabel(\"Log₁₀(Capital)\", fontsize=11)\n", - "axes[1].set_ylabel(\"Frequency\", fontsize=11)\n", - "axes[1].set_title(\n", - " \"Success Distribution: Power-Law\", fontsize=12, fontweight=\"bold\"\n", - ")\n", - "axes[1].grid(axis=\"y\", alpha=0.3)\n", - "axes[1].text(\n", - " 0.05,\n", - " 0.95,\n", - " f\"Skewness: {stats.skew(np.log10(capital_vals)):.2f}\",\n", - " transform=axes[1].transAxes,\n", - " verticalalignment=\"top\",\n", - " bbox=dict(boxstyle=\"round\", facecolor=\"wheat\", alpha=0.5),\n", - ")\n", - "\n", - "# Panel 3: Lorenz Curve\n", - "sorted_capital = np.sort(capital_vals)\n", - "cumsum = np.cumsum(sorted_capital)\n", - "cumsum_normalized = cumsum / cumsum[-1]\n", - "pop_share = np.linspace(0, 1, len(cumsum_normalized))\n", - "\n", - "axes[2].plot(\n", - " [0, 1], [0, 1], \"k--\", label=\"Perfect Equality\", linewidth=2, alpha=0.7\n", - ")\n", - "axes[2].plot(\n", - " pop_share, cumsum_normalized, \"b-\", label=\"Actual Distribution\", linewidth=2\n", - ")\n", - "axes[2].fill_between(\n", - " pop_share, cumsum_normalized, pop_share, alpha=0.3, color=\"blue\"\n", - ")\n", - "axes[2].set_xlabel(\"Cumulative Population Share\", fontsize=11)\n", - "axes[2].set_ylabel(\"Cumulative Wealth Share\", fontsize=11)\n", - "axes[2].set_title(\n", - " \"Lorenz Curve: Inequality Visualization\", fontsize=12, fontweight=\"bold\"\n", - ")\n", - "axes[2].legend(fontsize=10, loc=\"upper left\")\n", - "axes[2].grid(True, alpha=0.3)\n", - "axes[2].set_xlim(0, 1)\n", - "axes[2].set_ylim(0, 1)\n", - "\n", - "plt.tight_layout()\n", - "plt.show()\n", - "\n", - "gini = calculate_gini(capital_vals)\n", - "top10_share = (\n", - " df_results.nlargest(10, \"capital\")[\"capital\"].sum()\n", - " / df_results[\"capital\"].sum()\n", - ")\n", - "top20_share = (\n", - " df_results.nlargest(20, \"capital\")[\"capital\"].sum()\n", - " / df_results[\"capital\"].sum()\n", - ")\n", - "\n", - "print(\"\\nInequality Quantification:\")\n", - "print(\"=\" * 60)\n", - "print(f\"Gini Coefficient: {gini:.4f}\")\n", - "print(\" Interpretation: 0 = perfect equality, 1 = perfect inequality\")\n", - "print(f\" Observed value of {gini:.4f} indicates substantial inequality\")\n", - "print(\"\\nWealth Concentration:\")\n", - "print(f\" Top 10% control: {top10_share:.1%} of total wealth\")\n", - "print(f\" Top 20% control: {top20_share:.1%} of total wealth\")\n", - "print(\n", - " f\" Bottom 50% control: {df_results.nsmallest(50, 'capital')['capital'].sum() / df_results['capital'].sum():.1%} of total wealth\"\n", - ")\n", - "print(\"\\nThese patterns mirror real-world wealth distributions despite\")\n", - "print(\"starting from equality and using only random processes.\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Section 7: Correlation Analysis - Talent versus Luck\n", - "\n", - "We now examine which factors correlate more strongly with final outcomes. Standard Pearson correlations quantify linear relationships between variables. We compare correlations between:\n", - "\n", - "1. Talent and log(capital)\n", - "2. Beneficial events and log(capital) \n", - "3. Net events (beneficial minus detrimental) and log(capital)\n", - "\n", - "The log transformation of capital improves linearity and interpretability." - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Correlation Analysis with Log(Capital)\n", - "======================================================================\n", - "\n", - "Talent Measures:\n", - " Overall talent (norm): -0.0447\n", - " Intensity dimension: -0.0417\n", - " IQ dimension: 0.0856\n", - " Networking dimension: -0.1028\n", - "\n", - "Luck Measures:\n", - " Beneficial events: 0.5397\n", - " Net events (lucky-unlucky): 0.9199\n", - "\n", - "Comparative Analysis:\n", - " Luck correlation / Talent correlation = -12.07x\n", - "\n", - "Key Finding: Beneficial events are -12.1 times more correlated\n", - "with success than overall talent. This quantifies the dominance of\n", - "stochastic factors over ability in determining outcomes.\n" - ] - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAABW0AAAHqCAYAAAB/bWzAAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8pXeV/AAAACXBIWXMAAA9hAAAPYQGoP6dpAAEAAElEQVR4nOzdd3hUZdrH8W8mZSaTSkICSYQEQicFUBMEBJeuqGvBgh3b7sqqK+6+ggUXVER3N64FXduiuCLiKlhWQCmiglIUSKFIbwkQEsikTOrM+8eYIYEkTCBlkvw+18VFZs4zZ+45Z07ynPs853487Ha7HRERERERERERERFxC4bmDkBERERERERERERETlLSVkRERERERERERMSNKGkrIiIiIiIiIiIi4kaUtBURERERERERERFxI0raioiIiIiIiIiIiLgRJW1FRERERERERERE3IiStiIiIiIiIiIiIiJuRElbERERERERERERETeipK2IiIiIiIiIiIiIG1HSVkTO2dq1a+nZsyc9e/ZkypQpzR2OtDL33nsvPXv2ZOLEic0dSpv2008/OY/z1NTU5g5HRESkRfnkk0+cf0dffvnl5g5Hmsj06dPp2bMnY8aMwW63N3c4rVpRUREXXnghPXv25K233mrucEQahFdzByAiTWv48OEcOnTIpbZz584lOTm5kSM6OxaLhXfffReAqKgorrnmmmaO6HQVFRXMmzePhQsXsmfPHsrLywkODiYqKoq+ffty0003ERsb29xhurVNmzaxatUqAG6//fZmjqb+srOzefnll1m1ahU5OTmEhoZyySWXcP/999O+fXuX17Nv3z5eeuklfvjhBywWCx07dmTMmDH84Q9/wN/fv9bX/fWvf+WDDz5wPn7zzTcZOnSo8/HLL7/MK6+8Uuvrq/4OOP/884mPjyctLY2XXnpJnWEREWlRqv7Nu/rqq5k1a1YzR+T+Pv30U+bPn8/27dspLS0lODiY8PBw+vbty7XXXku/fv2aO0S3lpmZyUcffQTAbbfdhoeHRzNHdLrS0lL+/e9/89lnn3HgwAHMZjPnn38+kyZNom/fvi6t45NPPmHq1Km1Ln/22WdrPVf78ssveeihh5yP77nnHv785z+fVYxms5nrrruOt99+m7fffpsJEybg5+fn0mcQcVdK2opIi2SxWJwd76SkJLdM2j7++ON88skn1Z47evQoR48eZePGjSQkJChpewb//ve/AQgPD2fYsGHNHE39ZGVlceONN3L48GHnc4cPH2b+/Pl8++23zJ8/nw4dOpxxPdu2beOWW24hPz/f+dyBAwd46623WL16Nf/5z39qTNxu2LCB+fPnN8yH+dV1111HWloa3333Hb/88gs9evRo0PWLiIiIe3jllVdOGxGcnZ1NdnY2GRkZREREKGl7Bu+99x5lZWV4e3vz29/+trnDOU15eTn33nsvP/zwg/O50tJSli9fznfffccbb7zBRRdd1Gjvf+LECZ555pkGjbEyaZubm8vChQu55ZZbGi1+kaagpK1IG/Piiy9SUlLifPynP/2J7OxswJFk7N27t3NZz549mzy+1mLv3r3OhG27du3405/+RHR0NDk5OezevZuvv/66mSN0f8ePH2fFihUAjBo1yuXRCVarFV9f38YMzSXPPPOMM2E7evRorrrqKhYtWsRXX31FZmYmzzzzDC+99NIZ1zN16lRnwvaGG25g2LBhzJkzh/Xr17N161Zmz57NI488Uu01paWlPPHEE9jtdoxGY7Vjvjbvv//+ac+d+jtg5MiR/PWvf8Vms7Fw4cLT3ldERERavsLCQl5//XUATCYTDz74IL179+bEiRPs27ePlStXuuWoUXdSXl7OZ599BsDgwYPrvDOqqqKiIsxmc2OG5jRv3jxnMrRHjx7cf//9bNmyhddee43S0lKmTJnC119/jY+Pj8vrfPHFF0+7m6xLly41tn3uuec4duxYnX3V+sbYpUsXunfvzo4dO/jkk0+UtJUWT0lbkTYmPj6+2uOqf4R79OjBBRdcAMCRI0eYOXMmGRkZHDlyhIKCAvz8/OjVqxe33XYbI0eOdOn9cnNzef3111m5ciWZmZn4+vrSv39/7rvvvmpX59euXcttt90GOG5ZGzduHP/85z/55ZdfCA0N5c4773QunzJlCgsXLnS+dt26dc7kUlJSEu+9916Nsfz+979n5cqVACxcuJA+ffo4lz3xxBMsWLAAgDfeeINhw4axbds2XnzxRTZt2oTFYsHf35+OHTuSmJjI73//eyIjI2v93Fu2bHH+fNVVV3HjjTdWW/7AAw9gtVqdj6veVvTHP/6R+++/H4CDBw8yYsSIGj9bcXEx77zzDkuXLmXv3r3Y7XaioqIYPXo0Dz74oLPdiRMnePvtt1m+fDmHDh3C09OT6Ohorr322modmQMHDvD666+zevVqsrOzCQgIIDk5mfvvv7/aiGCbzcbrr7/O//73P/bv34/dbic0NJQePXowatQorrvuOmd8L774IsuXLyczMxMvLy9CQkLo06cPv/3tbxk1alSt2w9g1apVlJWVAY7OblWnbq/27dvzzjvvcPDgQZ566qk6R15v2LChzvet1KVLF0JDQ11qe6rs7GyWL18OQEBAAH//+98xGo0MGTKEwYMHk5+fz7Jlyzh27FidZRJSU1Od36XY2FimT5+Oh4cH8fHxDB06FLvdzscff8zkyZPx9vZ2vm727Nns3r2bIUOGUFpayrp1684Yc+WxX5fQ0FB69uzJ1q1b+frrr5W0FRGRVqeuvlfVMmPbt2+v9rovvviCDz/8kG3btmG1WgkPD+f8889n2rRpBAQE1Pp+jz32GP/9738BGDZsGK+88kqNSbKnn37aGcsrr7xSrR/1r3/9ixdeeAGAadOmcfPNN3Pw4EFeeOEF1q5dy/Hjx/H19SU8PJzExERuv/12evXqVWtMO3fupLS0FIChQ4dy5513Vlv++9//vlo/9tR+fNXSE5V99KioKOfFeHCUEZs/fz6fffYZO3fupKysjI4dOzJw4EBmzJjhbOdqf9fVcw6A+fPns2DBAvbs2UNZWRnt2rUjNjaWwYMHc8899wCu93drs3HjRo4dOwac3o89dXsNHz6c2bNns2vXLn73u985zwNqkpaW5tLF+MjIyDrPVSq3Q6WnnnqKfv36MXr0aNLS0vj+++85fPgwK1euZMyYMWd8v0pxcXGcd955Z2y3Zs0aPvnkE9q3b8+ll15a6/nb2cQ4aNAgduzYQUZGBllZWURERLgcv4i7UdJWRGqUlZV12q39eXl5rF27lrVr1/Lcc89x1VVX1bmOzMxMJkyYUO328LKyMlatWsWaNWt48cUXnZ3iqtatW8enn36KzWZzxvLMM8/QrVs3Bg0adNaf6corr3QmbZcuXepM2lZUVLBs2TLAkZQaPHgwx48fZ+LEieTm5jpff+LECU6cOMG2bdsYO3ZsnR2hqvWTvvzyS/r06cOQIUMICQlxPn8uo0ELCgq45ZZb2Lp1a7Xnd+7cidVqdXZis7KyuOmmm8jMzKzWbsuWLfj7+zuTthkZGdxxxx1YLBZnm9zcXBYvXsyqVat49913SUhIAOC11147bYRoVlYWWVlZ5OfnOzuxM2bM4OOPP3a2KSsr49ChQxw6dAiTyXTGpO3PP//s/LmumlqffvopBw4cqHNdVd18880utaur/taZbNy40fn97dOnD0ajEQCj0UifPn1Yu3YtFRUVbNq0qc4LID/99JPz58TEROeolvDwcKKiojh48CB5eXns3LnTOUp++/btvP3225jNZqZPn15njbGqLrnkEo4dO0ZwcDADBw7kj3/8IzExMae169OnD1u3buXAgQNkZ2cTFhbm0vpFRERaq0cffbRanwdw9nkefPDBWpO2KSkpzoTtRRddxMsvv1zrqMYrrrjCmdhasmRJtX7U0qVLAfD29uayyy6jvLycu+66i7179zrb5Ofnk5+fz65duxgwYECdSduq/dg1a9Ywf/58LrnkEjp27Oh8/lz6sWVlZfz+97/n+++/r/b8vn372LdvnzNp62p/tz7nHIsWLeLJJ5+str7K8mW7d+92Jm1d7e/Wpmo/tupAkVOtX7+eRYsWuTxJ2YMPPujS/CRVB4HU5MSJE+zatQtwfG+qDuzp37+/c99s2LChXknbm2++mZycHPz9/RkwYAB/+MMfThs0ZLVamTZtGuAYOLNjx44GjbHq9v75558ZN26cy/GLuBslbUWkRu3bt+fhhx8mJiaGgIAADAYDWVlZPPfcc+Tm5vLaa6+dMWk7ffp0Z+fpqquu4vLLL+fgwYM8//zzFBUV8eijj7Jy5crTbgE6dOgQI0aM4LrrruPzzz/nf//7H+C40jpo0CB+//vfc8kllzg7ar179+bxxx8HqHMkw/Dhw/Hz86OwsJClS5c6i96vW7fOmZy97LLL8PLyYtOmTc7nLr/8cq699lqKiorYv38/K1euxGAw1PnZ4+Pjne915MgR/vKXvwDQuXNnhgwZwk033UT37t3rXEddXnjhBWcHNjg4mD/84Q/ExsY6b1mrNH36dGfCNjIykj/84Q9ERESwfft25wgRu93OlClTnAnbO++8kyFDhrBlyxZeeOEFioqKmDp1Kl988QUeHh7OEaSBgYE88cQThIWFceTIETZu3Mjx48ed713ZLioqikceeQR/f3+ysrJYv369S7eIVXbSfHx8qp0knOrAgQMMGTKECRMmUFZWRlRUlMvbsbFU7UyfOpK26ujdgwcPntN6Kl9/8OBBevfujc1m4/HHH6esrIy//OUvLo10qJSVlQU4Rgl//vnnrFy5knnz5p1WIiE6Otr5886dO5W0FRGRNm3p0qXOhK2npye33347AwcO5Pjx43z22We1lhF49913nSUILrjgAl577TXnRd6aJCYmEh0dzb59+/jmm28oLS3Fx8eHAwcOOO/KGTJkCO3ateOXX35xJmwHDRrEnXfeSUVFBQcPHmTVqlXV7s6pSXR0NJGRkWRmZlJQUOBMcnbs2JFBgwZx/fXX079//3ptp6ree+89Z8LN19eXe++9l/j4eA4fPsyHH37obFef/q6r5xyVo329vLx44okniI6O5tixY2zZsoXNmzc71+lqf7c2lf1YqN53OtXBgweJj4/n7rvvxsvLq8kmzqraxwwODsbT09P5uD591VNV7ofjx4+zfPlyvv32W15//fVqo41ffPFFDhw4wMiRIxk7dmytSduzjfHUvqpIS6akrYjU6LzzziMsLIx3332XX375hfz8/GpXgPfu3UtBQUGtybcTJ06watUqAMLCwpxXo7t3787gwYP5+uuvOXHiBN99991pV29DQ0P55z//iY+PD/Hx8c6k7f79+wGIiYnBy+vkr6+AgACXbu02mUyMHj2ahQsXsmfPHrZv307Pnj2doxPAMYoBqLb+jh070qVLFzp27IiHh8dpt4jVJCQkhJkzZzJ16lSKioqcz+/fv5958+axYMECXnjhBUaPHn3GdZ3KZrPxxRdfOB//4x//YMiQIQBcfPHFztGzVfeBp6cnb731lrPMwcUXX+x8/bZt2/jll18ARwK8ciRC//79SUhIYOPGjezcuZOMjAzi4uKcHX1fX186d+5Mz5498fX1PS2JX9kuICCAzp07Exsbi4+PD+PHj3fpc1Z2iIOCgupsFxUVxeuvv15tn9Xl1NsZz1Z+fv5p6zIajcTHx1fb56eeGFV9XLVdTeq7nrlz55Kamkq/fv249dZbz/gZTCYTl19+OYMHD6ZDhw7s3buX1157jezsbAoKCnj22Wd55513qr0mMDDQ+bMrJy0iIiKt2aeffur8+e6772by5MnOx7UNcFi5cqUz0ZqYmMjrr7/u0sjVK664gldeeYWCggK+//57hg8fzpIlS5zLr7zySqB6PzYsLIyYmBiioqIwGAwu1fj09vbm+eef58EHHyQnJ8f5/OHDh/nkk0/45JNPeOyxx5y3+NdX1W02depUbrjhBufjynOGs+nvunLOUbltvL29iY6OJj4+Hn9/f+c5QNVtAGfu79amah+prr6s2WzmrbfeIjg42KX1Vi0xcS6qlreoq49ZtV1tvL29+c1vfsPw4cOJioriyJEjvP766+zdu5eysjKmT5/OV199BTjKO8ydO5eAgADnaNuGjlF9VWlNlLQVkRq98847PPvss3W2qazzWpPK2k/gGLlX2y3pVa9CV0pMTHTeGla1A1P11v2zdeWVVzrr4S5dupTu3bs7SyNER0eTmJgIOEY8xMTEsHfvXt566y3eeust/Pz86Nu3L1dccQXjx48/42jbsWPHcv755ztLDGzcuJHCwkLAMTnBU089dVZJ2+PHj3PixAnAMQq1tpIR+/fvd96i36lTp2p1aavas2eP8+etW7fWua/i4uIYP348mzZt4siRI9xwww14eHjQqVMnLrroIiZOnOicbODaa6/lX//6F9u2beOqq67C09OTmJgYLr74Yu666y7Cw8Nd+rxnul1syJAhLidsoeFq2m7ZsuW0k5XKem1VR49X1oSrVFmnFzjjRBP1WU9eXh4vvvgi3t7ePPXUU2f8fgLOWwArDR48mNjYWG6//XbAMQq9uLgYk8nkbOPq7XsiIiJtQdUSBJdccolLr8nIyAAcZQhef/11lyepuvLKK3nllVcARz92+PDhzsEHfn5+DB8+HHAMcLjgggvYsGEDn376KZ9++ikmk4levXoxatQobrvttjNOLnXhhReyZMkSli5dysqVK/npp5+c/U9wJFGvuuqqagkyV7myzerT363POcc111zDl19+idVq5Y477gAcAzQuvPBCbr/9duct+K72d11RV99pwIABLidsoeFq2la9SFBXH9PViwmnJr0vvPBCZwmwffv2sXfvXmJiYnjmmWeoqKjgL3/5Cx06dKhzvQ0Zo0hLpaStiNSoajH4u+++myFDhuDt7c306dOdozIrE4Lnoqart1WvRtcnGeeKgQMHEh4eztGjR1m6dCkXXXQR2dnZANU6G76+vnzwwQd88MEHrFu3jl27dpGdnc26detYt24dJ06c4N577z3j+4WFhXHbbbdx2223UVZWxhdffMHUqVOx2+0cPXrUWRO06q1zFRUVzp/PdHXYw8OjyWbvrdxX1113HR06dOCLL75g69at7N27l/3797N//35WrFjBl19+SWBgIH/605/o0aMHX331Fdu3b+fAgQPs2rWLXbt2sWbNGhYuXFjn/m3Xrh3gqKVcl7om8qpJU9S0rVqioXISipoen6l8QdX1VB3pUtN68vPznSNuT+04V7rnnnsICAioM3FdWbsYHN/FvLy8aknbqhdPKveRiIhIa1FbnwwabtSep6cnFRUVFBYW8tJLL51WY7U2lQMMNm/ezIoVK9i3bx9paWkAjB492vn32mAw8MYbb7BgwQJWr17Nrl27yMzMZNOmTWzatIn9+/dXm+yrNoGBgVx33XVcd9112Gw2vvvuOx544AGKi4spLi5m9+7d9OvXr9ZtVnVuiHPREP3dyn7skCFD+OCDD/jkk09IT09nz549HD58mM8//5xly5bx+eef06lTJ5f7u7Wp2kfKy8urdbBCffuxDVXTtmof88SJE5SXlzv75fXpq9amU6dOtGvXznnM5ObmEhMTw9GjRwHHhHk1jbR98803efPNN1m0aNFZx1j13EF9VWnpzjwMR0TapCNHjgCOka5/+ctfuOiii+jTp4/zD+2ZdO7c2dm56ty5M1u2bHHWUa38l56ezgMPPHBW8VUdRVif5LHBYHAWo9+5cyevvfaac1nlLWXguCIeEhLCpEmTePfdd/n+++9ZtmyZc+Rj5S0+tTl48OBpNZS8vb25+uqrq3XwKmOvWou3aifku+++O23d7dq1cya2S0pKWLNmTY0xdO7c2bmdKhOmNak6UiApKem0/bR9+3Y2bdrEjTfeCDi2zdChQ3n++ef5/PPP2bhxo3NkZnZ2Nhs3bnSub9y4cbz44ossWbKEn3/+2VkKo2qttdpUjgwuKytz1lutSVMlrU+VnJx82naqvGWtf//+zm2/detW54iIkpIS5+2Qnp6ep81mfKrzzz/f+fPGjRudIzWOHDnirFUcFBREt27dzuozVJ7oVVW1npuXl9dpoz/27dvn/Pls31dERMRd1dYn27BhQ41ljapO2ll5m/6ZTJgwwVl3c968ebzxxhsux1d5YdZisTB9+nTn86f2Y/38/Jg4cSJvvfUWK1eu5IcffnAmt77++us63+PEiRNs2rSp2nMGg4Fhw4bRtWtX53OVCdr69GPBtW1Wn/5ufc457HY7/fv356mnnmLhwoX8/PPPTJkyBXAkdr/99ltnO1f7uzWpeodbZYm3mjRXPzY4ONgZY3l5ebU+YdV970oJupr6k/v37692kaO+yelzibHq9lZfVVo6jbQVkRpFRUWxd+9eTpw4wRtvvEHPnj2ZO3dutdui6hIcHMzQoUNZtWoV+/fv5w9/+APjx4/Hz8+PzMxMtmzZwtdff838+fPP6gpu1cTnL7/8wrJlywgODj7jrUDg6NTOmTMHgNWrVwMnJ3eo9PPPP/PMM88wevRooqOjadeuHdu3b6e4uBg4/RadU+3fv58777yTiy66iEsuuYTY2FjsdjtfffWV8+pveHi487agzp07O1/72Wef0blzZwoLC3n77bdPW7fBYODyyy/n/fffB+Dhhx/mvvvuo2vXrhw4cIAVK1bw5ptvOvfBN998Q0VFBffcc49zIrLKGrV/+9vf6NWrFz169OCXX35h3bp1/N///R9jx47Fy8uLQ4cOkZqayrJly1i/fj0ADzzwAH5+fpx//vl07NiRiooK0tPTnfFVbpsJEybQu3dvEhIS6NChA4WFhdUSx2fahgMGDHBORpGRkUFERESd7V3VUDVt6xIWFsaIESP4+uuvyc/PZ/LkyVx77bV88sknFBQUADBy5MhqHdjKCb8qSyyAY9Rrnz592LJlC3v27GHatGlccsklzJkzx5nAvfbaa/H29iY4OJipU6eeFsv777/v7LzecMMN1WaLvu666xg6dCijR48mKiqK3bt3V7uQMWTIkNMmRamcEKRTp06ahExERFqkjIwM/v73v5/2/D333ENQUBDBwcGcOHGCffv2MW3aNLp27Vpjnwwc/crKSaveeustysvLSU5O5sSJE3z22WdMnz79tElSg4ODef3117nhhhvIy8sjJSWFDh068Nvf/vaMsY8bN45Zs2ZRXl7u7MeGh4czcOBAZ5sjR45wxx13cOmll9KtWzfn5KWVI1/P1AfLy8vjhhtuoF+/fowcOZIePXrg7e3Njz/+6OwH+Pj4OPsu5513HgaDAZvNxo8//khKSgp+fn61JqOvvPJKtm3bBjjubMrJySE+Pp4jR46wYMECPvzww3r3d10953j66afJzs5m0KBBRERE4OnpWe0OpMrb7l3t79ZmwIABzp8zMjJcSn66oqFq2gLceOONPPPMMwA88cQTPPDAA2RkZDgnievYsSO/+c1vnO1vvfVW1q1bBzgmaqs8h3vwwQeJiIhg3LhxdOnShaysLOcke+CoL1x5rnPfffc5+8KVvvvuO+d7Vp47VZ4j1TdGwDlAAqrvB5GWSElbEanR9ddfz/PPPw84alaB44p3ly5dqtVArctf//pXJkyYwOHDh1m1apXLow9c4e/vT9++fcnIyMBisTBp0iTgzLcCAfTp04fY2NhqCcRTbye32+1kZGQ4a46d6vLLLz9jjHa7nTVr1tQ6MuChhx5y/tyjRw/69+/Pxo0bKSkpcW7zU+Os+toNGzawfft2jh8/7uzMQPXbnZ588km2bdvG4cOHOXToEI8//rhzWVJSEuC4wj9r1izuuOMOLBaLs/ZZbfLz8/nqq6+ctYGrat++vfOkIScnh3nz5jFv3rzT2nXr1s3Z0a/NJZdcgre3N2VlZfzwww/OulgtxWOPPUZaWhqHDx9m2bJlztrJ4Kgz9thjj7m0npkzZ3LrrbeSn5/PggULWLBggXNZ7969nd99f39/Z222qpYvX+5M2o4cOZKhQ4c6l9nt9lqPzfbt258WY05OjjPpPWrUKJfiFxERcTe//PKLs9xXVTfeeCNBQUHccMMNzqRT5QXksLAwAgMDT5tjYezYsVx99dUsXLiQ8vJy51wIlWqrZ9qlSxdefvll7rrrLsrKynjssccICwurtXZrpZCQEAYNGuQcEQqORO6ptez37NnDq6++WuM6Ku86O5PKcgo1+d3vfuesxRsQEMBll13GF198gc1mc2672NjY0xJ0ALfddhvff/89a9asoaioiH/+8581voer/d36nHMUFxezdOnSahMRVzKZTM4JeV3t79amf//+hIWFkZ2dzQ8//OAcpetObrrpJlasWMEPP/zAjh07qp1D+fj4MGvWrDPWPq60YcOGGstvmc1mnn76aefjmiYkzs/PdyZh4+LiqvVnzybGynOvuLi4Bhv0IdJcVB5BRGp0xx138Kc//YmoqCh8fX1JSkri3XffrdfIusjISBYuXMhdd91F165dMRqN+Pn50bVrV6666ipee+21c/pDmpKSwsUXX1znjKy1qXoLmZeX12md1y5dunDPPffQr18/2rdvj5eXF2azmfj4eKZNm3baBE6nSkxM5O9//ztXXXUVPXr0IDg4GC8vL9q1a8fFF1/Mm2++eVq91L/97W/OkY0hISHcdtttvPjiizWuPyAggA8//JAHH3yQXr16YTKZ8PX1JTY2ttoojcp9cPfddzv3gdlspnfv3s5SBQB9+/Zl0aJF3HjjjXTq1Alvb28CAwPp0aMHN954I++8846z7U033cRll11G586dMZvNeHl50aFDB6644grmzZvnvEXu3nvvZcSIEc7vkLe3N1FRUdx44428++67eHp61rkNg4ODnRNqfP311y1uAqyIiAj++9//csMNN9ChQwe8vb3p0KEDN9xwAx999NEZJ1+o1Lt3b/773/9y+eWXExoaire3N+eddx533303//nPf1yevKQmr7zyCldeeSUxMTH4+fnh4+NDTEwMt99+O59++mm1EeAAy5Ytc5b0ONt6vyIiIu5u0qRJ3HDDDQQGBmI2mxkxYgQffPBBtTIAVc2aNYvnn3+epKQkAgIC8Pb2JjIykiuuuKLOfmpycrKzxEFZWRn333+/cwRqXar2Y2t6HBQUxB//+EeSkpIICwvD29sbk8lEz549+dOf/sQTTzxR5/ojIyN55ZVXuOGGG+jduzehoaF4eXkRGBhIUlISf//73/njH/9Y7TWPP/44Y8eOxWw2ExAQwFVXXcV//vOfGtfv7e3Nm2++yeOPP05CQgJmsxmj0Uh0dDTXX3+9s119+7uunHNcccUVXH311XTp0oWAgAA8PT0JDQ1l5MiRvP/++3Tq1Alwvb9bGy8vL+egkNWrV9eYvG5uXl5evPHGGzz00EN07doVHx8fZ/97/vz5XHTRRS6t55lnnuGGG26gW7duBAYGOvv848eP59NPPz1jObCGjHHPnj3s2LEDUF9VWgcPe0s7CxYRkTZj8+bNzs77G2+8wbBhw5o5orZt/PjxpKWlMXToUN58883mDkdERETEbWVlZTFq1CjKysp48sknuemmm5o7pFbv+eef5+233yYkJITly5c75yMRaak00lZERNxWYmKiM1FbdbSvNL2ffvrJOQHEmUqQiIiIiLR1ERERXHfddQC8++67Le6usZamqKiIjz76CIC7775bCVtpFTTSVkRERERERERERMSNaKStiIiIiIiIiIiIiBtR0lZERERERERERETEjShpKyIiIiIiIiIiIuJGlLQVERERERERERERcSNezR1AW2ez2SgvL8dgMODh4dHc4YiIiIi4Jbvdjs1mw8vLC4NB4w7ckfq1IiIiImfmar9WSdtmVl5eTlpaWnOHISIiItIixMfH4+Pj09xhSA3UrxURERFx3Zn6tUraNrPKjHp8fDyenp7N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c4clDcyVY7Q+dDzXz7luL7vdTmlpqY5RERGRJqSkrYiIiLR4BoOBLl26kJWVRWZmZq3tbDYbBoNuNHI3lfvFbDbTuXNn7aNWyNVjtD50PNdPQ2wvHaMiIiJNR0lbERERaRV8fHzo3Lkz5eXlVFRUnLbcbreTn59PQECARua5kcr9EhwcjLe3t/ZNK3amY7Q+dDzXT0NsL09PT7y8vLS9RUREmoiStiIiItJqeHh44O3tjbe392nL7HY7JSUlmEwmJR3cSOV+UcK2bajrGK0PHc/1o+0lIiLS8ui+FhERERERERERERE3oqStiIiIiIiIiIiIiBtR0lZERERERERERETEjShpKyIiIiIiIiIiIuJGlLQVERERERERERERcSNK2oqIiIiIiIiIiIi4ESVtRURERERERERERNyIkrYiIiIiIiIiIiIibkRJWxERERERERERERE3oqStiIiIiIiIiIiIiBtR0lZERERERERERETEjShpKyIiIiIiIiIiIuJGlLQVERERERERERERcSNK2oqIiIiIiIiIiIi4ESVtRURERERERERERNyIkrYiIiIiIiIiIiIibkRJWxERERERERERERE3oqStiIiIiIiIiIiIiBtR0lZERERERERERETEjShpKyIiIiIiIiIiIuJGlLQVERERERERERERcSNK2oqIiIiIiIiIiIi4ESVtG9DKlSsZM2YMo0eP5qOPPmrucEREREREzor6tSIiIiLNy6u5A2gtysvLmTVrFnPnzsXf359rrrmGkSNH0q5du+YOTURERETEZerXioiIiDQ/jbRtIKmpqXTr1o0OHTrg5+fH0KFDWb16dXOHJSIiIiJSL+rXioiIiDQ/tx9p+/rrr/PVV1+xe/duTCYT/fv3589//jNdu3ZtsPdYv349b7/9Nunp6WRnZzN79mxGjhx5Wrv333+ft99+m+zsbHr16sUTTzxBQkICAEePHqVDhw7Oth06dODIkSMNFqOISGOw2WxsTk1jyYpvKSi04u/ny9jhQ0lMiMdg0HU9EZGGpH6tiIjYbDbSUzezdvlSLMdzCGwXSvKIMcQlJKr/LSLVuP1vhHXr1nHzzTezYMEC5syZQ3l5OXfddRdFRUU1tv/pp58oKys77fmdO3dy7NixGl9TVFREz549efLJJ2uN48svv+TZZ59l0qRJLFy4kF69enHXXXeR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IiIiIq4yGAzEJyYSl5BAXl4eQUFBzonIRESq0mUcERERERERERERETeipK2IiIiIiIiIiIiIG1HSVkRERERERERERMSNKGkrIiIiIiIiIiIi4kaUtBURERERERERERFxI0raioiIiIiIiIiIiLgRJW1FRERERERERERE3IiStiIiIiIiIiIiIiJuRElbERERERERERERETeipK2IiIiIiIiIiIiIG1HSVkRERERERERERMSNKGkrIiIiIiIiIiIi4kaUtBURERERERERERFxI0raioiIiIiIiIiIiLgRJW1FRERERERERERE3IiStiIiIiIiIiIiIiJuRElbERERERERERERETeipK2IiIiIiIiIiIiIG1HSVkRERERERERERMSNKGkrIiIiIiIiIiIi4ka8mjsAaVtsNhubU9NYsuJbCgqt+Pv5Mnb4UBIT4jEYdA1BRERERESkpbDZbKSnbmbt8qVYjucQ2C6U5BFjiEtI1PmdiMg5UtJWmozFYmFmymxKTGFEdE8i3GSmpLiIuUvWY1z0JY9OnkRAQEBzhykiIiIiIiJnYLFYmJMyi97GMibERuIdHUWZzc6axfNYuegjJk6eQmBgYHOHKSLSYunSlzQJm83GzJTZmGOTiYlPxmgyA2A0mYmJT8Ycm8zMlNnYbLZmjlRERERERETqYrPZmJMyi+u7BDI6rit+JiMAfiYjo+O6cn2XQOakzNL5nYjIOVDSVprE5tQ0SkxhBIWE1bg8KCSMYmN70tLTmzgyERERERERqY/01M30NpYRERJU4/KIkCB6+ZSSkZbWxJGJiLQeStpKk1iy4lsiusfX2SayewKLl3/bRBGJiIiIiIjI2Vi3fCmDu0XV2WZwtyjWLl/SRBGJiLQ+StpKkygotDpLItTG6GumoNDaRBGJiIiIiIjI2SgpKnCWRKiNv6+JksL8JopIRKT1UdJWmoS/ny8lxUV1timxFuHv59tEEYmIiIiIiMjZMJr9KSwuqbNNgbUYo58mmhYROVtezR2AtA1jhw9l7pL1xMQn19omc0cqd1w2tAmjEpFKNpuNzalpLFnxLQWFVvz9fBk7fCiJCfEYDLq+JyIiIiInJY0Yw+rF8xgd17XWNqt3HiJ53K1NGJWIgOPcLj11M2uXL8VyPIfAdqEkjxhDXEKizu1aGO0taRKJCfEYi7PJy82ucXlebja+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wmop9bvfaimFylMGg14f5MiIiIiIiJpPbzThkDsCxRar3/3FFisOe+QYZgjcz4GIiIioo2DSthMTBAFLFy2A49g+FOTshdvpK5XgdjpQkLMXzuP78MQjCyAI/DUgIiIiIukSBAHpi5ZgQ4ENW83HUOl0AfCVRNhqPoYNBTakL1rCeS0RERF1GuGhDoDal1arxapli2HOzcWWbTtRYnciSqNC+ozxMOj1nNgSERERUYeg1WqxcNlK5JnNWL9tC2zny6HtHoPRM+ZissHAeS0RERF1KkzadgGCIMBkNMJkNIY6FCIiIiKiVhMEAQaTCXqjEVarFTqdDjKZLNRhEREREbU5fh1NREREREREREREJCFM2hIRERERERERERFJCJO2RERERERERERERBLCpC0RERERERERERGRhDBp28YWLFiAkSNH4uGHHw51KERERERErcZ5LREREVHoMGnbxu69914888wzoQ6DiIiIiOiKcF5LREREFDpM2rax1NRUaDSaUIdBRERERHRFOK8lIiIiCh1JJG3XrVuHm2++GSNGjMCIESNw5513YufOnW16HwcOHMBDDz2E66+/HikpKdi2bZvfce+88w7S0tJgMBhwxx13ICcnp03jICIiIqLOi/NaIiIiImoL4aEOAAB69eqFxx57DP369YPX68WmTZuwYMECfPjhh0hOTm40/rvvvoPRaERERESD7UePHkW3bt3Qo0ePRtdxOBxISUnBrFmz8Lvf/c5vHJs3b8bq1auxfPlymEwmvPnmm7jvvvuQlZWFmJgYAMDMmTNRU1PT6LqvvfYaevbs2ZqHT0RERESdBOe1RERERNQWJJG0TUtLa3D5kUcewbvvvouDBw82mtyKoogVK1agX79+eO655xAWFgYAOH78OObNm4f58+fjgQceaHQf48ePx/jx4wPGkZmZidmzZ2PWrFkAgOXLl+Orr77C+++/jwcffBAA8NFHH7X6cRIRERFR58Z5LRERERG1BUmUR6ivpqYGn332GRwOB66++upG+wVBwCuvvIJDhw7h8ccfhyiKOHXqFObNm4eJEyf6ndg2h8fjQV5eHsaMGdPgvsaMGYMffvih1Y+HiIiIiLomzmuJiIiIqLUksdIWAI4cOYJf/epXcLvdUKvVWLt2LQYNGuR3bM+ePfHmm2/i7rvvxqOPPoqDBw9izJgxWL58eavv//z586ipqak7XaxWTEwMjh8/3uzbmT9/Pg4fPgyn04lx48bh+eef9ztJr+X1egHA76lpXZHX64UoiqipqYFMJgt1OPQzPi/SxOdFuvjcSBOfF2lq7vNSO1eqnTtJGee17T+v5d9zy/B4tRyPWcvweLUcj1nL8Hi1HI9ZywTzeDV3XiuZpO2AAQOwadMmVFRUYOvWrVi8eDH+/e9/NznBTUhIwF//+lfcc8896NOnD55++mlJ/BK+8cYbLRoviiIAwGw2t0M0RERERJ1L7dxJyjiv5byWiIiI6HIuN6+VTNJWLpejX79+AAC9Xg+z2Yy33noLK1as8Du+rKwMTz31FCZMmIDc3FysXr0aTz31VKvvv3v37ggLC0N5eXmD7eXl5X4bQLSV8PBwGAwGCIIgick5ERERkRTVrn4ID5fM9LVJnNdyXktERETUlObOayU76xVFER6Px+8+i8WC+fPnIykpCc8//zxOnDiBuXPnQi6XY/Hixa26P7lcjmHDhuGbb77BpEmT6mL45ptvcM8997T6cVyOIAiQy+XtdvtEREREFFqc1xIRERFRS0kiafvss89i3LhxiI+Ph91ux6effor9+/fjtddeazRWFEU88MADSEhIwHPPPYfw8HAMGjQImZmZmDdvHnr27In58+c3up7dbsepU6fqLp85cwaHDh2CTqdDQkICACA9PR2LFy+GXq+H0WjEm2++CafTiV/+8pft9tiJiIiIqPPgvJaIiIiI2oLMK4FuDkuXLsXevXtRUlKCqKgopKSk4IEHHsDYsWP9jt+9ezeuvfZaKBSKBtt//PFHREdHo1evXo2us2/fPtx7772Ntt92221Ys2ZN3eV///vfeO2111BaWoohQ4bgySefhMlkusJHSERERERdAee1RERERNQWJJG0JSIiIiIiIiIiIiIfIdQBEBEREREREREREdFFTNoSERERERERERERSQiTtkREREREREREREQSwqQtERERERERERERkYQwaUtBc+DAATz00EO4/vrrkZKSgm3btgUc//nnnyM9PR2jR4/GiBEjcOedd+Lrr78OUrRdS0ufm2+//Ra/+tWvkJqaCqPRiGnTpuGNN94ITrBdSEufl/q+++47DB06FDNnzmzHCLumlj4v+/btQ0pKSqOfhm7CNAAAHp9JREFU0tLSIEXcdbTmb8bj8eC5557DhAkToNfrkZaWhvfeey8I0XYdLX1elixZ4vdvZsaMGUGKmKTunXfeQVpaGgwGA+644w7k5OSEOiTJupK5RFf0z3/+E7NmzcLVV1+N6667Dr/97W9x/PjxUIclaevWrcPNN9+MESNG1H1m27lzZ6jD6jBeeeUVpKSk4Omnnw51KJL14osvNpoTTJs2LdRhSdq5c+fw2GOP1X1ev/nmm2E2m0MdlmSlpaX5nXsuX7481KEhPNQBUNfhcDiQkpKCWbNm4Xe/+91lxx84cABjxozBI488Aq1Wiw8++AC/+c1vsGHDBgwdOjQIEXcdLX1u1Go17rnnHqSkpEClUuG7777Dn//8Z6hUKtx5551BiLhraOnzUstms2Hx4sW47rrrUFZW1o4Rdk2tfV6ysrIQGRlZdzkmJqY9wuvSWvPc/P73v0d5eTmefvpp9O3bF6WlpRBFsZ0j7Vpa+rz86U9/wqOPPlp3uaamBjNnzuQHNAIAbN68GatXr8by5cthMpnw5ptv4r777kNWVhZfV/1o7XtWV7V//37cfffdMBgMqKmpQUZGBu677z589tlnUKvVoQ5Pknr16oXHHnsM/fr1g9frxaZNm7BgwQJ8+OGHSE5ODnV4kpaTk4P169cjJSUl1KFIXnJyMjIzM+suh4WFhTAaabNarZgzZw5SU1Pxr3/9C927d8fJkyeh0+lCHZpkvffee6ipqam7nJ+fj/T0dEnMPZm0paAZP348xo8f3+zxf/rTnxpcXrRoEbZv344dO3YwadvGWvrcDB06tMFz0Lt3b3zxxRf49ttvmbRtQy19Xmr9+c9/xk033YSwsDCuqGkHrX1eYmJioNVq2yEiqtXS52bXrl04cOAAtm3bhm7dugHwvZ5R22rp8xIVFYWoqKi6y9u2bYPVasUvf/nL9giPOpjMzEzMnj0bs2bNAgAsX74cX331Fd5//308+OCDIY5Oelr7ntVVvfbaaw0ur1mzBtdddx3y8vIwcuTIEEUlbWlpaQ0uP/LII3j33Xdx8OBBJm0DsNvt+OMf/4iVK1fiH//4R6jDkbywsDDExsaGOowO4V//+hd69eqF1atX123r06dPCCOSvujo6AaXX3nlFfTt2xejRo0KUUQXsTwCdRiiKMJut9d9sCbp+PHHH/HDDz9I4kWtq3v//fdx+vRprqaRoFtvvRXXX3890tPT8d1334U6HAKwY8cO6PV6vPrqq/jFL36BqVOn4plnnoHL5Qp1aFTPe++9hzFjxiAxMTHUoVCIeTwe5OXlYcyYMXXbBEHAmDFj8MMPP4QwMuqsKioqAIAr1JqppqYGn332GRwOB66++upQhyNpK1aswPjx4xu8nlHTTp48ieuvvx4TJ07Eo48+iqKiolCHJFm189uHH34Y1113HW699VZs2LAh1GF1GB6PBx9//DFmzZoFmUwW6nC40pY6jtdeew0OhwPTp08PdSj0s3HjxsFisaCmpga/+93vcMcdd4Q6pC7txIkTePbZZ/HOO+8gPJwv71IRGxuL5cuXQ6/Xw+PxYOPGjbj33nuxYcMGDBs2LNThdWmnT5/Gd999B4VCgbVr1+L8+fNYvnw5Lly40GB1AoXOuXPnsGvXLvz9738PdSgkAefPn0dNTU2jMggxMTGsO0ptThRFrFq1CiNGjMBVV10V6nAk7ciRI/jVr34Ft9sNtVqNtWvXYtCgQaEOS7I+++wz/Pjjj6yh30xGoxGrV6/GgAEDUFpairVr1+Luu+/GJ5980qD0GPmcPn0a7777LtLT0/HQQw/BbDZj5cqViIiIwG233Rbq8CRv27ZtqKiokMyx4qd66hA++eQTrF27Fi+//DLrlUnIO++8A4fDgezsbDz77LPo168fbrrpplCH1SXV1NTg0UcfxcKFCzFgwIBQh0P1DBw4EAMHDqy7PGLECJw+fRpvvPEG/va3v4UwMvJ6vZDJZPj73/9edzr+kiVL8PDDD+PPf/4zlEpliCOkTZs2ISoqCpMmTQp1KETUxSxfvhz5+flYt25dqEORvAEDBmDTpk2oqKjA1q1bsXjxYvz73/9m4taP4uJiPP3003j99dehUChCHU6HUL/Ey+DBg2EymTBhwgRs2bKFi4b88Hq90Ov1WLRoEQBfacP8/HysX79eMolIKXv//fcxbtw49OzZM9ShAGDSljqAzz77DE8++SSef/55nj4iMbW1cVJSUlBWVoYXX3yRSdsQsdvtyM3NxaFDh/CXv/wFgG+FiNfrxdChQ/Haa6/huuuuC3GUVMtgMOD7778PdRhdXmxsLHr27NmgfmpSUhK8Xi/Onj2L/v37hy44gtfrxfvvv4+ZM2dCLpeHOhySgO7duyMsLAzl5eUNtpeXl6NHjx4hioo6oxUrVuCrr77Cv//9b/Tq1SvU4UieXC5Hv379AAB6vR5msxlvvfUWVqxYEeLIpCcvLw/l5eUN6rTX1NTgwIEDeOedd2A2m9lk6zK0Wi369++PU6dOhToUSYqNjUVSUlKDbQMHDsTWrVtDFFHHUVhYiD179uDFF18MdSh1mLQlSfv000+xdOlSZGRk4IYbbgh1OBSAKIqoqqoKdRhdVmRkJD755JMG29atW4e9e/fihRdeYHMliTl8+DCbKUjAiBEjkJWVBbvdDo1GAwAoKCiAIAj8kC4B+/fvx8mTJ3H77beHOhSSCLlcjmHDhuGbb76pW30tiiK++eYb3HPPPSGOjjoDr9eLv/zlL/jiiy/w9ttvs3lPK4miCI/HE+owJGn06NGN5uxPPPEEBg4ciAceeIAJ22aw2+04ffo059JNGDFiBAoKChpsO3HiBHsDNMMHH3yAmJgYSeWemLSloLHb7Q2+DTtz5gwOHToEnU6HhIQEPPvsszh37hz++te/AvCVRFiyZAmWLl0Kk8mE0tJSAIBSqWywKoquXEufm3feeQfx8fF1p3wfOHAAr7/+OubOnRuS+DurljwvgiA0qrcWExMDhULBOmxtrKV/L2+88QZ69+6N5ORkuN1ubNy4EXv37sXrr78eqofQabX0ubnpppvw8ssv44knnsDDDz+M8+fP429/+xtmzZrF0ghtqKXPS6333nsPJpOJr2HUQHp6OhYvXgy9Xg+j0Yg333wTTqezwao1uuhyf3/U0PLly/Hpp5/i5Zdfhkajqfv8ERUVxfeFJjz77LMYN24c4uPjYbfb8emnn2L//v147bXXQh2aJEVGRjZ6X1Or1ejWrRvf75rwzDPPYMKECUhISEBJSQlefPFFCILAMzybMG/ePMyZMwf/93//h+nTpyMnJwcbNmzgyvfLEEURH3zwAW699VZJ9YeRTiTU6eXm5uLee++tu1zb5OW2227DmjVrUFpaiuLi4rr9GzZsQHV1NVasWNHgBaZ2PLWdlj43oigiIyMDZ86cQVhYGPr27YvHHnsMv/rVr4Iee2fW0ueFgqOlz0tVVRWeeeYZnDt3DiqVCldddRUyMzMxevTooMfe2bX0udFoNHj99dexcuVKzJo1C926dcP06dPxhz/8Idihd2qteS2rqKjA559/jj/96U9BjZWk78Ybb4TFYsELL7yA0tJSDBkyBK+++irLIzThcn9/1NC7774LAI0WIqxevZpfDDShvLwcixcvRklJCaKiopCSkoLXXnsNY8eODXVo1EmcPXsWixYtwoULFxAdHY1rrrkGGzZsQHR0dKhDkySj0YiXXnoJGRkZWLt2LXr37o2lS5filltuCXVokrZnzx4UFRVh1qxZoQ6lAZnX6/WGOggiIiIiIiIiIiIi8hFCHQARERERERERERERXcSkLREREREREREREZGEMGlLREREREREREREJCFM2hIRERERERERERFJCJO2RERERERERERERBLCpC0RERERERERERGRhDBpS0RERERERERERCQhTNoSERERERERERERSQiTtkRE7SglJeWyPx988EHA2/jggw+QkpICi8XSLjG++OKL+P7775s1tri4GE888QTS0tJgMBhw/fXXY/78+fjoo4/aJTYiIiIiKXrxxReRkpKCu+++u9G+p59+GmlpaUGNZ+7cufj1r38d1PtsCY/HgyeeeAKjR49GSkoK3njjDb/jao9r7Y/BYMD06dPxr3/9C6IoBjdoPz755BNMmTIFw4YNw8yZM3HmzBmkpKQgKyur2bfR2rl9c57jS49f/Z9XXnmlRffXlt544w3s3LkzZPdP1FGFhzoAIqLO7D//+U+Dy3feeSfmzp2Lm266qW5b3759gx1WAy+99BLUajVGjBgRcJzNZsPs2bOh0+mwcOFCJCQk4OzZs9i7dy++/vprzJw5M0gRExEREUnDt99+i3379iE1NTXUoUjaRx99hI8++ghr1qxB3759kZiY2ORYpVKJN998EwDgcrmwb98+PPvss/B6vXjwwQeDFXIjdrsdS5cuxU033YTVq1cjMjIScXFx+M9//oP+/fs3+3ZuuOEG/Oc//4FWq22XOOsfv/ri4+Pb5f6a46233sINN9yA8ePHhywGoo6ISVsionY0fPjwRtvi4+P9bpe6rVu3oqSkBP/5z3+QkJBQt33mzJlBW/ngcrmgVCqDcl9EREREgajVagwaNAgvv/xyp0/aXukc7Pjx44iLi8Mtt9xy2bGCIDSYK48ePRo//fQTPv/885AmbQsLC+HxeHDLLbfgmmuuqdve0nl9dHQ0oqOj2zi6iy49fkTUcbE8AhFRCH311VdIT0/HddddhxEjRuCOO+7Arl27Lns9j8eDjIwMTJgwAXq9HtOnT8cnn3zSYMySJUtw0003Yd++fbj11lsxfPhw3H777cjNza0bk5KSAgD461//Wnfq1L59+/zep9VqhSAIiImJabRPEBq+nZw7dw6PP/44xowZA6PRiGnTpjX4xl8URbz88stIS0uDXq/H/2/vzoOqKv84jr9BQAkQARdMzcFE7RISS6moGOKWuDSOuYVGIiQukIpbqYUrkzpjAu5mGrZppibuWmoatqgxY9popiZqIoppSoNefn8w9+SVq4BSOv0+rxlmuOee85xznntn+PI9z/N9OnXqxMcff2zVRmpqKoGBgWRnZ9O7d2/8/f1ZuXIlAL/88gvx8fEEBwfzzDPPEBcXx+nTp0vtNxEREZGKNGTIELKysu5Zaupu0+G7d+/OuHHjjNeW2G3fvn107dqVpk2bEhUVxZkzZ8jPzycxMZGgoCDatWvHxo0bbZ5r7dq1tGvXjqZNm9K/f39OnDhh9X5RURFLly6lY8eOPP3000RERJQoVXCvGMyWnJwcEhISjLgsJiaGn3/+2Xi/bdu2vPfee5w7d86IN8+cOXPX9mxxcXHh5s2bVtsqKh4uS7+kpqbStWtXAKKjo2ncuDGpqal3LY+wdu1aXnzxRfz9/WnWrBmxsbHk5OQAtr8Ps2bNomvXrgQGBtK6dWtGjhzJhQsXytVHZXW3MgsZGRk0bdqUq1evAuX7rvz888/07duXgIAAunTpwp49e4x92rZtS05ODitXrixRHm7Hjh306NGDwMBAQkJC6NGjh8ooiNxGI21FRB6iM2fOEB4ezsCBA7G3t2f37t3ExcWxfPnye47YSExM5MCBAwwdOpQnn3ySXbt2MXr0aKpWrWo17Sg3N5epU6cSFxeHm5sbs2fPZtiwYWzbtg1HR0c++eSTEiUbGjZsaPOcfn5+mM1mkpKSGDhwIP7+/jg4lPwzcvnyZXr37g3AiBEjqFu3LqdOnbJKqr7zzjusWLGC+Ph4AgMD+eqrr3jrrbe4efMmUVFRxn6FhYWMGjWK6OhoRowYQbVq1fjtt9/o06cPvr6+pKSkYGdnx4IFC4iOjmbz5s04OTmV70MQERERuU/h4eGYTCbS09NZunTpA7eXm5tLSkoK8fHxODg4MHXqVJKSknB2diYkJIRevXrx6aefMnr0aAICAqzKDBw+fJjTp08zatQoAObMmcOgQYOs4qNp06axatUqBg8eTEBAAAcOHGDWrFlUrlyZvn37Gm3ZisFsuXbtGv3798fe3p7k5GQqV67M/PnziYqKYv369dSuXZu0tDQWL17Md999R1paGgA1a9a8Zz9YErSW8ghbt24tkWisqHi4LP3y0ksvUa9ePcaOHcukSZPw8/PD29u7RCIZYMmSJcycOZOePXsyYsQICgsLycrK4tKlS3ctC5GXl8drr71GzZo1uXTpEsuWLaN///5kZmbajLdLY+u6LO1ERkYydepU8vPzrT7XDRs20KZNG9zc3MrUJxaFhYUkJSUxYMAAhgwZwuLFi0lISGDnzp14eHiQlpZGXFwcQUFBDBw4ECguD3f69GkSExOJjIxk1KhRmM1mjh49ypUrV8p9vyL/VUraiog8RLcnKM1mM82aNeP48eN8+umnd03aZmVlsXPnTpYuXUqrVq0AaNmyJbm5uaSmploFqVeuXCEjIwNfX18AnJ2dGTBgAD/++CMhISHG1KmylGxo0aIFMTExLFu2jK1bt1KlShWCg4Pp1q0b3bt3x87ODiheaCAvL49NmzZRt25d41iLS5cukZGRQUxMDMOHDwegVatWXL58mfT0dPr27UulSpWA4iBwxIgRdO7c2Th+7NixuLu7s2zZMipXrgxAUFAQERERrFq1yuaCICIiIiL/lPj4eIYPH052djZNmzZ9oLbujN0uXLjAlClTiI2NZejQoQD4+/uzbds2tm/fziuvvGIcm5eXR0ZGhlFf1WQy0alTJ9asWUOfPn04ffo0GRkZJCcnGw/YQ0NDKSgoID09nd69exuzp2zFYLasWbOGs2fPkpmZyZNPPgnAs88+S3h4OMuXL2fcuHGYTCaqV6+Ok5NTmabtX79+HT8/P6ttnTt3tiqNUJHxcFn6xdvb25ih1rBhQ+M+7hwxfPXqVdLS0ujduzeTJ082trdr1+6e9zxjxgzj91u3bhEYGEhYWBhZWVnG/ZWVrf4DWLlyJSEhIXTs2JGpU6eydetWevXqBRSPlj506BBz5swBKPd3JSkpyehzHx8fIiIi2L17N927d8dkMuHk5ET16tWtPv9vv/2WwsJCJk6ciKurKwCtW7cu172K/NepPIKIyEN0/vx5xo4dS+vWrTGZTPj5+fH111/z66+/3vWYvXv3Uq1aNZo3b87NmzeNn9DQUI4cOcKtW7eMfWvWrGkEqPD3KNrff//9vq53zJgxbN26lfHjxxMWFkZ2djZjx45lzJgxxj7ffPMNzZs3NxK2d8rOzqawsJBOnTpZbX/hhRe4dOkSJ0+etNp+54IFe/fupW3btlSqVMm496pVq2IymUpMdRMRERH5p7Vv355GjRqRnp7+wG3dGbtZErChoaHGtqpVq+Lp6cn58+etjvX19bVaEKt+/fo0adKEH3/8EYB9+/YB0KFDhxIxZG5uLufOnbNqryyLRn3//ff4+voaCVuAatWqERoayg8//FC2m75DlSpVWL16NatXr+bDDz/kzTffZM+ePUyYMMHYpyLj4fL2y70cPHiQGzdu0LNnz3Ld865du+jTpw/BwcGYTCbCwsIASsTFZXF7/93+89RTTwHg4eFBaGgomZmZxjEbN27kscceIzw8HChfn9jb21sN0Khbty5VqlQp9f+Nxo0bU6lSJZKSkti5c6dRlkFE/qaRtiIiD4nZbCY+Pp6rV6+SkJBA/fr1cXZ2Zu7cufcMDi9fvkx+fr7NJ+hQPAXM29sboMSqtJYpYH/99dd9X3e9evWIjo4mOjqaP//8k8TERNavX09MTAxNmjQhPz/fKjC+k2XKU/Xq1a22W17n5+cb25ydnXFxcbHa7/LlyyxfvtzmqriW+xMRERH5t9jZ2TF48GBGjhzJ4cOHH6itu8VulinrFk5OTiXiOVvrDnh5eZGbmwsUx1BFRUU0b97c5rnPnTtnTN+3FYPZ8scff5SI6SznPXbsWKnH22Jvb4+/v7/xOjg4mFu3bpGSksKrr75Ko0aNKjQeLk+/lMYSx5ZW/uF22dnZDBkyhIiICGJjY/Hy8sLOzo5evXrdV8x+Z//ZEhkZybhx48jNzaVGjRpkZmbSvn17YxZbefqkSpUqJcqTOTo6lnrtPj4+LFiwgIULFzJs2DDs7e1p1aoVkyZNslr0WOT/mZK2IiIPyalTp/jpp59IT0+3mjJVUFBwz+Pc3d3x9PRk0aJFNt//J1ejvZOLiwv9+vVjz549nDhxgiZNmlCtWrV7LpxgqZ2Vl5dHrVq1jO0XL160eh8wSi7czt3dnTZt2tCvXz+b1yMiIiLyb3vhhRdITU1l3rx5JRJOlkRYYWGh1fY//vijQq8hLy/P5rYmTZoAxTGUnZ0dH374oc0H3T4+PsbvtmIwW9zd3W3OEMvLy8Pd3b2sl16qBg0aAHD8+HEaNWpUofFwefqlNJY49sKFC0bSuDTbt2/H1dWVOXPmGCUHLIuW/VMiIiJwcnJi06ZNtGrViiNHjjBy5Ejj/Yrsk3sJCwsjLCyMa9eusXv3bmbMmMH48eNtDs4Q+X+kpK2IyENiefp8eyCUk5PDwYMHraa23Sk0NJQlS5bg6OhoBOEPoixPwqG4Fq2Hh0eJIN4ybcsyyqJFixa89957nD171uZTcn9/fxwdHdm8eTMmk8nYvmnTJry8vO5575b2jx07hslkMmrfioiIiDxM9vb2DB48mHHjxvHcc89ZvWd5SH3ixAnj919++aVc0+7L4tixY5w6dYr69esDxQMEjh49atQktUxhz8/Pp23bthVyzuDgYLZs2cKJEyeMxOqVK1fYt2+fcd6KYBm16+HhAVRsPFyR/RIYGIizszOfffZZmesbFxQU4OjoaBVjf/HFFw90HaVxdXXl+eefJzMzkytXruDp6WlVgqOivyul/b/h6upK586dyc7OZsOGDQ98PpH/CiVtRUQekgYNGuDt7c3s2bMxm81cv36duXPnljqdqmXLloSHhzNo0CAGDRpE48aNuXHjBsePH+fUqVNMmzat3NexY8cOQkJCcHZ2xsfHx1gM4Haff/4569atMxYUMJvNHDx4kMWLF+Pn50dwcDAA0dHRrFu3jqioKOLj46lXrx6//fYbJ0+eZPTo0Xh6ehIVFcXSpUuNBSl27drFhg0bmDhxYqmJ2ISEBHr27ElMTAy9evWievXqXLx4kW+//ZaQkBC6dOlSrvsXERERqQhdu3YlPT2d/fv3W02nDwgIoHbt2kyfPp1Ro0Zx7do1Fi1aZDW7qCJ4eXkxePBgEhISAHj33XepVasWPXr0AIpHR7788suMGTOGmJgYAgICKCws5OTJk+zfv5958+aV+5w9evTg/fff57XXXuP111+ncuXKzJ8/HwcHB6tF0srDbDZz6NAhoHh08uHDh5k/fz4NGzYkJCQEqNh4uCL7xc3NjaFDhzJr1iyKioqIiIjAbDazf/9+IiMjbZYtaNmyJcuXL2fKlCm0b9+egwcPsm7dujKf806399/tvLy8qFevnvG6S5cuDBs2jJycHDp16oSDw9/poYr+rjRo0ICsrCz27t1L1apVqVu3Llu2bOHQoUO0bt2aGjVqcObMGdavX0/Lli3v+95F/muUtBUReUicnJxITU1l8uTJJCYmUrt2beLj48nKyip1Qa25c+eyaNEiPvroI3JycnBzc8PX19cIystj0qRJTJ8+ndjYWAoKClixYgXNmjUrsV+bNm04e/Ysa9euZd68eZjNZh5//HEGDhzIq6++aiRbPTw8+Oijj5g9ezazZs3ixo0b1KlTx6qcwZgxY3Bzc2P16tUsWLCAOnXqkJycTJ8+fUq93vr167Nq1SrmzJlDcnIy169fp0aNGjz77LPGqr4iIiIi/7ZKlSoRFxdntWAWFI8yTEtL4+233yYxMZEnnniCN954g5SUlAo9v5+fHx06dGDmzJnk5uYSEBBAcnKyVb3RCRMm4OPjwyeffEJ6ejouLi74+PiUWCC2rFxdXfnggw9ISUlh4sSJmM1mgoKCyMjIoHbt2vfVZkFBgTFK18HBAW9vb7p168awYcOsZqhVZDxckf0SGxuLp6cn77//PmvWrMHFxYXAwECbNYehOMZOSkoiIyODNWvWEBQUxMKFC+nYsWO5zw3W/Xe7nj17WiWz27Rpg5ubG7m5uURGRpbYvyL7ZOTIkbz99tsMHz6cP//8kxkzZtC4cWO+/PJLZsyYQX5+PjVq1CAyMpLExMRyty/yX2VXVFRU9LAvQkRERERERERERESK2T/sCxARERERERERERGRvylpKyIiIiIiIiIiIvIIUdJWRERERERERERE5BGipK2IiIiIiIiIiIjII0RJWxEREREREREREZFHiJK2IiIiIiIiIiIiIo8QJW1FREREREREREREHiFK2oqIiIiIiIiIiIg8QpS0FREREREREREREXmEKGkrIiIiIiIiIiIi8ghR0lZERERERERERETkEaKkrYiIiIiIiIiIiMgj5H/v2T6vBfiwDAAAAABJRU5ErkJggg==", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "Visualization Insights:\n", - "The left panel shows weak correlation between talent and outcomes.\n", - "The right panel shows strong correlation between beneficial events and outcomes.\n", - "Note the logarithmic vertical scale indicating multiplicative effects.\n" - ] - } - ], - "source": [ - "log_capital = np.log(df_results[\"capital\"])\n", - "\n", - "corr_talent = df_results[\"talent_norm\"].corr(log_capital)\n", - "corr_luck = df_results[\"lucky_events\"].corr(log_capital)\n", - "corr_net = df_results[\"net_events\"].corr(log_capital)\n", - "corr_intensity = df_results[\"talent_intensity\"].corr(log_capital)\n", - "corr_iq = df_results[\"talent_iq\"].corr(log_capital)\n", - "corr_network = df_results[\"talent_networking\"].corr(log_capital)\n", - "\n", - "print(\"Correlation Analysis with Log(Capital)\")\n", - "print(\"=\" * 70)\n", - "print(\"\\nTalent Measures:\")\n", - "print(f\" Overall talent (norm): {corr_talent:.4f}\")\n", - "print(f\" Intensity dimension: {corr_intensity:.4f}\")\n", - "print(f\" IQ dimension: {corr_iq:.4f}\")\n", - "print(f\" Networking dimension: {corr_network:.4f}\")\n", - "\n", - "print(\"\\nLuck Measures:\")\n", - "print(f\" Beneficial events: {corr_luck:.4f}\")\n", - "print(f\" Net events (lucky-unlucky): {corr_net:.4f}\")\n", - "\n", - "print(\"\\nComparative Analysis:\")\n", - "print(\n", - " f\" Luck correlation / Talent correlation = {corr_luck / corr_talent:.2f}x\"\n", - ")\n", - "print(\n", - " f\"\\nKey Finding: Beneficial events are {corr_luck / corr_talent:.1f} times more correlated\"\n", - ")\n", - "print(\"with success than overall talent. This quantifies the dominance of\")\n", - "print(\"stochastic factors over ability in determining outcomes.\")\n", - "\n", - "fig, axes = plt.subplots(1, 2, figsize=(14, 5))\n", - "\n", - "# Panel 1: Talent vs Success\n", - "axes[0].scatter(\n", - " df_results[\"talent_norm\"],\n", - " df_results[\"capital\"],\n", - " alpha=0.6,\n", - " s=50,\n", - " c=\"steelblue\",\n", - " edgecolor=\"black\",\n", - " linewidth=0.5,\n", - ")\n", - "z = np.polyfit(df_results[\"talent_norm\"], df_results[\"capital\"], 1)\n", - "p = np.poly1d(z)\n", - "axes[0].plot(\n", - " df_results[\"talent_norm\"].sort_values(),\n", - " p(df_results[\"talent_norm\"].sort_values()),\n", - " \"r--\",\n", - " alpha=0.8,\n", - " linewidth=2,\n", - " label=\"Linear Fit\",\n", - ")\n", - "axes[0].set_xlabel(\"Talent Score\", fontsize=11)\n", - "axes[0].set_ylabel(\"Final Capital ($)\", fontsize=11)\n", - "axes[0].set_title(\n", - " f\"Talent vs Success (r = {corr_talent:.3f})\", fontsize=12, fontweight=\"bold\"\n", - ")\n", - "axes[0].set_yscale(\"log\")\n", - "axes[0].grid(True, alpha=0.3)\n", - "axes[0].legend(fontsize=10)\n", - "\n", - "# Panel 2: Luck vs Success\n", - "axes[1].scatter(\n", - " df_results[\"lucky_events\"],\n", - " df_results[\"capital\"],\n", - " alpha=0.6,\n", - " s=50,\n", - " c=\"coral\",\n", - " edgecolor=\"black\",\n", - " linewidth=0.5,\n", - ")\n", - "z = np.polyfit(df_results[\"lucky_events\"], df_results[\"capital\"], 1)\n", - "p = np.poly1d(z)\n", - "axes[1].plot(\n", - " df_results[\"lucky_events\"].sort_values(),\n", - " p(df_results[\"lucky_events\"].sort_values()),\n", - " \"r--\",\n", - " alpha=0.8,\n", - " linewidth=2,\n", - " label=\"Linear Fit\",\n", - ")\n", - "axes[1].set_xlabel(\"Number of Beneficial Events\", fontsize=11)\n", - "axes[1].set_ylabel(\"Final Capital ($)\", fontsize=11)\n", - "axes[1].set_title(\n", - " f\"Luck vs Success (r = {corr_luck:.3f})\", fontsize=12, fontweight=\"bold\"\n", - ")\n", - "axes[1].set_yscale(\"log\")\n", - "axes[1].grid(True, alpha=0.3)\n", - "axes[1].legend(fontsize=10)\n", - "\n", - "plt.tight_layout()\n", - "plt.show()\n", - "\n", - "print(\"\\nVisualization Insights:\")\n", - "print(\"The left panel shows weak correlation between talent and outcomes.\")\n", - "print(\n", - " \"The right panel shows strong correlation between beneficial events and outcomes.\"\n", - ")\n", - "print(\"Note the logarithmic vertical scale indicating multiplicative effects.\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Section 8: Top Performers Characterization\n", - "\n", - "We now examine the highest-achieving agents to test whether they possess exceptional talent or simply experienced favorable event sequences. If success were purely meritocratic, we would expect top performers to rank highly in talent. If randomness dominates, top performers should have average talent but above-average beneficial event counts." - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Top Performers Analysis\n", - "================================================================================\n", - "\n", - "Top 10 Agents by Final Capital:\n", - " id capital talent_norm talent_rank lucky_events unlucky_events net_events\n", - " 6 2.573136 1.365554 33.0 6 1 5\n", - " 51 1.986911 1.417705 18.0 4 1 3\n", - " 26 1.929791 1.371717 31.0 4 1 3\n", - " 76 1.618122 1.194075 94.0 3 0 3\n", - " 39 1.549727 1.420095 17.0 6 3 3\n", - " 52 1.411704 1.367399 32.0 5 4 1\n", - " 8 1.405200 1.313800 56.0 2 1 1\n", - " 66 1.321949 1.333611 51.0 3 1 2\n", - " 64 1.299675 1.350784 39.0 4 3 1\n", - " 24 1.261673 1.316457 55.0 3 3 0\n", - "\n", - "Aggregate Statistics for Top 10:\n", - " Average talent rank: 42.6 out of 100\n", - " Median talent rank: 36.0 out of 100\n", - " Average beneficial events: 4.00\n", - " Average detrimental events: 1.80\n", - " Average net events: 2.20\n", - "\n", - "Comparison to Population:\n", - " Population average talent rank: 50.5\n", - " Population average beneficial events: 2.32\n", - " Population average net events: -1.68\n", - "\n", - "Interpretation:\n", - " Top performers have BELOW AVERAGE talent (rank 43/100)\n", - " However, they experienced 4.0 beneficial events\n", - " versus population average of 2.3\n", - "\n", - " This demonstrates success is more strongly determined by fortunate\n", - " circumstances than by exceptional ability.\n", - "\n", - "Mann-Whitney U test (top 10 vs others for beneficial events):\n", - " U-statistic: 742.50\n", - " p-value: 0.000312\n", - " Result: Highly significant difference (p < 0.001)\n", - " Conclusion: Top performers experienced significantly more beneficial events.\n" - ] - } - ], - "source": [ - "df_results[\"talent_rank\"] = df_results[\"talent_norm\"].rank(ascending=False)\n", - "df_results[\"capital_rank\"] = df_results[\"capital\"].rank(ascending=False)\n", - "\n", - "top_10 = df_results.nlargest(10, \"capital\").copy()\n", - "top_20 = df_results.nlargest(20, \"capital\").copy()\n", - "\n", - "print(\"Top Performers Analysis\")\n", - "print(\"=\" * 80)\n", - "print(\"\\nTop 10 Agents by Final Capital:\")\n", - "display_cols = [\n", - " \"id\",\n", - " \"capital\",\n", - " \"talent_norm\",\n", - " \"talent_rank\",\n", - " \"lucky_events\",\n", - " \"unlucky_events\",\n", - " \"net_events\",\n", - "]\n", - "print(top_10[display_cols].to_string(index=False))\n", - "\n", - "print(\"\\nAggregate Statistics for Top 10:\")\n", - "print(f\" Average talent rank: {top_10['talent_rank'].mean():.1f} out of 100\")\n", - "print(f\" Median talent rank: {top_10['talent_rank'].median():.1f} out of 100\")\n", - "print(f\" Average beneficial events: {top_10['lucky_events'].mean():.2f}\")\n", - "print(f\" Average detrimental events: {top_10['unlucky_events'].mean():.2f}\")\n", - "print(f\" Average net events: {top_10['net_events'].mean():.2f}\")\n", - "\n", - "print(\"\\nComparison to Population:\")\n", - "print(\n", - " f\" Population average talent rank: {df_results['talent_rank'].mean():.1f}\"\n", - ")\n", - "print(\n", - " f\" Population average beneficial events: {df_results['lucky_events'].mean():.2f}\"\n", - ")\n", - "print(f\" Population average net events: {df_results['net_events'].mean():.2f}\")\n", - "\n", - "print(\"\\nInterpretation:\")\n", - "avg_talent_rank = top_10[\"talent_rank\"].mean()\n", - "if avg_talent_rank > 40:\n", - " print(\n", - " f\" Top performers have BELOW AVERAGE talent (rank {avg_talent_rank:.0f}/100)\"\n", - " )\n", - "elif avg_talent_rank > 25:\n", - " print(\n", - " f\" Top performers have AVERAGE talent (rank {avg_talent_rank:.0f}/100)\"\n", - " )\n", - "else:\n", - " print(\n", - " f\" Top performers have ABOVE AVERAGE talent (rank {avg_talent_rank:.0f}/100)\"\n", - " )\n", - "\n", - "print(\n", - " f\" However, they experienced {top_10['lucky_events'].mean():.1f} beneficial events\"\n", - ")\n", - "print(f\" versus population average of {df_results['lucky_events'].mean():.1f}\")\n", - "print(\"\\n This demonstrates success is more strongly determined by fortunate\")\n", - "print(\" circumstances than by exceptional ability.\")\n", - "\n", - "# Statistical test\n", - "from scipy.stats import mannwhitneyu\n", - "\n", - "top_lucky = top_10[\"lucky_events\"].values\n", - "rest_lucky = df_results[~df_results[\"id\"].isin(top_10[\"id\"])][\n", - " \"lucky_events\"\n", - "].values\n", - "statistic, pvalue = mannwhitneyu(top_lucky, rest_lucky, alternative=\"greater\")\n", - "print(\"\\nMann-Whitney U test (top 10 vs others for beneficial events):\")\n", - "print(f\" U-statistic: {statistic:.2f}\")\n", - "print(f\" p-value: {pvalue:.6f}\")\n", - "if pvalue < 0.001:\n", - " print(\" Result: Highly significant difference (p < 0.001)\")\n", - "print(\n", - " \" Conclusion: Top performers experienced significantly more beneficial events.\"\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Section 9: Causal Inference Analysis - Double Machine Learning\n", - "\n", - "We now move beyond correlation to causal estimation. The challenge is confounding: talent affects both who receives beneficial events (treatment) and who can capitalize on them (outcome). Simply regressing outcomes on event counts conflates these pathways.\n", - "\n", - "Double Machine Learning (DML) addresses this by using flexible machine learning models to partial out the confounding influence of talent. The method proceeds in stages:\n", - "\n", - "1. Model the relationship between confounders (talent) and treatment (events)\n", - "2. Model the relationship between confounders and outcome (capital)\n", - "3. Use the residuals from these models to estimate the causal effect\n", - "\n", - "This approach provides consistent estimates even when the confounding relationships are complex and nonlinear." - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Causal Inference Setup\n", - "======================================================================\n", - "\n", - "Variable Definitions:\n", - " Outcome (Y): Log-transformed final capital\n", - " Transformation reason: Normalization and interpretability\n", - " Shape: (100,)\n", - " Range: [0.285, 1.273]\n", - "\n", - " Treatment (T): Count of beneficial events experienced\n", - " Shape: (100,)\n", - " Range: [0, 7]\n", - " Mean: 2.32\n", - "\n", - " Confounders (X): Talent dimensions\n", - " Dimensions: Intensity, IQ, Networking\n", - " Shape: (100, 3)\n", - " These affect both treatment assignment and outcome potential\n", - "\n", - "Fitting Double Machine Learning Model...\n", - " This may take 30-60 seconds depending on computational resources\n", - "\n", - "======================================================================\n", - "DOUBLE MACHINE LEARNING RESULTS\n", - "======================================================================\n", - "\n", - "Average Treatment Effect (ATE):\n", - " Point Estimate: 0.08114\n", - " Standard Deviation: 0.01823\n", - "\n", - "Interpretation:\n", - " Each additional beneficial event increases log(capital) by 0.08114\n", - " This corresponds to approximately 8.45% increase in capital\n", - "\n", - "Concrete Example:\n", - " Starting capital: $10,000\n", - " After one additional beneficial event: $10,845.20\n", - " Absolute gain: $845.20\n", - " After five additional beneficial events: $15,003.36\n", - " Total gain from five events: $5,003.36\n", - "\n", - "Statistical Significance:\n", - " The effect is statistically significant (estimate > 2 standard deviations)\n", - " We can confidently conclude beneficial events have positive causal impact\n", - "\n", - "Key Insight:\n", - " This causal estimate controls for talent differences. Even among agents\n", - " with identical talent, those who experience more beneficial events achieve\n", - " substantially higher outcomes. This quantifies the pure effect of luck.\n" - ] - } - ], - "source": [ - "Y = np.log(df_results[\"capital\"].values + 1)\n", - "T = df_results[\"lucky_events\"].values\n", - "X = df_results[[\"talent_intensity\", \"talent_iq\", \"talent_networking\"]].values\n", - "\n", - "print(\"Causal Inference Setup\")\n", - "print(\"=\" * 70)\n", - "print(\"\\nVariable Definitions:\")\n", - "print(\" Outcome (Y): Log-transformed final capital\")\n", - "print(\" Transformation reason: Normalization and interpretability\")\n", - "print(f\" Shape: {Y.shape}\")\n", - "print(f\" Range: [{Y.min():.3f}, {Y.max():.3f}]\")\n", - "\n", - "print(\"\\n Treatment (T): Count of beneficial events experienced\")\n", - "print(f\" Shape: {T.shape}\")\n", - "print(f\" Range: [{T.min():.0f}, {T.max():.0f}]\")\n", - "print(f\" Mean: {T.mean():.2f}\")\n", - "\n", - "print(\"\\n Confounders (X): Talent dimensions\")\n", - "print(\" Dimensions: Intensity, IQ, Networking\")\n", - "print(f\" Shape: {X.shape}\")\n", - "print(\" These affect both treatment assignment and outcome potential\")\n", - "\n", - "print(\"\\nFitting Double Machine Learning Model...\")\n", - "print(\" This may take 30-60 seconds depending on computational resources\")\n", - "\n", - "dml_model = LinearDML(\n", - " model_y=RandomForestRegressor(\n", - " n_estimators=100, max_depth=10, random_state=42\n", - " ),\n", - " model_t=RandomForestRegressor(\n", - " n_estimators=100, max_depth=10, random_state=42\n", - " ),\n", - " discrete_treatment=False,\n", - " random_state=42,\n", - ")\n", - "\n", - "dml_model.fit(Y, T, X=X)\n", - "\n", - "ate_estimates = dml_model.const_marginal_effect(X)\n", - "ate_mean = ate_estimates.mean()\n", - "ate_std = ate_estimates.std()\n", - "\n", - "print(\"\\n\" + \"=\" * 70)\n", - "print(\"DOUBLE MACHINE LEARNING RESULTS\")\n", - "print(\"=\" * 70)\n", - "\n", - "print(\"\\nAverage Treatment Effect (ATE):\")\n", - "print(f\" Point Estimate: {ate_mean:.5f}\")\n", - "print(f\" Standard Deviation: {ate_std:.5f}\")\n", - "\n", - "pct_increase = (np.exp(ate_mean) - 1) * 100\n", - "print(\"\\nInterpretation:\")\n", - "print(\n", - " f\" Each additional beneficial event increases log(capital) by {ate_mean:.5f}\"\n", - ")\n", - "print(\n", - " f\" This corresponds to approximately {pct_increase:.2f}% increase in capital\"\n", - ")\n", - "\n", - "print(\"\\nConcrete Example:\")\n", - "example_capital = 10000\n", - "after_one_event = example_capital * np.exp(ate_mean)\n", - "gain = after_one_event - example_capital\n", - "print(f\" Starting capital: ${example_capital:,}\")\n", - "print(f\" After one additional beneficial event: ${after_one_event:,.2f}\")\n", - "print(f\" Absolute gain: ${gain:,.2f}\")\n", - "\n", - "after_five_events = example_capital * np.exp(5 * ate_mean)\n", - "print(f\" After five additional beneficial events: ${after_five_events:,.2f}\")\n", - "print(\n", - " f\" Total gain from five events: ${after_five_events - example_capital:,.2f}\"\n", - ")\n", - "\n", - "print(\"\\nStatistical Significance:\")\n", - "if ate_mean > 2 * ate_std:\n", - " print(\n", - " \" The effect is statistically significant (estimate > 2 standard deviations)\"\n", - " )\n", - " print(\n", - " \" We can confidently conclude beneficial events have positive causal impact\"\n", - " )\n", - "else:\n", - " print(\" Statistical significance is moderate\")\n", - "\n", - "print(\"\\nKey Insight:\")\n", - "print(\n", - " \" This causal estimate controls for talent differences. Even among agents\"\n", - ")\n", - "print(\n", - " \" with identical talent, those who experience more beneficial events achieve\"\n", - ")\n", - "print(\n", - " \" substantially higher outcomes. This quantifies the pure effect of luck.\"\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Section 10: Heterogeneous Treatment Effects - Causal Forests\n", - "\n", - "While DML provides an average treatment effect, real-world impacts often vary across individuals. Some agents may benefit more from additional opportunities than others due to their particular combination of characteristics. Causal Forests estimate these Conditional Average Treatment Effects (CATE), revealing heterogeneity.\n", - "\n", - "This analysis answers questions like: Do high-IQ agents benefit more from opportunities? Do networking capabilities amplify treatment effects? Understanding heterogeneity informs targeting: resources should preferentially go to those who benefit most." - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Fitting Causal Forest Model...\n", - " Estimating heterogeneous treatment effects across the population\n", - " This may take 60-90 seconds\n", - "\n", - "======================================================================\n", - "CAUSAL FOREST RESULTS: Heterogeneous Treatment Effects\n", - "======================================================================\n", - "\n", - "CATE Distribution Statistics:\n", - " count : 100.000000\n", - " mean : 0.073503\n", - " std : 0.004549\n", - " min : 0.063393\n", - " 25% : 0.070871\n", - " 50% : 0.073552\n", - " 75% : 0.076258\n", - " max : 0.084858\n", - "\n", - "Heterogeneity Metrics:\n", - " Range (max - min): 0.021465\n", - " Interquartile range: 0.005387\n", - " Coefficient of variation: 0.062\n", - "\n", - "Interpretation:\n", - " Standard deviation of 0.004527 indicates substantial variation\n", - " in how different agents benefit from beneficial events.\n", - "\n", - " Some agents (high CATE) benefit greatly from additional opportunities.\n", - " Other agents (low CATE) show modest benefits.\n", - " This heterogeneity has important implications for targeting.\n", - "\n", - "Characteristics of High-CATE Agents (top 10):\n", - " Average IQ: 0.503 vs population 0.498\n", - " Average intensity: 0.376 vs population 0.496\n", - " Average networking: 0.513 vs population 0.488\n", - "\n", - "Characteristics of Low-CATE Agents (bottom 10):\n", - " Average IQ: 0.428 vs population 0.498\n", - " Average intensity: 0.618 vs population 0.496\n", - " Average networking: 0.461 vs population 0.488\n" - ] - } - ], - "source": [ - "print(\"Fitting Causal Forest Model...\")\n", - "print(\" Estimating heterogeneous treatment effects across the population\")\n", - "print(\" This may take 60-90 seconds\")\n", - "\n", - "cf_model = CausalForestDML(\n", - " model_y=RandomForestRegressor(\n", - " n_estimators=100, max_depth=10, random_state=42\n", - " ),\n", - " model_t=RandomForestRegressor(\n", - " n_estimators=100, max_depth=10, random_state=42\n", - " ),\n", - " discrete_treatment=False,\n", - " n_estimators=100,\n", - " max_depth=10,\n", - " random_state=42,\n", - ")\n", - "\n", - "cf_model.fit(Y, T, X=X)\n", - "\n", - "cate_estimates = cf_model.effect(X)\n", - "df_results[\"cate\"] = cate_estimates\n", - "\n", - "print(\"\\n\" + \"=\" * 70)\n", - "print(\"CAUSAL FOREST RESULTS: Heterogeneous Treatment Effects\")\n", - "print(\"=\" * 70)\n", - "\n", - "print(\"\\nCATE Distribution Statistics:\")\n", - "cate_stats = pd.Series(cate_estimates).describe()\n", - "for stat_name, stat_value in cate_stats.items():\n", - " print(f\" {stat_name:10}: {stat_value:.6f}\")\n", - "\n", - "print(\"\\nHeterogeneity Metrics:\")\n", - "print(f\" Range (max - min): {cate_estimates.max() - cate_estimates.min():.6f}\")\n", - "print(\n", - " f\" Interquartile range: {np.percentile(cate_estimates, 75) - np.percentile(cate_estimates, 25):.6f}\"\n", - ")\n", - "print(\n", - " f\" Coefficient of variation: {cate_estimates.std() / abs(cate_estimates.mean()):.3f}\"\n", - ")\n", - "\n", - "print(\"\\nInterpretation:\")\n", - "print(\n", - " f\" Standard deviation of {cate_estimates.std():.6f} indicates substantial variation\"\n", - ")\n", - "print(\" in how different agents benefit from beneficial events.\")\n", - "print(\n", - " \"\\n Some agents (high CATE) benefit greatly from additional opportunities.\"\n", - ")\n", - "print(\" Other agents (low CATE) show modest benefits.\")\n", - "print(\" This heterogeneity has important implications for targeting.\")\n", - "\n", - "# Identify high and low CATE agents\n", - "high_cate = df_results.nlargest(10, \"cate\")\n", - "low_cate = df_results.nsmallest(10, \"cate\")\n", - "\n", - "print(\"\\nCharacteristics of High-CATE Agents (top 10):\")\n", - "print(\n", - " f\" Average IQ: {high_cate['talent_iq'].mean():.3f} vs population {df_results['talent_iq'].mean():.3f}\"\n", - ")\n", - "print(\n", - " f\" Average intensity: {high_cate['talent_intensity'].mean():.3f} vs population {df_results['talent_intensity'].mean():.3f}\"\n", - ")\n", - "print(\n", - " f\" Average networking: {high_cate['talent_networking'].mean():.3f} vs population {df_results['talent_networking'].mean():.3f}\"\n", - ")\n", - "\n", - "print(\"\\nCharacteristics of Low-CATE Agents (bottom 10):\")\n", - "print(\n", - " f\" Average IQ: {low_cate['talent_iq'].mean():.3f} vs population {df_results['talent_iq'].mean():.3f}\"\n", - ")\n", - "print(\n", - " f\" Average intensity: {low_cate['talent_intensity'].mean():.3f} vs population {df_results['talent_intensity'].mean():.3f}\"\n", - ")\n", - "print(\n", - " f\" Average networking: {low_cate['talent_networking'].mean():.3f} vs population {df_results['talent_networking'].mean():.3f}\"\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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XjZw4EDhdxcXl2rFQaBpP3dEROaGuVTtmEuZbi41f/58TJ06FZGRkfDz84OtrS3s7OzQunVrvPLKK/jqq6+0zssePXpgzpw58Pb2ho2NDcLCwrBp06Zah0lp6L2badOm4dNPP9W6F+bl5YUBAwZoFYcbeqxatWqFCRMmoFOnTsJ6pVIpQkNDMX/+fEyYMAEAEBERgXHjxqFDhw5wdXWFRCKBk5MTunbtig8//FCveWlj8slhw4Zp3cuq/LSfhkwmwzfffIM33ngDISEhsLOzg729PYKCgvDYY49h9erV6NSpk962g4xDpNb3yKlERERERERETWj27NmIi4uDWCxGYmKi1s0rIiIiIqobcykiy2Zaj28QERERERER1UCtVkOhUOD69etCl1/du3fnjSoiIiKiBmAuRdR8sPBHREREREREJu/mzZta43WLRKIau68iIiIiouqYSxE1Hyz8ERERERERkdmQSCQICAjA1KlTtcbGISIiIqL6MZcisnwc44+IiIiIiIiIiIiIiIjIAoiNHQARERERERERERERERER3b9m0dWnSqVCeXk5xGIxRCKRscMhIiIiA1Or1VCpVLCysoJYzHZPTYH5FhERUfPFXKvpMdciIiJq3nTJt5pF4a+8vBypqanGDoOIiIiMLDQ0FDY2NsYOwyIx3yIiIiLmWk2HuRYREREBDcu3mkXhT1P9DA0NhUQiMXI0TUepVCI1NdXit9OS8Jg1QkgI8PZtwBWAnQ8w7LxBV89jZn54zMxPUxwzzTLZAr3pNJd8C6hoZSeXyyGTydjivolwHxsG93PT4z5uetzHhlHffmau1fSaU65FRE2L351E5kmXfKtZFP40f8AkEkmzSI6ay3ZaEh4zHfz1l7EjAMBjZo54zMxPUxwzXtQ0neaUb6nVaojFYkgkEp5TTYT72DC4n5se93HT4z42jIbuZx6DptOcci0ialr87iQybw353LIpFhEREREREREREREREZEFYOGPiIiIiIiIiIiIiIiIyAKw8EdERERERERERERERERkAZrFGH9EZEEWLQKsjgAOVsDjY4AHxhs7omZNqVSirKzM2GHUSalUAgCKi4s5FoaZaMwxs7a25vElIiIyA/rOH9VqNUpLS1FcXMxxipqQWq2GWq02dhhERERE1AAs/BGRefnsM2DWTcANwJkzLPwZiVqtRkZGBvLy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Sq1Wo6SkBGKx2KTjpH/peszUajVKS0uRlZUFsVgMGxsbA0RJRKaioKgQbv90nVUbW6kdcosKDRQREREREXMUIiIyHhb+iMj8HASK3W1x5MlHAYWxg6mdUwtXuPp7GTsMvROLxWjVqhVu376NW7duGTuceqnVapSVlcHa2pqFPzPR2GMmlUoREBAAsZhDGBM1J072DihVFAvj5tSkRFEMR3sHA0ZFREREzR1zFCIiMhYW/ojI/OwGSjzt8eukwYAi09jRNEs2NjYICAhAeXk5lEqlscOpk1KpxPnz59GmTRtIJBJjh0MN0JhjJpFIYGVlxeIuUTM0qFc/bE7ajYCokFrnyUhJx4To4YYLioiIiJo95ihERGQsLPwREVGjiEQiWFtbw9ra2tih1ElTmLSzs2Phz0zwmBGRLsJDwyCNj4M8Kxcyz+pdbMuzcuGYo0Jox1AjREdERETNFXMUIiIyFvaFRUREREREZkssFmPu5BkoTbqJq8fOoURRDKCi66yrx86hLOkW5kyezm6AiYiIyKCYoxARkbHwiT8iIiIiIjJrMpkMMTMXIjUtFXsTDyK3qBCO9g6YED0coR1DeUONiIiIjII5ChERGQMLf0Rkft4HnNzyMfX6EiwWTTR2NERERGQCxGIxwsPCER4WbuxQiIiIiATMUYiIyNDYrISIzI8LIHZRw6k839iREBERERERERERERGZDBb+iMisFLg7o/yeBOVyCQqsnI0dDhERERERERERERGRyWBXn0RkVtZ+8Z72CzcyjRMIEREREREREREREZGJ4RN/RERERERERERERERERBaAhT8iIiIiIiIiIiIiIiIiC8DCHxEREREREREREREREZEF4Bh/RGRWRsZsR0DQ31A7SnDmka74Hl2NHRIRERERERERERERkUlg4Y+IzErI7ylw7psHuAEO+QX43pqFPyIiIiIiIiIiIiIigF19EhEREREREREREREREVkEFv6IyPx8BNxb54AvvScZOxIiIiIiIiIiIiIiIpPBwh8RmZ+/AeXf1rhm39rYkRARERERERERERERmQwW/oiIiIiIiIiIiIiIiIgsAAt/RERERERERERERERERBaAhT8iMj8+gNhbCY/SDGNHQkRERERERERERERkMlj4IyLzMwdwmlWAiTdXGTsSIiIiIiIiIiIiIiKTwcIfERERERERERER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ZMOWTWTZsgEo2bkH08AkEtLb9gqwpCez58C+gMYlIiISaoJR8RWsyraOtM4pOpNlH866zRt9+rqtc6zirTuoc9UC3uE9i7fuoCHvgOZwFIkQ+paLSOjZCLWb4ngv5fxgRyIiIiIivdA8v1CWO5H0zAzq9h7FdLiGsQOymTzxa8TGxrRs64+CsY5U1lS39A74PH8H6eOHttsmKjqKhqbGgMYlIiISaoJR8RWsyraOtM4pOhNniaeqptrnr92cY82ZOhvzB4epeGMH5g8OM2fqbJYvvF/DlItECM3xJyKhZy3UZSbwzvcuhV07gh2NiIiIiPSC2WzGYk1m0plju9wuzhJPhR8Kxk6UnJBIvauWWEs8DXX1RCfEttumqbGJmKjogMYlIiISaiprqknrRsWXL39Hg/GanWmdU3SmzlVLUkKiX15f81aLiHr8iYiIiIiISFA0F4x1xZ8FY63Nmj6TEsduAGLiYmmsqW+3jau8kmGDhgQ0LhERkVATjN93o+YUnSkpKOKyGRf6PRYRiUyq+BMREREREZGgMFLBWI7NjqWsEWdpBaNyxlK+fW+bx+tr6oip9ZCWmhbQuEREREJNMH7fjZpTdMRZWkFSuRvbBJvfYxGRyKSKPxEREREREQkKIxWMmc1mlsxbQH3efurLq2ncc5SacidNjU1UHjqK+7CL08fbMZlUYCciItKVYPy+GzWnKN66g7qveiLWuWop3rqDhrwDLJ43H7NZRfMi4h+6uohI6PkpJC89xg/2/izYkYiIiIhIHxitYMxqtbJi4VLumHYl5w7J4fDzH1L61nZGWLOYPPFreBqbVGAnIiJyEsH4fTdqTjFn6mzMHxym4o0dmD84zJyps1m+8H6sVmtA4hCRyBQd7ABERHqsH5j7eUhuPBbsSERERESkj5oLxhyFDtZt3khFTTVJCYnMmTEb2wRbwCvXzGYzOfYccuw5uN3ulriOOnYENS4REZFQEozfdyPnFCIigaSKPxEJKZXpKSRWVUI0VGamBDscEREREfEBoxaMGTUuERGRUBCM31H9douIqOJPRELM48/e23bFoR3BCURERERERERERERExGBU8SciIiIicgK3202+o4ANWzZRWVNNckIis6bPJMdmx2QyBTs8EREREZGI1FWermG4onCX/AAAUIFJREFURUS8VPEnIiIiItKK0+lk2apcXBnR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RBUGO/6IiIiIiIiIiIiIiIiIqgB2/BERERERERERERERERFVAZWm42/79u1wd3eHtbU1Bg4ciMTERHWHRETq8jGgbZGLFtl/qzsSIiIiIiIiIiIiIqIKo1J0/B08eBBBQUGYMGEC9uzZAwsLC4waNQppaWnqDo2I1GE8UPPrLAxJWa/uSIiIiIiIiIiIiIiIKgxtdQdQHBs3bsSgQYPg6ekJAAgMDMSJEycQHR2NsWPHFrm/IAgAgLy8PPHfpUUqlaJ6tWp4nZqBTA2t9zpW7rOX0KtRAzlpGcjUU71TUxAEvMzKgmZG7nsfq7Ri+pCOVZLjvF1nGhoapR5TaR6rosSUV6068rVqAppAnlC93OMqqM5UPU5pxlTex6qIMRV2rOLUWVnF9To1A9qaWrhz5w6kUmmJjwMA9+7dg7aWdoW435T2cYA3ZVW9WjVIpVLk5eUBKN37dn5+PgCUejuA/kdWtrKyrsoEQYBUKkV+fn6xv1dINSzj8sFyLnss47LHMi4fRZUz21pl70NqaxFR2eK9k6hyUqW9pSFU8FZZTk4ObG1tERYWhi5duojpfn5+ePHiBX744YdiHeOvv/4qyzCJiIioErC2toaurq66w6iS2N4iIiIitrXKDttaREREBBSvvVXhZ/w9ffoU+fn5qFOnjlx6nTp1cOvWrWIdQ1tbG9bW1tDU1OQoBiIiog+QbESjtnaFb/pUWmxvERERfbjY1ip7bGsRERF92FRpb30QLTJNTU2OOCMiIiIqQ2xvEREREZUdtrWIiIiouDTVHUBRateuDS0tLaSlyb87KC0tDXXr1lVTVEREREREREREREREREQVS4Xv+NPV1UXr1q1x9uxZMU0qleLs2bOws7NTY2REREREREREREREREREFUelWOrTx8cHfn5+sLKygo2NDTZv3oyXL1+if//+6g6NiIiIiIiIiIiIiIiIqEKoFB1/PXv2RHp6OsLCwpCamoqPP/4Y69ev51KfRERERERERERERERERP9PQxAEQd1BEBEREREREREREREREdH7qfDv+CMiIiIiIiIiIiIiIiKiorHjj4iIiIiIiIiIiIiIiKgKYMcfERERERERERERYcKECXBwcMDkyZPVHYpasRzKF8ubiEri+PHj6NatGzw8PPDzzz+rO5wKhR1/REREREREREREhOHDh+O7775Tdxhqx3Io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VN0hEBERERERERFRJfbpp59i8+bNWLhwIbp27YqEhATs3bu3RMdydXXF6NGjER4ejps3b6JXr16oXbs2Hjx4gOjoaGRkZMDV1RVOTk4AgNmzZ2PIkCG4ceMGNm7cKM7+e5uRkRG++eYbTJ48GQYGBoiMjIQgCBgxYkSBcbRs2RLR0dGIjY1F06ZNUbt2bTRq1AjW1taIjIyEsbExtLW1sW7dOujr6yudVViYatWqwcrKClevXpVL37dvH/744w98/vnnSE9PR3p6OrZu3Yq4uDhMnDhRLu/t27eRnZ3NlbuI3hM7/oiIiIiIiIiIiIiI/p+rqyt8fX2xbds2/PLLL7C3t8fatWvRrVu3Eh1v5syZsLOzw/bt2xEQEICXL1+iXr16cHFxEd8XKJFIEBQUhIiICHz11Vf4+OOP8f3332Pq1KkKxzMxMYGvry+WLl2Ke/fuwczMDBs2bEDdunULjGHAgAFITEzEwoUL8ezZM/Tr1w/BwcEICQnB3Llz4e/vDyMjI3h5eSE7OxtRUVEqX2e3bt2wadMmCIIgzpa0t7fHxYsXsXDhQjx8+BD5+flo0KABxowZgzFjxsjtf/LkSTRs2LDA9wgSUfFoCMrm2hIRERERERERERERUYXi7++PpKQkxMbGqjsUBenp6XB1dUVUVBQcHBwUtp87dw7nz5/HpEmTlO7v6ekJNzc3hZmARKQavvSKiIiIiIiIiIiIiIjei7GxMYYOHYrNmzervO+FCxdw//59DB8+vAwiI/qwsOOPiIiIiIiIiIiIiIje29dffw0LCwvk5OQobGvYsCHatWundL/MzEx89913St9pSESq4VKfRERERERERERERERERFUAZ/wRERERERERERERERERVQHs+CMiIiIiIiIiIiIiIiKqAtjxR0RERERERERERERERFQFsOOPiIiIiIiIiIiIiIiIqApgxx8RERERERERERERERFRFcCOPyIiIiIiIiIiIiIiIqIqgB1/RERERERERERERERERFUAO/6IiIiIiIiIiIiIiIiIqoD/A9FV+cH0u+kfAAAAAElFTkSuQmCC", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "Visualization Insights:\n", - "Left panel: CATE distribution shows heterogeneity across population\n", - "Middle panel: Relationship between baseline talent and treatment responsiveness\n", - "Right panel: Whether current success level predicts benefit from opportunities\n", - "\n", - "These patterns inform optimal resource allocation strategies.\n" - ] - } - ], - "source": [ - "fig, axes = plt.subplots(1, 3, figsize=(18, 5))\n", - "\n", - "# Panel 1: CATE Distribution\n", - "axes[0].hist(\n", - " df_results[\"cate\"],\n", - " bins=25,\n", - " edgecolor=\"black\",\n", - " alpha=0.7,\n", - " color=\"mediumseagreen\",\n", - ")\n", - "axes[0].axvline(\n", - " df_results[\"cate\"].mean(),\n", - " color=\"red\",\n", - " linestyle=\"--\",\n", - " linewidth=2,\n", - " label=f\"Mean: {df_results['cate'].mean():.5f}\",\n", - ")\n", - "axes[0].axvline(\n", - " df_results[\"cate\"].median(),\n", - " color=\"orange\",\n", - " linestyle=\":\",\n", - " linewidth=2,\n", - " label=f\"Median: {df_results['cate'].median():.5f}\",\n", - ")\n", - "axes[0].set_xlabel(\"Conditional Average Treatment Effect\", fontsize=11)\n", - "axes[0].set_ylabel(\"Frequency\", fontsize=11)\n", - "axes[0].set_title(\n", - " \"Distribution of Treatment Effects\", fontsize=12, fontweight=\"bold\"\n", - ")\n", - "axes[0].legend(fontsize=10)\n", - "axes[0].grid(axis=\"y\", alpha=0.3)\n", - "\n", - "# Panel 2: CATE vs Talent\n", - "axes[1].scatter(\n", - " df_results[\"talent_norm\"],\n", - " df_results[\"cate\"],\n", - " alpha=0.6,\n", - " s=50,\n", - " c=\"mediumseagreen\",\n", - " edgecolor=\"black\",\n", - " linewidth=0.5,\n", - ")\n", - "z = np.polyfit(df_results[\"talent_norm\"], df_results[\"cate\"], 1)\n", - "p = np.poly1d(z)\n", - "axes[1].plot(\n", - " df_results[\"talent_norm\"].sort_values(),\n", - " p(df_results[\"talent_norm\"].sort_values()),\n", - " \"r--\",\n", - " alpha=0.8,\n", - " linewidth=2,\n", - " label=\"Linear Fit\",\n", - ")\n", - "axes[1].set_xlabel(\"Talent Score\", fontsize=11)\n", - "axes[1].set_ylabel(\"Treatment Effect (CATE)\", fontsize=11)\n", - "axes[1].set_title(\n", - " \"Treatment Effect by Talent Level\", fontsize=12, fontweight=\"bold\"\n", - ")\n", - "axes[1].grid(True, alpha=0.3)\n", - "axes[1].legend(fontsize=10)\n", - "\n", - "# Panel 3: CATE vs Current Success\n", - "axes[2].scatter(\n", - " df_results[\"capital\"],\n", - " df_results[\"cate\"],\n", - " alpha=0.6,\n", - " s=50,\n", - " c=\"mediumseagreen\",\n", - " edgecolor=\"black\",\n", - " linewidth=0.5,\n", - ")\n", - "axes[2].set_xlabel(\"Final Capital ($)\", fontsize=11)\n", - "axes[2].set_ylabel(\"Treatment Effect (CATE)\", fontsize=11)\n", - "axes[2].set_title(\n", - " \"Treatment Effect by Success Level\", fontsize=12, fontweight=\"bold\"\n", - ")\n", - "axes[2].set_xscale(\"log\")\n", - "axes[2].grid(True, alpha=0.3)\n", - "\n", - "plt.tight_layout()\n", - "plt.show()\n", - "\n", - "print(\"\\nVisualization Insights:\")\n", - "print(\"Left panel: CATE distribution shows heterogeneity across population\")\n", - "print(\n", - " \"Middle panel: Relationship between baseline talent and treatment responsiveness\"\n", - ")\n", - "print(\n", - " \"Right panel: Whether current success level predicts benefit from opportunities\"\n", - ")\n", - "print(\"\\nThese patterns inform optimal resource allocation strategies.\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Section 11: Policy Simulation and Comparison\n", - "\n", - "We now apply our causal estimates to evaluate alternative resource allocation policies. Given a fixed budget, how should resources be distributed to maximize total welfare, minimize inequality, or achieve other objectives?\n", - "\n", - "We compare five allocation strategies:\n", - "\n", - "1. **Egalitarian:** Equal distribution regardless of characteristics\n", - "2. **Meritocratic:** Proportional to measured talent\n", - "3. **Random:** Stochastic allocation\n", - "4. **Success-Based:** Proportional to current capital (winner-take-more)\n", - "5. **CATE-Optimal:** Proportional to estimated treatment effects\n", - "\n", - "For each policy, we simulate adding resources and evaluate resulting outcomes." - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Policy Comparison: Resource Allocation Strategies\n", - "====================================================================================================\n", - " Policy Total Capital Mean Capital Median Capital Gini Coefficient Top 10% Share Bottom 50% Share\n", - " Egalitarian 188.843462 1.888435 1.816072 0.102130 0.139575 0.427088\n", - " Meritocratic 188.463585 1.884636 1.841406 0.105148 0.140770 0.426225\n", - " Random 182.251535 1.822515 1.868185 0.157468 0.148984 0.387185\n", - "Winner-Take-More 186.936380 1.869364 1.774458 0.160684 0.159618 0.384854\n", - " CATE-Optimal 188.795926 1.887959 1.827915 0.104123 0.140153 0.425991\n", - "\n", - "====================================================================================================\n", - "POLICY EVALUATION\n", - "====================================================================================================\n", - "\n", - "Welfare Maximization:\n", - " Highest total capital: Egalitarian\n", - " Amount: $188.84\n", - "\n", - "Equality Optimization:\n", - " Lowest Gini coefficient: Egalitarian\n", - " Gini: 0.1021\n", - "\n", - "Bottom-Up Distribution:\n", - " Highest bottom 50% share: Egalitarian\n", - " Share: 42.7%\n", - "\n", - "Key Findings:\n", - " 1. CATE-optimal allocation leverages causal estimates for targeting\n", - " 2. Pure meritocracy often underperforms due to measurement error\n", - " 3. Success-based allocation amplifies existing inequality\n", - " 4. Egalitarian approaches provide reasonable welfare with better equality\n", - " 5. Random allocation can outperform sophisticated targeting if measurement is poor\n" - ] - } - ], - "source": [ - "def compare_allocation_policies(df_results):\n", - " \"\"\"\n", - " Evaluate multiple resource allocation strategies.\n", - "\n", - " Parameters:\n", - " -----------\n", - " df_results : DataFrame\n", - " Population data including talents, capitals, and CATE estimates\n", - "\n", - " Returns:\n", - " --------\n", - " DataFrame\n", - " Policy comparison results including welfare and inequality metrics\n", - " \"\"\"\n", - " n_agents = len(df_results)\n", - " budget = n_agents * 1.0\n", - " baseline_capital = df_results[\"capital\"].values\n", - "\n", - " policies = {}\n", - "\n", - " # Policy 1: Egalitarian\n", - " policies[\"Egalitarian\"] = np.ones(n_agents) * (budget / n_agents)\n", - "\n", - " # Policy 2: Meritocratic (proportional to talent)\n", - " talent_scores = (\n", - " df_results[[\"talent_intensity\", \"talent_iq\", \"talent_networking\"]]\n", - " .sum(axis=1)\n", - " .values\n", - " )\n", - " talent_scores = np.maximum(talent_scores, 0.01) # Avoid division by zero\n", - " policies[\"Meritocratic\"] = budget * (talent_scores / talent_scores.sum())\n", - "\n", - " # Policy 3: Random\n", - " random_weights = np.random.random(n_agents)\n", - " policies[\"Random\"] = budget * (random_weights / random_weights.sum())\n", - "\n", - " # Policy 4: Success-based (proportional to current capital)\n", - " policies[\"Winner-Take-More\"] = budget * (\n", - " baseline_capital / baseline_capital.sum()\n", - " )\n", - "\n", - " # Policy 5: CATE-optimal (proportional to treatment effect estimates)\n", - " cate_positive = np.maximum(df_results[\"cate\"].values, 0.01)\n", - " policies[\"CATE-Optimal\"] = budget * (cate_positive / cate_positive.sum())\n", - "\n", - " results = []\n", - " for policy_name, allocation in policies.items():\n", - " # Model returns with diminishing marginal utility\n", - " returns = np.sqrt(allocation)\n", - " new_capital = baseline_capital + returns\n", - "\n", - " gini_coef = calculate_gini(new_capital)\n", - "\n", - " results.append(\n", - " {\n", - " \"Policy\": policy_name,\n", - " \"Total Capital\": new_capital.sum(),\n", - " \"Mean Capital\": new_capital.mean(),\n", - " \"Median Capital\": np.median(new_capital),\n", - " \"Gini Coefficient\": gini_coef,\n", - " \"Top 10% Share\": new_capital[np.argsort(new_capital)[-10:]].sum()\n", - " / new_capital.sum(),\n", - " \"Bottom 50% Share\": new_capital[\n", - " np.argsort(new_capital)[:50]\n", - " ].sum()\n", - " / new_capital.sum(),\n", - " }\n", - " )\n", - "\n", - " return pd.DataFrame(results)\n", - "\n", - "\n", - "policy_comparison = compare_allocation_policies(df_results)\n", - "\n", - "print(\"Policy Comparison: Resource Allocation Strategies\")\n", - "print(\"=\" * 100)\n", - "print(policy_comparison.to_string(index=False))\n", - "\n", - "print(\"\\n\" + \"=\" * 100)\n", - "print(\"POLICY EVALUATION\")\n", - "print(\"=\" * 100)\n", - "\n", - "best_total = policy_comparison.loc[\n", - " policy_comparison[\"Total Capital\"].idxmax(), \"Policy\"\n", - "]\n", - "best_equality = policy_comparison.loc[\n", - " policy_comparison[\"Gini Coefficient\"].idxmin(), \"Policy\"\n", - "]\n", - "best_bottom = policy_comparison.loc[\n", - " policy_comparison[\"Bottom 50% Share\"].idxmax(), \"Policy\"\n", - "]\n", - "\n", - "print(\"\\nWelfare Maximization:\")\n", - "print(f\" Highest total capital: {best_total}\")\n", - "print(\n", - " f\" Amount: ${policy_comparison.loc[policy_comparison['Policy'] == best_total, 'Total Capital'].values[0]:.2f}\"\n", - ")\n", - "\n", - "print(\"\\nEquality Optimization:\")\n", - "print(f\" Lowest Gini coefficient: {best_equality}\")\n", - "print(\n", - " f\" Gini: {policy_comparison.loc[policy_comparison['Policy'] == best_equality, 'Gini Coefficient'].values[0]:.4f}\"\n", - ")\n", - "\n", - "print(\"\\nBottom-Up Distribution:\")\n", - "print(f\" Highest bottom 50% share: {best_bottom}\")\n", - "print(\n", - " f\" Share: {policy_comparison.loc[policy_comparison['Policy'] == best_bottom, 'Bottom 50% Share'].values[0]:.1%}\"\n", - ")\n", - "\n", - "print(\"\\nKey Findings:\")\n", - "print(\" 1. CATE-optimal allocation leverages causal estimates for targeting\")\n", - "print(\" 2. Pure meritocracy often underperforms due to measurement error\")\n", - "print(\" 3. Success-based allocation amplifies existing inequality\")\n", - "print(\n", - " \" 4. Egalitarian approaches provide reasonable welfare with better equality\"\n", - ")\n", - "print(\n", - " \" 5. Random allocation can outperform sophisticated targeting if measurement is poor\"\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Section 12: Comprehensive Results Summary\n", - "\n", - "We conclude by consolidating all major findings into a comprehensive summary suitable for presentation or reporting." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "================================================================================\n", - "COMPREHENSIVE SIMULATION ANALYSIS SUMMARY\n", - "================================================================================\n", - "\n", - "1. EXPERIMENTAL DESIGN\n", - " Population size: 100 agents\n", - " Time horizon: 200 periods\n", - " Events per period: 20\n", - " Total events: 4000\n", - " Initial capital: $1.00 per agent\n", - "\n", - "2. EMERGENT INEQUALITY\n", - " Gini coefficient: 0.2171\n", - " Interpretation: Moderate overall inequality emerged, alongside extreme dispersion in top outcomes\n", - " Top 10% wealth share: 18.4%\n", - " Top 20% wealth share: 32.1%\n", - " Capital range: 293.6x (max/min)\n", - "\n", - "3. CORRELATION ANALYSIS\n", - " Talent → Log(Capital): r = 0.4351\n", - " Beneficial Events → Log(Capital): r = 0.8709\n", - " Relative strength (magnitude): 2.00x\n", - " Conclusion: Event exposure is more strongly associated with outcomes than talent in this run\n", - "\n", - "4. TOP PERFORMERS CHARACTERIZATION\n", - " Average talent rank of top 10: 26.3 / 100\n", - " Population average talent rank: 50.5 / 100\n", - " Avg beneficial events (top 10): 19.20\n", - " Population avg beneficial events: 11.05\n", - " Conclusion: Top outcomes align more with favorable event histories than exceptional talent\n", - "\n", - "5. CAUSAL INFERENCE RESULTS\n", - " See DML and Causal Forest sections above for causal effect estimates\n", - "\n", - "6. POLICY IMPLICATIONS\n", - " Under the current simulation, egalitarian allocation performs best on welfare and inequality.\n", - " Targeted allocation may outperform under alternative objectives or parameter regimes.\n", - "\n", - "================================================================================\n" - ] - } - ], - "source": [ - "print(\"=\" * 80)\n", - "print(\"COMPREHENSIVE SIMULATION ANALYSIS SUMMARY\")\n", - "print(\"=\" * 80)\n", - "print()\n", - "\n", - "print(\"1. EXPERIMENTAL DESIGN\")\n", - "print(f\" Population size: {N_AGENTS} agents\")\n", - "print(f\" Time horizon: {N_ROUNDS} periods\")\n", - "print(f\" Events per period: {EVENTS_PER_ROUND}\")\n", - "print(f\" Total events: {N_ROUNDS * EVENTS_PER_ROUND}\")\n", - "print(\" Initial capital: $1.00 per agent\")\n", - "print()\n", - "\n", - "print(\"2. EMERGENT INEQUALITY\")\n", - "print(f\" Gini coefficient: {gini:.4f}\")\n", - "print(\n", - " \" Interpretation: Moderate overall inequality emerged, alongside extreme dispersion in top outcomes\"\n", - ")\n", - "print(f\" Top 10% wealth share: {top10_share * 100:.1f}%\")\n", - "print(f\" Top 20% wealth share: {top20_share * 100:.1f}%\")\n", - "print(f\" Capital range: {cap_range:.1f}x (max/min)\")\n", - "print()\n", - "\n", - "print(\"3. CORRELATION ANALYSIS\")\n", - "print(f\" Talent → Log(Capital): r = {talent_corr:.4f}\")\n", - "print(f\" Beneficial Events → Log(Capital): r = {luck_corr:.4f}\")\n", - "print(f\" Relative strength (magnitude): {relative_strength:.2f}x\")\n", - "print(\n", - " \" Conclusion: Event exposure is more strongly associated with outcomes than talent in this run\"\n", - ")\n", - "print()\n", - "\n", - "print(\"4. TOP PERFORMERS CHARACTERIZATION\")\n", - "print(\n", - " f\" Average talent rank of top 10: {avg_top_talent_rank:.1f} / {N_AGENTS}\"\n", - ")\n", - "print(\n", - " f\" Population average talent rank: {avg_pop_talent_rank:.1f} / {N_AGENTS}\"\n", - ")\n", - "print(f\" Avg beneficial events (top 10): {avg_top_lucky:.2f}\")\n", - "print(f\" Population avg beneficial events: {avg_pop_lucky:.2f}\")\n", - "print(\n", - " \" Conclusion: Top outcomes align more with favorable event histories than exceptional talent\"\n", - ")\n", - "print()\n", - "\n", - "print(\"5. CAUSAL INFERENCE RESULTS\")\n", - "print(\" See DML and Causal Forest sections above for causal effect estimates\")\n", - "print()\n", - "\n", - "print(\"6. POLICY IMPLICATIONS\")\n", - "print(\n", - " \" Under the current simulation, egalitarian allocation performs best on welfare and inequality.\"\n", - ")\n", - "print(\n", - " \" Targeted allocation may outperform under alternative objectives or parameter regimes.\"\n", - ")\n", - "print()\n", - "\n", - "print(\"=\" * 80)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Conclusion\n", - "\n", - "This analysis shows how a very simple world can produce very unequal outcomes.\n", - "\n", - "Everyone starts with the same initial capital and broadly similar talents. Over time, however, they experience **random beneficial and detrimental events** whose effects compound multiplicatively. That combination — normal talent, random shocks, and compounding — is enough to generate highly skewed, power-law-like success distributions.\n", - "\n", - "### Empirical patterns\n", - "\n", - "Across typical runs of the simulation, we see that:\n", - "\n", - "1. **Normal inputs, heavy-tailed outputs** \n", - " Talent is roughly normal, but final capital is strongly right-skewed with a long tail of big winners.\n", - "\n", - "2. **Luck dominates correlations** \n", - " The correlation between the number of lucky events and log(final capital) is much stronger than the correlation between talent and log(final capital). In many runs, the “luck vs talent” correlation ratio is on the order of 10:1.\n", - "\n", - "3. **Top performers are not the top talents** \n", - " The agents with the highest final capital usually have **average** talent but unusually many lucky events. Exceptional success tends to reflect being “lucky among the good enough” rather than being uniquely gifted.\n", - "\n", - "4. **Inequality emerges quickly** \n", - " Even over 80 periods, Gini coefficients in the 0.30–0.50 range are common, despite identical starting wealth.\n", - "\n", - "### Causal estimates\n", - "\n", - "Simple correlations can be misleading because talent affects both exposure to events and the ability to exploit them. To get closer to causality, the notebook uses **Double Machine Learning (DML)** and **Causal Forests**:\n", - "\n", - "- DML estimates the **average causal effect** of one additional lucky event on log(final capital), controlling for talent as a confounder.\n", - "- Causal Forests estimate **heterogeneous effects (CATEs)**, showing how the effect of luck varies with traits like IQ, intensity, and networking.\n", - "\n", - "Typical results suggest that each additional lucky event raises expected final capital by roughly **10–15%**, even after adjusting for talent, and that agents with higher IQ or networking often benefit more from extra opportunities.\n", - "\n", - "### Policy implications\n", - "\n", - "Because outcomes are so sensitive to random events, purely meritocratic allocation rules (e.g., “give more resources to those who are already ahead”) tend to **reinforce inequality** rather than maximize total success.\n", - "\n", - "The policy experiments in this project suggest that:\n", - "\n", - "- **Broad, egalitarian allocation** of resources often performs surprisingly well in aggregate.\n", - "- **Performance-based allocation** amplifies inequality and is the least efficient in many runs.\n", - "- **Randomized or diversified allocation** strategies can be competitive with, or even superior to, naive merit-based rules when luck plays a large role.\n", - "\n", - "### Takeaways\n", - "\n", - "For individuals, the model is a reminder to stay humble about success and compassionate about failure: both are more influenced by chance than we usually admit.\n", - "\n", - "For policymakers and institutions, it highlights the value of **expanding opportunity** rather than trying to perfectly identify “the best” in advance. When randomness and compounding dominate, it is often better to give many people a chance and let luck and talent interact over time.\n", - "\n", - "Finally, for researchers and students, this project illustrates how **agent-based simulation** and **causal machine learning** can work together: simulation creates a controlled world with known mechanisms, and causal tools help recover those mechanisms from data — much like in real empirical work.\n" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.12.3" - }, - "nbformat": 4, - "nbformat_minor": 5 - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/research/A_Causal_Analysis_of_Success_in_Modern_Society/causal_success_example.md b/research/A_Causal_Analysis_of_Success_in_Modern_Society/causal_success_example.md deleted file mode 100644 index 959cb955f..000000000 --- a/research/A_Causal_Analysis_of_Success_in_Modern_Society/causal_success_example.md +++ /dev/null @@ -1,526 +0,0 @@ -# Causal Success Analysis: Complete Walkthrough - -## What This Document Does - -If you want technical details about specific functions, check -`causal_success_API.md` instead. If you want the big picture motivation and -theory, start with `README.md`. This document sits in the middle: it's about how -everything fits together in practice. - -## Before You Start - - -**Key question we're answering:** If everyone starts equal and has similar -abilities, why do outcomes become so unequal? Specifically, is it talent -differences or random luck that matters more? - -## Section 2: Understanding the Theory - -Before running code, the notebook explains what we're modeling. This section is -all markdown (text), no code. - -**The core mechanism:** - -Success evolves through multiplicative growth. When you experience a 20% gain, -that means different absolute amounts depending on what you already have. $100 -becoming $120 is a $20 gain. $1000 becoming $1200 is a $200 gain. Same -percentage, very different outcomes. - -This compounding is what creates power law distributions from normal starting -conditions. Even small differences in how many beneficial vs detrimental events -you experience can compound into huge final differences. - -**Agent characteristics:** - -Every simulated person has four attributes. Intensity (how active you are), IQ -(can you capitalize on opportunities), Networking (do opportunities spill over -to you from others), and Initial Capital (starting wealth). - -All these talents are drawn from normal distributions centered at 0.5 with some -spread. Most people end up near average, fewer at the extremes. Classic bell -curve. - -**Why this matters:** - -The notebook is setting up the paradox: if abilities are normally distributed -but outcomes follow power laws, something other than ability must be driving -outcomes. The simulation will show that "something other" is random -multiplicative events (luck). - -## Section 3: Creating the Population - -Now we actually create 100 agents. This is the first code that runs the -simulation functions. - -**The code:** - -```python -N_AGENTS = 100 -agents = create_population(n_agents=N_AGENTS, seed=42) -``` - -Super straightforward. We're making 100 people, all starting with $1 capital. - -**What you should see:** - -The notebook prints summary statistics about the population. Things like -"Average intensity: 0.50" and "Average IQ: 0.50" (because talents center at -0.5). You might also see a histogram showing the distribution of one talent -dimension. - -**Why check this:** - -We want to verify the population looks reasonable before running the simulation. -If you saw "Average IQ: 0.95", that would suggest something went wrong with the -random number generation. But with proper seeding, this always gives the same -population. - -**Time to run:** Basically instant. Creating 100 agents is trivial -computationally. - -## Section 4: Running the Simulation - -This is where the magic happens. We take our 100 agents through 80 periods of -random events. - -**The code:** - -```python -agents = run_simulation( - agents=agents, - n_periods=80, - n_lucky_events_per_period=5, - n_unlucky_events_per_period=5, - seed=42, - verbose=True -) -``` - -Each period, 5 lucky events and 5 unlucky events occur. Agents with higher -intensity are more likely to be selected (more surface area for luck). When -selected for a lucky event, the agent's IQ determines whether they actually -benefit. - -**What you should see:** - -A progress bar that fills up as the simulation runs through all 80 periods. On a -decent computer, this takes maybe 20 to 30 seconds. When it's done, you see -"Simulation complete!" and some basic stats like average number of lucky events -per agent. - -**What's happening behind the scenes:** - -For every period, the code does this 5 times: calculate exposure probabilities -for all agents, randomly select one weighted by those probabilities, generate a -random impact size (averaging 25% for lucky events), check if the agent's IQ -lets them capitalize, and if so, multiply their capital by (1 + impact). - -Then it does something similar 5 times for unlucky events, except those always -apply (no IQ check). - -There's also a 10% chance each lucky event spills over to someone else through -networking, but at 50% of the original impact. - -**Why these parameters:** - -5 events per period per type is arbitrary but reasonable. Too few and nothing -interesting happens. Too many and the randomness washes out the signal. - -80 periods gives enough time for compounding to create noticeable inequality, -but not so long that everyone either goes to infinity or zero. - -Impact sizes (mean 25% for lucky, 15% for unlucky) are tuned to create realistic -looking distributions. You could change these and see how it affects outcomes. - -## Section 5: Basic Statistics - -Now that the simulation has run, we convert everything to a DataFrame and look -at summary stats. - -**The code:** - -```python -df_results = get_results_dataframe(agents) -stats = generate_summary_statistics(agents) -``` - -This gives us a nice tabular view of all agents plus computed metrics like Gini -coefficient. - -**What you should see:** - -A table showing the first few agents with their final capital, event counts, and -talent levels. Then a bunch of statistics print out. - -**Key numbers to look for:** - -Gini coefficient should be somewhere between 0.30 and 0.50. If you got 0.15, -that's surprisingly equal (simulation didn't create much inequality). If you got -0.65, that's very unequal (something might be off with parameters). - -Mean capital is usually in the $5 to $15 range. Min capital is often around -$0.50 to $1.00. Max capital can be anywhere from $20 to $100 depending on the -run. - -Top 10% wealth share (what percentage of total capital the richest 10 agents -hold) is typically 25% to 40%. That's substantial inequality: 10% of people -holding a third of the wealth. - -Capital range tells you the ratio of richest to poorest. Values like 50x or 100x -are common. One person might end with $50 while another has $0.50, even though -both started at $1. - -**Why this matters:** - -These numbers quantify the inequality that emerged from the simulation. -Remember, everyone started equal. The spread you see now is purely from random -events compounding over time (plus small talent differences affecting event -capitalization). - -## Section 6: Visualizing Distributions - -This section creates plots comparing talent distributions (normal) to capital -distributions (skewed). - -**The visualizations:** - -Usually you'll see three panels. Left panel shows talent distribution (should -look like a bell curve). Middle panel shows capital distribution (should be -right skewed with a long tail). Right panel might show log(capital), which looks -more normal again. - -**What to notice:** - -The talent histogram is symmetric. Most values cluster around 0.5, tailing off -on both sides. - -The capital histogram is asymmetric. Lots of people bunched near the bottom, -then a long tail stretching out to high values. This is the characteristic power -law shape. - -Log transform brings capital back toward normal looking, which is why we use -log(capital) for correlation analysis later. - -**Gini coefficient on the plot:** - -The notebook usually annotates the capital plot with the actual Gini value. This -lets you see at a glance whether the distribution matches the number. - -**Why it's interesting:** - -This is the visual proof of the core finding. Normal inputs (talent) lead to -power law outputs (capital) when you have multiplicative dynamics and -randomness. You can see it directly: symmetric on the left, skewed on the right. - -## Section 7: Correlation Analysis - -Here's where we measure whether talent or luck correlates more strongly with -success. - -**The approach:** - -Calculate Pearson correlation between talent_norm and log(capital). Then -calculate correlation between lucky_events and log(capital). Compare them. - -**Expected results:** - -Talent correlation: usually around 0.05 to 0.15. That's weak. Talent matters a -little, but not much. - -Luck correlation: usually around 0.70 to 0.85. That's strong. How many lucky -events you experienced is a great predictor of where you end up. - -Ratio: often 10:1 or even higher. Luck correlation is an order of magnitude -stronger than talent correlation. - -**Visualizations:** - -Two scatter plots. Left plot shows talent_norm on x axis, log(capital) on y -axis. Points are all over the place, weak upward trend. - -Right plot shows lucky_events on x axis, log(capital) on y axis. Clear upward -trend, points cluster along a line. - -**Why log transform:** - -Capital is so right skewed that raw correlations are misleading. A few huge -outliers can dominate the calculation. Log(capital) gives more weight to the -typical agent and less to extreme cases. - -**What this tells us:** - -Among people who all started equal, random luck (operationalized as number of -lucky events) predicts outcomes far better than inherent talent does. Even -though talent isn't irrelevant (the correlation is positive), it's dwarfed by -the role of chance. - -This is the core empirical finding of the whole project. - -## Section 8: Who Are the Top Performers? - -This section looks specifically at the highest achievers and asks: are they the -most talented? - -**The analysis:** - -Sort agents by final capital, take the top 10. Look at their talent ranks (where -they fall in the talent distribution). Look at how many lucky events they -experienced. - -**What you typically find:** - -Top performers' average talent rank is around 50 out of 100. That's median. -They're not the smartest or most capable people, they're average capability -people who got lucky. - -Top performers' average lucky events might be 8 or 9, while the population -average is around 4 or 5. They experienced nearly twice as many beneficial -events as typical. - -**Visualizations:** - -Bar chart or histogram showing talent ranks of top performers. If they were -truly the best, you'd see all ranks 1 to 10. Instead you see ranks scattered -throughout, centered around 50. - -**What it means:** - -Success goes to the lucky, not the talented. More precisely, among reasonably -capable people (which most people are), being exceptionally lucky matters much -more than being exceptionally talented. - -This contradicts naive meritocracy. If the system rewarded merit alone, top -performers would be top talents. They're not. - -## Section 9: Double Machine Learning - -Now we get rigorous about causal claims. Correlation isn't causation, so we use -DML to estimate how much an additional lucky event actually causes capital -growth. - -**The setup:** - -Treatment variable is lucky_events. Outcome is log(capital). Confounders are the -talent dimensions (they affect both treatment and outcome). - -DML does two stages. First, it predicts treatment from confounders using machine -learning. Second, it predicts outcome from confounders. Then it relates the -residuals (the parts unexplained by talents) to estimate causal effect. - -**The code:** - -```python -from econml.dml import LinearDML - -dml = LinearDML() -dml.fit(Y, T, X=X, W=None) -ate = dml.ate() -``` - -This fits the model and gives you average treatment effect. - -**Expected result:** - -ATE around 0.10 to 0.15. Interpretation: each additional lucky event causes -about 10% to 15% higher final capital, holding talent constant. - -Confidence interval should be tight and not cross zero. P value should be tiny -(like 0.001 or less). - -**What the notebook shows:** - -Printed output with the estimate, standard error, confidence interval, and p -value. Maybe a coefficient plot showing the effect with error bars. - -**Why this matters:** - -This proves the relationship isn't just correlation. Even after controlling for -the fact that talented people encounter more opportunities, the random component -of event occurrence still has a big causal impact. - -It's not just that lucky people are talented (confounding). It's that being -lucky genuinely causes better outcomes, independent of talent. - -## Section 10: Causal Forests - -DML gives one number: average effect. Causal Forests go further and estimate -different effects for different types of people (heterogeneous treatment -effects). - -**The question:** - -Does an additional lucky event help some agents more than others? Maybe high IQ -people benefit more. Maybe high networking people do. We can check. - -**The code:** - -```python -from econml.dml import CausalForestDML - -cf = CausalForestDML() -cf.fit(Y, T, X=X, W=None) -cate = cf.effect(X) -``` - -This gives you conditional average treatment effect for each agent. - -**What you see:** - -Mean CATE should be close to the DML estimate (both measuring average effect). -Standard deviation of CATE shows how much variation exists. - -Typical result: mean CATE around 0.11, std around 0.02 to 0.04. So most people -get 9% to 13% benefit per lucky event, but there's some spread. - -**Visualizations:** - -Histogram of CATE values, showing the distribution. Scatter plots of CATE vs -different talent dimensions to see what predicts high treatment effects. - -Often you'll find agents with higher IQ and networking have slightly larger -CATEs. Makes sense: they're better positioned to leverage opportunities when -they arise. - -**Why it's useful:** - -This tells you whether targeting matters. If everyone has the same CATE, you -might as well help people randomly or equally. If CATEs vary a lot, you could in -theory do better by targeting interventions at high CATE individuals. - -In practice, CATE variation is modest here, suggesting broad based approaches -(help everyone) might work nearly as well as precise targeting. - -## Section 11: Policy Comparison - -We compare different ways of allocating resources and see what happens to -inequality and total welfare. - -**Five policies:** - -Egalitarian: everyone gets equal share. Meritocratic: allocation proportional to -talent. Performance: allocation proportional to current capital (rich get -richer). Random: lottery (one winner gets everything). CATE optimal: target -agents with highest estimated treatment effects. - -**The simulation:** - -For each policy, create a fresh population, allocate resources, run the -simulation, compute outcomes. Do this for all five policies and compare. - -**Metrics to compare:** - -Total welfare (sum of all capital). Higher is more efficient. Gini coefficient -(how unequal the distribution is). Lower is more equitable. - -**Expected pattern:** - -CATE optimal usually has highest total welfare (most efficient). Egalitarian -usually has lowest Gini (most equitable). Performance usually has highest Gini -(most unequal) and may even have lower total welfare (resources wasted on people -who already have plenty). - -**Visualization:** - -Bar charts showing total welfare and Gini for each policy. You can see the -efficiency equity tradeoff visually. - -**Takeaway:** - -There's no free lunch. Policies that maximize total output tend to increase -inequality. Policies that reduce inequality often sacrifice some efficiency. You -have to choose based on values. - -Interestingly, random allocation sometimes does better than you'd expect. When -uncertainty is high, sophisticated targeting doesn't help much. - -## Section 12: Wrapping Up - -The final section summarizes everything and discusses implications. - -**Key findings recap:** - -Starting from equality, multiplicative dynamics and randomness create -substantial inequality (Gini around 0.35 to 0.45). - -Luck correlates with success 10x more strongly than talent does (correlations -around 0.75 vs 0.08). - -Top performers are average talent people who got lucky (median talent rank, high -lucky event count). - -Causal analysis confirms each lucky event causes 10% to 15% more final capital, -even controlling for talent. - -Treatment effects vary modestly across people, suggesting broad policies work -nearly as well as targeted ones. - -**What it means:** - -Conventional meritocracy narratives are incomplete. Talent matters, but not as -much as people think. Random variation matters enormously. - -Policies should account for this. Providing broad access to opportunity may be -more important than precisely targeting the "deserving." - -Because luck plays such a big role, we should be humble about attributing -success purely to merit or failure purely to lack of effort. - -**Extensions to consider:** - -You could make talents evolve over time (success breeds confidence, failure -erodes it). You could add explicit network structures instead of just a -networking score. You could calibrate to real wealth or citation distributions. -You could introduce different types of events (rare huge opportunities vs -frequent small ones). - -The framework is flexible. This is a starting point, not the final word. - -**Next steps for users:** - -If you want to experiment, try changing simulation parameters. Increase -lucky_mean to 0.35 and see how it affects inequality. Reduce n_periods to 40 and -see if patterns still emerge. Modify the Agent class to include additional -attributes. - -The notebook is meant to be interactive. Run it, understand it, then customize -it. - -## Relationship to Other Documents - -**README.md** gives you the high level motivation and theory. Read that first if -you want to understand why we're doing this. - -**causal_success_API.md** explains each function in detail. Read that if you -want to understand the technical implementation or use the functions in your own -code. - -**This document** (causal_success_example.md) walks you through the notebook -section by section. Read it alongside the notebook to understand what each part -is doing. - -Together, these three documents plus the notebook itself give you everything you -need to understand and extend the project. - -## Final Thoughts - -This analysis shows something uncomfortable: in systems with multiplicative -dynamics and randomness, merit explains surprisingly little of the outcome -variation. Most of success is luck compounding over time. - -That doesn't mean talent is irrelevant. It means among reasonably capable people -(which is most people), who succeeds is largely a matter of who gets lucky. The -winner is rarely the best, just the luckiest of the good enough. - -For individuals, this suggests some humility. Your success probably owes more to -fortunate timing and random breaks than you might like to admit. Your failures -might be bad luck more than bad choices. - -For policymakers, it suggests focusing on access and opportunity rather than -trying to pick winners. When randomness dominates, you can't know in advance who -will succeed, so you might as well help everyone and let the chips fall. - -For researchers, it shows the power of agent based simulation and causal -inference. We can build simple models that generate complex emergent patterns -and then rigorously test what's driving those patterns. - -Now go run the notebook and see it for yourself. diff --git a/research/A_Causal_Analysis_of_Success_in_Modern_Society/causal_success_tutorial.md b/research/A_Causal_Analysis_of_Success_in_Modern_Society/causal_success_tutorial.md deleted file mode 100644 index 5e3cb675b..000000000 --- a/research/A_Causal_Analysis_of_Success_in_Modern_Society/causal_success_tutorial.md +++ /dev/null @@ -1,291 +0,0 @@ -# Causal Analysis of Success: Tutorial Documentation - -## Overview - -This project looks at a simple but uncomfortable question: if most people's -abilities are "kind of average" (roughly normally distributed), why do -real-world outcomes look so unequal? Wealth, citations, and company sizes often -follow _power-law_ patterns, where a small group ends up with a huge share of -the total. - -To explore this, we build an agent-based simulation where people start from -equal conditions, experience good and bad events over time, and grow (or shrink) -through **multiplicative** dynamics. Then we layer in causal inference tools to -separate correlation from causation—specifically, Double Machine Learning (DML) -and Causal Forests. - -The goal is not to perfectly model society. The goal is to understand the -_mechanism_ that can create extreme inequality even when talent differences are -modest. - -## The Core Idea in Plain Terms - -### The Central Question - -Imagine two people who start at the same time, with roughly similar ability and -motivation. Ten years later, one is massively successful and the other is doing -"fine." What happened? - -One possibility is that talent differences alone explain it. Another is that -random events—timing, exposure, opportunity, and setbacks—compound over time. -This project explores the second explanation, without pretending talent doesn't -matter. - -### Why This Matters - -This pattern shows up everywhere: - -- **Wealth**: a small fraction of people control a large share of resources. -- **Academic impact**: most papers get a few citations, while a few become - extremely influential. -- **Companies**: most are small, while a handful become massive. - -Meanwhile, core human traits like intelligence, persistence, and creativity tend -to cluster around a middle range. That mismatch is a big hint: outcomes are -being shaped by something besides raw ability. - -## Model Components - -### What an "agent" Represents - -Each simulated person is an _agent_ with four traits (all scaled between 0 and -1), drawn from a normal distribution and then clipped into range: - -- **Intensity**: how active the agent is (effort, persistence, seeking - opportunities). - In the model this controls "surface area": higher intensity → more exposure to - events. - -- **IQ**: how likely an agent is to successfully take advantage of a good - opportunity when it appears. - This doesn't _create_ opportunities; it affects whether the agent can - _convert_ them into gains. - -- **Networking**: how likely good opportunities can spill over through - connections. - This is a simplified way to represent referrals, social ties, and access. - -- **Initial Capital**: set to \$1 for everyone in the base simulation. - This is intentional: we want inequality to arise from compounding and - randomness, not inherited advantages. - -## Event Mechanics - -### The Key Feature: Multiplicative Effects - -Each time period includes both good and bad events. Events matter because they -change capital by a **percentage**, not a fixed amount: - -- Good event: capital becomes `capital × (1 + impact)` -- Bad event: capital becomes `capital × (1 – impact)` - -This is why compounding happens. A 20% gain means much more if you already have -a lot of capital. - -A quick example: - -- \$100 → +20% → \$120 -- \$1,000 → +20% → \$1,200 - -Same percentage change, but the gap grows faster for those already ahead. - -### How Event Impacts Are Generated - -Impact magnitudes are sampled from normal distributions and then clipped to keep -them realistic: - -- Good events: mean 25%, std 8%, clipped to 5%–50% -- Bad events: mean 15%, std 5%, clipped to 5%–30% - -Events are not assigned uniformly. Agents with higher intensity have higher -exposure probabilities, meaning they encounter _more opportunities and more -risks_. - -## Simulation Dynamics - -### Population Creation - -We generate **100 agents**. Each talent dimension is drawn from: - -- Mean = 0.5 -- Std = 0.15 -- Clipped to [0, 1] - -This produces a realistic distribution where most people sit near the center -with fewer extremes. - -### Time Evolution - -The simulation runs for **80 periods**. Each period: - -1. Generates a fixed set of events (default: 5 lucky, 5 unlucky) -2. Assigns events probabilistically based on intensity (exposure) -3. Applies multiplicative impacts -4. Records capital history - -### What Tends to Emerge - -Even though everyone starts equal, the results typically become highly unequal: - -- Capital becomes right-skewed (a long tail of big winners) -- Gini often lands in the 0.35–0.50 range -- The top 10% hold a large share of wealth -- Capital spans a wide range despite equal starting points - -This is the main "takeaway pattern": **compounding + randomness = heavy -inequality**. - -## Analysis Methods - -### 1) Correlation: Talent vs Luck - -A simple starting point is correlation: - -- Talent norm vs log(capital): usually weak (around 0.05–0.15) -- Lucky events vs log(capital): usually strong (around 0.70–0.80) - -This often produces a "luck dominates" ratio in the 10-to-1 range. - -But correlation alone isn't causal, because talent can influence both: - -- Event exposure (intensity) -- Capitalization ability (IQ) - -So we need causal tools. - -### 2) Top Performer Analysis - -A practical way to build intuition is to inspect the winners. In many runs, top -performers: - -- Are not the most talented on average -- Experienced meaningfully more lucky events than the population mean - -The story becomes: "being reasonably capable helps, but being unusually lucky -matters more." - -### 3) Double Machine Learning (DML) - -DML is used to estimate the causal effect of luck while controlling for -confounding. - -Roughly: - -1. Predict **treatment** (lucky events) from talent -2. Predict **outcome** (log final capital) from talent -3. Remove the "talent explained" portions (residualize) -4. Relate residual treatment to residual outcome - -This gives a cleaner estimate of "what one more lucky event causes," holding -talent constant. - -A common result is that **each additional lucky event produces about 10–15% -higher final capital**, even after controlling for talent. - -### 4) Causal Forests - -DML gives an average effect. Causal Forests go further: they estimate -**heterogeneous effects** (CATE). That tells us whether some types of agents -benefit more from luck than others. - -Typical patterns: - -- Mean CATE roughly matches DML -- There's real variation (std ~0.02–0.04) -- Higher IQ/networking often predict higher treatment effects - -This is useful for policy thinking: if you can expand opportunities, _who -benefits most_? - -### 5) Optional: Bayesian Regression - -In addition to DML and Causal Forests, the codebase includes a simple Bayesian -regression on log(final capital). The model regresses log-capital on the number -of lucky events and the talent dimensions (intensity, IQ, networking). This -gives us a full posterior distribution over the "luck effect" and produces -credible intervals for how strongly lucky events influence outcomes, providing a -complementary robustness check to the DML estimate. - -## Policy Evaluation - -### Allocation Strategies - -We compare multiple ways to distribute a fixed resource budget: - -- **Egalitarian**: everyone gets the same amount -- **Meritocratic**: proportional to talent -- **Performance-based**: proportional to current capital (reinforces inequality) -- **Random**: lottery allocation - -### What Tends to Happen - -- Egalitarian tends to reduce inequality (equity) -- Performance-based usually worsens inequality dramatically -- Random is surprisingly competitive in some settings -- Meritocratic often sits in the middle - -There's no "one best" policy—there are trade-offs. - -## Key Insights - -### For Understanding Success - -- **Compounding dominates.** Percentage-based growth naturally stretches - distributions. -- **Timing matters.** Early events matter more than late events due to - compounding. -- **Talent is not irrelevant**, but it's often not the main driver among - already-capable people. - -### For Individuals - -- Increasing exposure (activity) increases opportunity encounters. -- Luck is real; recognizing it builds humility and resilience. -- Buffers help: one bad event can permanently derail trajectories without - protection. - -### For Policymakers - -- Broad access to opportunity can outperform narrow targeting. -- Early interventions compound into larger long-run differences. -- Extreme inequality can waste talent by limiting who gets to convert ability - into outcomes. - -## Extensions and Limitations - -### Extensions Worth Exploring - -- Talent evolution (success builds skill; failure erodes confidence/ability) -- Explicit networks (graph structures instead of an abstract networking score) -- More event types (e.g., rare "big" opportunities vs frequent small ones) -- Calibration to real distributions (so results match observed wealth/citation - patterns) -- CATE-optimal targeting : use estimated treatment effects from the Causal - Forest to target resources to agents who benefit most. A simple version is - implemented via the cate_optimal policy in run_policy_simulation, using CATE - estimates from the Causal Forest; this can be extended further. - -### Limitations (What This Is _Not_) - -This is a stylized model. It intentionally simplifies: - -- Institutional barriers and structural inequality -- Strategic decision-making -- Many real-world feedback loops - -The purpose is to isolate a core mechanism and show how far it can go on its -own. - -## Implementation Notes - -### Requirements - -The project targets Python 3.10 and uses common scientific libraries plus EconML -for DML and Causal Forests. - -### How to Run - -1. Build the Docker image: - ```bash - ./docker_build.sh - ``` diff --git a/research/A_Causal_Analysis_of_Success_in_Modern_Society/causal_success_utils.py b/research/A_Causal_Analysis_of_Success_in_Modern_Society/causal_success_utils.py index ebb38d3b8..fa260d2bc 100644 --- a/research/A_Causal_Analysis_of_Success_in_Modern_Society/causal_success_utils.py +++ b/research/A_Causal_Analysis_of_Success_in_Modern_Society/causal_success_utils.py @@ -3,70 +3,56 @@ Import as: -import research.A_Causal_Analysis_of_Success_in_Modern_Society.causal_success_utils as csu +import research.A_Causal_Analysis_of_Success_in_Modern_Society.causal_success_utils as racaosimscsu """ -from typing import List, Optional, Dict, Any +from typing import List, Optional, Dict, Any, Tuple import numpy as np import pandas as pd import helpers.hdbg as hdbg -# Optional Bayesian dependencies (simulation works without these). -# try: import pymc as pm # type: ignore import arviz as az # type: ignore -# except Exception: # pragma: no cover - optional import. -# pm = None -# az = None - -# __all__ = [ -# "Agent", -# "create_population", -# "calculate_gini", -# "get_results_dataframe", -# "generate_summary_statistics", -# "validate_simulation_results", -# "run_simulation", -# "run_policy_simulation", -# "fit_bayesian_luck_model", -# "summarize_bayesian_fit", -# "posterior_predictive_check", -# ] + +from sklearn.ensemble import RandomForestRegressor +from econml.dml import LinearDML, CausalForestDML + # ############################################################################# # Agent # ############################################################################# + class Agent: """ Agent representing an individual in the simulation. - Each agent has four characteristics that define their position in the system: - - 1. Intensity (0-1): Activity level and effort. - - How active the agent is in seeking opportunities and experiences. - - Higher intensity → higher probability of encountering events (both good and bad). - - Think of it as "surface area for luck": more active people encounter more events. - - Influences event exposure probability via sigmoid function. - - 2. IQ (0-1): Ability to capitalize on opportunities. - - When a lucky event occurs, IQ determines if the agent successfully exploits it. - - Does NOT create opportunities, only gates whether they can be converted to gains. - - Unlucky events always apply (no IQ gate). - - Used as probability of capitalizing on beneficial events. - - 3. Networking (0-1): Social connectivity and spillover. - - Represents social connections and access to network effects. - - When an agent benefits from a lucky event, there's a chance (10%) that - a connected agent also benefits (at reduced impact: 50% of original). - - Spillover amount weighted by networking score. - - 4. Initial Capital: Starting wealth. - - Set to 1.0 for all agents in baseline simulation. - - This ensures inequality EMERGES from dynamics, not inherited advantages. - - Minimum enforced: 0.01 (prevent collapse to zero). + Each agent has four characteristics that define their position in the system. + + 1. **Intensity** (0-1) captures activity level and effort. It controls how + active the agent is in seeking opportunities and experiences. Higher + intensity leads to a higher probability of encountering events, both good + and bad. Think of it as "surface area for luck." The event exposure + probability is computed from intensity via a sigmoid function. + + 2. **IQ** (0-1) measures the ability to capitalize on opportunities. When a + lucky event occurs, IQ determines whether the agent successfully exploits + it. IQ does not create opportunities on its own; it only gates whether + they can be converted into gains. Unlucky events always apply regardless + of IQ. + + 3. **Networking** (0-1) represents social connectivity and spillover. It + measures social connections and access to network effects. When an agent + benefits from a lucky event there is a 10% chance that a connected agent + also benefits at 50% of the original impact, weighted by the networking + score. + + 4. **Initial Capital** is the starting wealth level. It is set to 1.0 for + all agents in the baseline simulation so that inequality emerges from + dynamics rather than inherited advantages. A minimum of 0.01 is enforced + to prevent collapse to zero. """ def __init__( @@ -150,6 +136,9 @@ def apply_event(self, event_type: str, impact: float) -> None: raise ValueError(f"Unknown event type: {event_type}") self.capital_history.append(self.capital) + +# ############################################################################# +# Population and metrics # ############################################################################# @@ -182,7 +171,9 @@ def calculate_gini(values: np.ndarray) -> float: :return: Gini coefficient in [0, 1] """ x = np.asarray(values, dtype=float) - hdbg.dassert_lt(0, x.size, "Cannot calculate Gini coefficient for empty array") + hdbg.dassert_lt( + 0, x.size, "Cannot calculate Gini coefficient for empty array" + ) hdbg.dassert( not np.any(x < 0), "Gini coefficient requires non-negative values", @@ -298,9 +289,7 @@ def validate_simulation_results(agents: List[Agent]) -> bool: """ df = get_results_dataframe(agents) hdbg.dassert(not df.empty, "No agents provided to validate") - hdbg.dassert( - not (df["capital"] < 0).any(), "Negative capital detected" - ) + hdbg.dassert(not (df["capital"] < 0).any(), "Negative capital detected") hdbg.dassert(not df.isnull().any().any(), "NaN values detected") hdbg.dassert( not ((df["lucky_events"] < 0).any() or (df["unlucky_events"] < 0).any()), @@ -428,36 +417,19 @@ def run_policy_simulation( """ Allocate initial resources under a policy, then run the standard simulation. - 1. "egalitarian" - - Every agent gets: resource_amount / n_agents - - Rationale: Reduce initial inequality, give everyone equal chance - - Typical outcome: Lowest final Gini (most equitable) - - Typical outcome: Moderate total welfare - - 2. "meritocratic" - - Allocation ∝ talent_norm (total ability) - - Rationale: Reward potentially capable people - - Typical outcome: Moderate final Gini - - Typical outcome: High total welfare (resources go to productive people) - - 3. "performance" - - Allocation ∝ current capital (rich get richer) - - Rationale: Compound success (controversial, tested for comparison) - - Typical outcome: Highest final Gini (most unequal) - - Typical outcome: Lowest total welfare (resources wasted on already-rich) - - 4. "random" - - One randomly chosen agent gets ALL resources - - Rationale: Extreme luck-based allocation - - Typical outcome: Very high Gini - - Typical outcome: Highest possible total welfare (concentrated resources) - - 5. "cate_optimal" - - Allocation ∝ CATE estimates (heterogeneous treatment effects) - - Rationale: Give resources to agents who benefit most from them - - Requires: cate_values array with one value per agent - - Typical outcome: High total welfare, moderate Gini - - Note: Only allocates to agents with non-negative CATE + Five policies are supported. **"egalitarian"** gives every agent an equal + share of resource_amount / n_agents, aiming to reduce initial inequality. + It typically produces the lowest final Gini and moderate total welfare. + **"meritocratic"** allocates proportionally to talent_norm (total ability), + rewarding potentially capable agents. This tends to yield moderate Gini and + high total welfare. **"performance"** allocates proportionally to current + capital (rich get richer). It is included for comparison and typically + produces the highest Gini and lowest total welfare. **"random"** gives all + resources to one randomly chosen agent, representing extreme luck-based + allocation with very high Gini. **"cate_optimal"** allocates proportionally + to CATE estimates so that resources go to agents who benefit most. It + requires a cate_values array with one value per agent and only allocates to + agents with non-negative CATE. :param agents: List of Agent objects (capital modified in-place) :param policy: Allocation rule: "egalitarian", "meritocratic", "performance", @@ -491,7 +463,9 @@ def run_policy_simulation( weights = np.array([a.capital for a in agents], dtype=float) elif policy == "cate_optimal": hdbg.dassert_is_not( - cate_values, None, "cate_values must be provided when policy='cate_optimal'." + cate_values, + None, + "cate_values must be provided when policy='cate_optimal'.", ) cate_array = np.asarray(cate_values, dtype=float) hdbg.dassert_eq( @@ -522,10 +496,57 @@ def run_policy_simulation( return run_simulation(agents, **simulation_kwargs) +def run_policy_and_measure( + policy_name: str, + *, + n_agents: int = 20, + resource_amount: float = 20.0, + n_periods: int = 10, + seed: int = 123, + cate_values: Optional[np.ndarray] = None, +) -> Tuple[pd.DataFrame, float]: + """ + Create a population, allocate resources under a policy, simulate, and + return the results DataFrame together with the Gini coefficient. + + This is a convenience wrapper that combines create_population, + run_policy_simulation, get_results_dataframe, and calculate_gini into a + single call. + + :param policy_name: allocation rule (see run_policy_simulation for options) + :param n_agents: number of agents to create (default 20) + :param resource_amount: total budget to distribute at t=0 (default 20.0) + :param n_periods: simulation time periods (default 10) + :param seed: RNG seed for both population creation and simulation + :param cate_values: CATE array, required when policy_name="cate_optimal" + :return: Tuple (df, gini) where df is the DataFrame with agent attributes + and final outcomes and gini is the Gini coefficient of the final + capital distribution + """ + agents = create_population(n_agents=n_agents, seed=seed) + kwargs: Dict[str, Any] = dict( + agents=agents, + policy=policy_name, + resource_amount=resource_amount, + n_periods=n_periods, + seed=seed, + ) + if policy_name == "cate_optimal": + hdbg.dassert_is_not( + cate_values, + None, + "cate_values must be provided for 'cate_optimal'.", + ) + kwargs["cate_values"] = cate_values + agents = run_policy_simulation(**kwargs) + df = get_results_dataframe(agents) + gini = calculate_gini(df["capital"].values) + return df, gini + + # ############################################################################# # Bayesian model # ############################################################################# -# ------------------------------------------------------------------- def fit_bayesian_luck_model( @@ -549,10 +570,10 @@ def fit_bayesian_luck_model( Valid range: (0.5, 1.0), higher = slower but more stable :param random_seed: RNG seed for reproducibility (default 42) - :return: Tuple (model, idata): - - model: PyMC Model object (for diagnostics, re-sampling, etc.) - - idata: ArviZ InferenceData object containing posterior samples - Use with summarize_bayesian_fit() or posterior_predictive_check() + :return: Tuple (model, idata) where model is the PyMC Model object (for + diagnostics and re-sampling) and idata is the ArviZ InferenceData + object containing posterior samples, suitable for use with + summarize_bayesian_fit() or posterior_predictive_check() """ required_cols = [ "capital", @@ -594,7 +615,7 @@ def fit_bayesian_luck_model( # PRIORS # ====== # All coefficients use weakly informative N(0, 1) priors (centered at 0). - #This allows the data to dominate the inference without strong prior beliefs. + # This allows the data to dominate the inference without strong prior beliefs. with pm.Model() as model: # Priors: fairly weakly informative, centered at 0. alpha = pm.Normal("alpha", mu=0.0, sigma=1.0) @@ -665,10 +686,9 @@ def posterior_predictive_check( :param idata: ArviZ InferenceData with posterior draws :param df: same DataFrame used for fitting :param random_seed: RNG seed for reproducibility - :return: dict with: - - "y_obs": observed log-capital - - "y_pred_mean": posterior predictive mean log-capital per agent - - "y_pred_std": posterior predictive std-dev per agent + :return: dict with keys "y_obs" (observed log-capital), "y_pred_mean" + (posterior predictive mean log-capital per agent), and "y_pred_std" + (posterior predictive standard deviation per agent) """ capital = df["capital"].to_numpy(dtype=float) y_obs = np.log(capital) @@ -696,3 +716,176 @@ def posterior_predictive_check( "y_pred_mean": y_pred_mean, "y_pred_std": y_pred_std, } + + +# ############################################################################# +# Causal inference +# ############################################################################# + + +def fit_dml_model( + df: pd.DataFrame, + *, + n_estimators: int = 100, + max_depth: int = 10, + random_state: int = 42, +) -> Tuple[Any, np.ndarray, float, float]: + """ + Fit a Double Machine Learning model to estimate the causal effect of luck. + + Uses LinearDML from EconML with Random Forest nuisance models to estimate + the average treatment effect of beneficial events on log-capital, controlling + for talent confounders. + + :param df: DataFrame from get_results_dataframe(agents), must have: + 'capital', 'lucky_events', 'talent_intensity', 'talent_iq', + 'talent_networking' + :param n_estimators: number of trees in RF nuisance models (default 100) + :param max_depth: max depth of RF nuisance models (default 10) + :param random_state: RNG seed for reproducibility (default 42) + :return: Tuple (dml_model, ate_estimates, ate_mean, ate_std) where + dml_model is the fitted LinearDML model object, ate_estimates is a + 1D array of per-agent ATE estimates, ate_mean is the mean ATE across + agents, and ate_std is the standard deviation of ATE across agents + """ + Y = np.log(df["capital"].values + 1) + T = df["lucky_events"].values + X = df[["talent_intensity", "talent_iq", "talent_networking"]].values + dml_model = LinearDML( + model_y=RandomForestRegressor( + n_estimators=n_estimators, + max_depth=max_depth, + random_state=random_state, + ), + model_t=RandomForestRegressor( + n_estimators=n_estimators, + max_depth=max_depth, + random_state=random_state, + ), + discrete_treatment=False, + random_state=random_state, + ) + dml_model.fit(Y, T, X=X) + ate_estimates = dml_model.const_marginal_effect(X) + ate_mean = float(ate_estimates.mean()) + ate_std = float(ate_estimates.std()) + return dml_model, ate_estimates, ate_mean, ate_std + + +def fit_causal_forest( + df: pd.DataFrame, + *, + n_estimators: int = 100, + max_depth: int = 10, + random_state: int = 42, +) -> Tuple[Any, np.ndarray]: + """ + Fit a Causal Forest to estimate heterogeneous treatment effects (CATE). + + Uses CausalForestDML from EconML to estimate per-agent conditional average + treatment effects of beneficial events on log-capital. + + :param df: DataFrame from get_results_dataframe(agents), must have: + 'capital', 'lucky_events', 'talent_intensity', 'talent_iq', + 'talent_networking' + :param n_estimators: number of trees (default 100) + :param max_depth: max depth of trees (default 10) + :param random_state: RNG seed for reproducibility (default 42) + :return: Tuple (cf_model, cate_estimates) where cf_model is the fitted + CausalForestDML model object and cate_estimates is a 1D array of + per-agent CATE estimates + """ + Y = np.log(df["capital"].values + 1) + T = df["lucky_events"].values + X = df[["talent_intensity", "talent_iq", "talent_networking"]].values + cf_model = CausalForestDML( + model_y=RandomForestRegressor( + n_estimators=n_estimators, + max_depth=max_depth, + random_state=random_state, + ), + model_t=RandomForestRegressor( + n_estimators=n_estimators, + max_depth=max_depth, + random_state=random_state, + ), + discrete_treatment=False, + n_estimators=n_estimators, + max_depth=max_depth, + random_state=random_state, + ) + cf_model.fit(Y, T, X=X) + cate_estimates = cf_model.effect(X) + return cf_model, cate_estimates + + +def compare_allocation_policies( + df: pd.DataFrame, + *, + budget_per_agent: float = 1.0, +) -> pd.DataFrame: + """ + Evaluate multiple resource allocation strategies and compare outcomes. + + Given a population with existing capital and CATE estimates, distributes a + fixed budget under five policies and measures resulting welfare and inequality. + + Policies: + 1. Egalitarian: equal allocation to all agents. + 2. Meritocratic: proportional to sum of talent dimensions. + 3. Random: random weights. + 4. Winner-Take-More: proportional to current capital. + 5. CATE-Optimal: proportional to estimated treatment effects. + + :param df: DataFrame with columns 'capital', 'talent_intensity', 'talent_iq', + 'talent_networking', and 'cate' + :param budget_per_agent: budget per agent to allocate (default 1.0) + :return: DataFrame with one row per policy and columns for welfare/inequality + metrics (Total Capital, Mean Capital, Median Capital, + Gini Coefficient, Top 10% Share, Bottom 50% Share) + """ + n_agents = len(df) + budget = n_agents * budget_per_agent + baseline_capital = df["capital"].values + policies: Dict[str, np.ndarray] = {} + # Policy 1: Egalitarian. + policies["Egalitarian"] = np.ones(n_agents) * (budget / n_agents) + # Policy 2: Meritocratic (proportional to talent). + talent_scores = ( + df[["talent_intensity", "talent_iq", "talent_networking"]] + .sum(axis=1) + .values + ) + talent_scores = np.maximum(talent_scores, 0.01) + policies["Meritocratic"] = budget * (talent_scores / talent_scores.sum()) + # Policy 3: Random. + random_weights = np.random.random(n_agents) + policies["Random"] = budget * (random_weights / random_weights.sum()) + # Policy 4: Success-based (proportional to current capital). + policies["Winner-Take-More"] = budget * ( + baseline_capital / baseline_capital.sum() + ) + # Policy 5: CATE-optimal (proportional to treatment effect estimates). + cate_positive = np.maximum(df["cate"].values, 0.01) + policies["CATE-Optimal"] = budget * (cate_positive / cate_positive.sum()) + results: List[Dict[str, Any]] = [] + for policy_name, allocation in policies.items(): + returns = np.sqrt(allocation) + new_capital = baseline_capital + returns + gini_coef = calculate_gini(new_capital) + results.append( + { + "Policy": policy_name, + "Total Capital": new_capital.sum(), + "Mean Capital": new_capital.mean(), + "Median Capital": float(np.median(new_capital)), + "Gini Coefficient": gini_coef, + "Top 10% Share": new_capital[np.argsort(new_capital)[-10:]].sum() + / new_capital.sum(), + "Bottom 50% Share": new_capital[ + np.argsort(new_capital)[:50] + ].sum() + / new_capital.sum(), + } + ) + return pd.DataFrame(results) diff --git a/research/A_Causal_Analysis_of_Success_in_Modern_Society/conftest.py b/research/A_Causal_Analysis_of_Success_in_Modern_Society/conftest.py new file mode 100644 index 000000000..ca627d639 --- /dev/null +++ b/research/A_Causal_Analysis_of_Success_in_Modern_Society/conftest.py @@ -0,0 +1,14 @@ +""" +Configure pytensor to use Python backend to avoid C compilation issues on macOS. +""" + +import platform + +# Disable C compilation to avoid linker errors on macOS with ld64. +if platform.system() == "Darwin": + try: + import pytensor + + pytensor.config.cxx = "" + except ImportError: + pass diff --git a/research/A_Causal_Analysis_of_Success_in_Modern_Society/docker_bash.sh b/research/A_Causal_Analysis_of_Success_in_Modern_Society/docker_bash.sh index e8af65fbf..0025e81f4 100755 --- a/research/A_Causal_Analysis_of_Success_in_Modern_Society/docker_bash.sh +++ b/research/A_Causal_Analysis_of_Success_in_Modern_Society/docker_bash.sh @@ -7,13 +7,13 @@ # Exit immediately if any command exits with a non-zero status. set -e -# Print each command to stdout before executing it. -set -x - # Import the utility functions from the project template. GIT_ROOT=$(git rev-parse --show-toplevel) source $GIT_ROOT/class_project/project_template/utils.sh +# Parse default args (-h, -v) and enable set -x if -v is passed. +parse_default_args "$@" + # Load Docker configuration variables for this script. get_docker_vars_script ${BASH_SOURCE[0]} source $DOCKER_NAME @@ -26,14 +26,9 @@ run "docker image ls $FULL_IMAGE_NAME" # - Container is removed automatically on exit (--rm) # - Interactive mode with TTY allocation (-ti) # - Port forwarding for Jupyter or other services -# - Current directory mounted to /data inside container +# - Git root mounted to /git_root inside container CONTAINER_NAME=${IMAGE_NAME}_bash -PORT=8889 -cmd="docker run --rm -ti \ - --name $CONTAINER_NAME \ - -p $PORT:$PORT \ - -v $(pwd):/data \ - -v $GIT_ROOT:/git_root \ - -e PYTHONPATH=/git_root:/git_root/helpers_root \ - $FULL_IMAGE_NAME" -run $cmd +PORT= +DOCKER_CMD=$(get_docker_bash_command) +DOCKER_CMD_OPTS=$(get_docker_bash_options $CONTAINER_NAME $PORT) +run "$DOCKER_CMD $DOCKER_CMD_OPTS $FULL_IMAGE_NAME" diff --git a/research/A_Causal_Analysis_of_Success_in_Modern_Society/docker_build.sh b/research/A_Causal_Analysis_of_Success_in_Modern_Society/docker_build.sh index e36e25824..5b0957a99 100755 --- a/research/A_Causal_Analysis_of_Success_in_Modern_Society/docker_build.sh +++ b/research/A_Causal_Analysis_of_Success_in_Modern_Society/docker_build.sh @@ -12,13 +12,15 @@ # Exit immediately if any command exits with a non-zero status. set -e -# Print each command to stdout before executing it. -set -x - # Import the utility functions. GIT_ROOT=$(git rev-parse --show-toplevel) source $GIT_ROOT/class_project/project_template/utils.sh +# Parse default args (-h, -v) and enable set -x if -v is passed. +# Shift processed option flags so remaining args are passed to the build. +parse_default_args "$@" +shift $((OPTIND-1)) + # Load Docker configuration variables (REPO_NAME, IMAGE_NAME, FULL_IMAGE_NAME). get_docker_vars_script ${BASH_SOURCE[0]} source $DOCKER_NAME @@ -34,6 +36,5 @@ export DOCKER_BUILDKIT=1 export DOCKER_BUILD_MULTI_ARCH=0 # Build the container image. -# Uncomment the line below to build without using Docker cache. -#build_container_image --no-cache -build_container_image +# Pass extra arguments (e.g., --no-cache) via command line after -v. +build_container_image "$@" diff --git a/research/A_Causal_Analysis_of_Success_in_Modern_Society/docker_clean.sh b/research/A_Causal_Analysis_of_Success_in_Modern_Society/docker_clean.sh index 4519e6c00..7e40839ae 100755 --- a/research/A_Causal_Analysis_of_Success_in_Modern_Society/docker_clean.sh +++ b/research/A_Causal_Analysis_of_Success_in_Modern_Society/docker_clean.sh @@ -10,13 +10,13 @@ # Exit immediately if any command exits with a non-zero status. set -e -# Print each command to stdout before executing it. -set -x - # Import the utility functions. GIT_ROOT=$(git rev-parse --show-toplevel) source $GIT_ROOT/class_project/project_template/utils.sh +# Parse default args (-h, -v) and enable set -x if -v is passed. +parse_default_args "$@" + # Load Docker configuration variables for this script. get_docker_vars_script ${BASH_SOURCE[0]} source $DOCKER_NAME diff --git a/research/A_Causal_Analysis_of_Success_in_Modern_Society/docker_cmd.sh b/research/A_Causal_Analysis_of_Success_in_Modern_Society/docker_cmd.sh index a471a5ee9..906d7a77b 100755 --- a/research/A_Causal_Analysis_of_Success_in_Modern_Society/docker_cmd.sh +++ b/research/A_Causal_Analysis_of_Success_in_Modern_Society/docker_cmd.sh @@ -1,24 +1,28 @@ -#!/bin/bash -e +#!/bin/bash # """ # Execute a command in a Docker container. # # This script runs a specified command inside a new Docker container instance. # The container is removed automatically after the command completes. The -# current directory is mounted to /data inside the container. +# git root is mounted to /git_root inside the container. # """ # Exit immediately if any command exits with a non-zero status. set -e -#set -x - -# Capture the command to execute from command-line arguments. -CMD="$@" -echo "Executing: '$CMD'" # Import the utility functions. GIT_ROOT=$(git rev-parse --show-toplevel) source $GIT_ROOT/class_project/project_template/utils.sh +# Parse default args (-h, -v) and enable set -x if -v is passed. +# Shift processed option flags so remaining args form the command. +parse_default_args "$@" +shift $((OPTIND-1)) + +# Capture the command to execute from remaining arguments. +CMD="$@" +echo "Executing: '$CMD'" + # Load Docker configuration variables for this script. get_docker_vars_script ${BASH_SOURCE[0]} source $DOCKER_NAME @@ -29,12 +33,9 @@ run "docker image ls $FULL_IMAGE_NAME" #(docker manifest inspect $FULL_IMAGE_NAME | grep arch) || true # Configure and run the Docker container with the specified command. -DOCKER_RUN_OPTS="" CONTAINER_NAME=$IMAGE_NAME -run "docker run \ - --rm -ti \ - --name $CONTAINER_NAME \ - $DOCKER_RUN_OPTS \ - -v $(pwd):/data \ - $FULL_IMAGE_NAME \ - bash -c '$CMD'" +DOCKER_CMD=$(get_docker_cmd_command) +PORT="" +DOCKER_RUN_OPTS="" +DOCKER_CMD_OPTS=$(get_docker_bash_options $CONTAINER_NAME $PORT $DOCKER_RUN_OPTS) +run "$DOCKER_CMD $DOCKER_CMD_OPTS $FULL_IMAGE_NAME bash -c '$CMD'" diff --git a/research/A_Causal_Analysis_of_Success_in_Modern_Society/docker_exec.sh b/research/A_Causal_Analysis_of_Success_in_Modern_Society/docker_exec.sh index 843b1c0f8..24f8e401a 100755 --- a/research/A_Causal_Analysis_of_Success_in_Modern_Society/docker_exec.sh +++ b/research/A_Causal_Analysis_of_Success_in_Modern_Society/docker_exec.sh @@ -9,13 +9,13 @@ # Exit immediately if any command exits with a non-zero status. set -e -# Print each command to stdout before executing it. -set -x - # Import the utility functions. GIT_ROOT=$(git rev-parse --show-toplevel) source $GIT_ROOT/class_project/project_template/utils.sh +# Parse default args (-h, -v) and enable set -x if -v is passed. +parse_default_args "$@" + # Load Docker configuration variables for this script. get_docker_vars_script ${BASH_SOURCE[0]} source $DOCKER_NAME diff --git a/research/A_Causal_Analysis_of_Success_in_Modern_Society/docker_jupyter.sh b/research/A_Causal_Analysis_of_Success_in_Modern_Society/docker_jupyter.sh index d678ae430..014cb773e 100755 --- a/research/A_Causal_Analysis_of_Success_in_Modern_Society/docker_jupyter.sh +++ b/research/A_Causal_Analysis_of_Success_in_Modern_Society/docker_jupyter.sh @@ -2,73 +2,42 @@ # """ # Execute Jupyter Lab in a Docker container. # -# This script launches a Docker container running Jupyter Lab with configurable -# port, directory mounting, and vim bindings. It passes command-line options to -# the run_jupyter.sh script inside the container. +# This script launches a Docker container running Jupyter Lab with +# configurable port, directory mounting, and vim bindings. It passes +# command-line options to the run_jupyter.sh script inside the container. # # Usage: -# > docker_jupyter.sh -d /path/to/notebooks -v -u -p 8889 +# > docker_jupyter.sh [options] # """ # Exit immediately if any command exits with a non-zero status. set -e -#set -x - -# Initialize default parameter values for Jupyter configuration. -export JUPYTER_HOST_PORT=8888 -export JUPYTER_USE_VIM=0 -export TARGET_DIR="" -TARGET_DIR=. -export VERBOSE=0 - -# Save original command-line options to pass through to run_jupyter.sh. -OLD_CMD_OPTS=$@ - -# Parse command-line options. -while getopts p:d:uv flag -do - case "${flag}" in - p) JUPYTER_HOST_PORT=${OPTARG};; # Port for Jupyter Lab - u) JUPYTER_USE_VIM=1;; # Enable vim bindings - d) TARGET_DIR=${OPTARG};; # Directory to mount as /data - v) VERBOSE=1;; # Enable verbose output - esac -done - -# Enable command tracing if verbose mode is requested. -if [[ $VERBOSE == 1 ]]; then - set -x -fi; # Import the utility functions. GIT_ROOT=$(git rev-parse --show-toplevel) +# Normalize Windows-style paths to MSYS/Unix form on Git Bash. +if command -v cygpath >/dev/null 2>&1; then + GIT_ROOT=$(cygpath -u "$GIT_ROOT") +fi source $GIT_ROOT/class_project/project_template/utils.sh +# Parse command-line options and set Jupyter configuration variables. +parse_docker_jupyter_args "$@" + # Load Docker configuration variables for this script. get_docker_vars_script ${BASH_SOURCE[0]} source $DOCKER_NAME print_docker_vars -# Configure Docker run options with port forwarding and optional volume mount. -DOCKER_RUN_OPTS="-p $JUPYTER_HOST_PORT:8888" -if [[ $TARGET_DIR != "" ]]; then - DOCKER_RUN_OPTS="$DOCKER_RUN_OPTS -v $TARGET_DIR:/data" -fi; -CMD="/curr_dir/run_jupyter.sh $OLD_CMD_OPTS" - # List available Docker images and inspect architecture. -run "docker image ls $FULL_IMAGE_NAME" -(docker manifest inspect $FULL_IMAGE_NAME | grep arch) || true +list_and_inspect_docker_image # Run the Docker container with Jupyter Lab. +CMD=$(get_run_jupyter_cmd "${BASH_SOURCE[0]}" "$OLD_CMD_OPTS") CONTAINER_NAME=$IMAGE_NAME -run "docker run \ - --rm -ti \ - --name $CONTAINER_NAME \ - $DOCKER_RUN_OPTS \ - -v $(pwd):/curr_dir \ - -v $GIT_ROOT:/git_root \ - -e PYTHONPATH=/git_root:/git_root/helpers_root \ - -e JUPYTER_USE_VIM=$JUPYTER_USE_VIM \ - $FULL_IMAGE_NAME \ - $CMD" +# Kill existing container if -f flag is set. +kill_existing_container_if_forced + +DOCKER_CMD=$(get_docker_jupyter_command) +DOCKER_CMD_OPTS=$(get_docker_jupyter_options $CONTAINER_NAME $JUPYTER_HOST_PORT $JUPYTER_USE_VIM) +run "$DOCKER_CMD $DOCKER_CMD_OPTS $FULL_IMAGE_NAME $CMD" diff --git a/research/A_Causal_Analysis_of_Success_in_Modern_Society/docker_push.sh b/research/A_Causal_Analysis_of_Success_in_Modern_Society/docker_push.sh index 8745194e9..27d752dd9 100755 --- a/research/A_Causal_Analysis_of_Success_in_Modern_Society/docker_push.sh +++ b/research/A_Causal_Analysis_of_Success_in_Modern_Society/docker_push.sh @@ -10,13 +10,13 @@ # Exit immediately if any command exits with a non-zero status. set -e -# Print each command to stdout before executing it. -set -x - # Import the utility functions. GIT_ROOT=$(git rev-parse --show-toplevel) source $GIT_ROOT/class_project/project_template/utils.sh +# Parse default args (-h, -v) and enable set -x if -v is passed. +parse_default_args "$@" + # Load Docker image naming configuration. SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source $SCRIPT_DIR/docker_name.sh diff --git a/research/A_Causal_Analysis_of_Success_in_Modern_Society/requirements.txt b/research/A_Causal_Analysis_of_Success_in_Modern_Society/requirements.txt index 1dba9d34d..c6523c4ed 100644 --- a/research/A_Causal_Analysis_of_Success_in_Modern_Society/requirements.txt +++ b/research/A_Causal_Analysis_of_Success_in_Modern_Society/requirements.txt @@ -1,13 +1,22 @@ -arviz==0.18.0 -econml -jupyterlab -jupyterlab-vim -matplotlib -numpy -pandas +# Core scientific computing. +numpy==1.26.4 +pandas==2.2.3 +scipy==1.14.1 + +# Visualization. +matplotlib==3.9.3 +seaborn==0.13.2 + +# Machine learning. +scikit-learn==1.6.0 +statsmodels==0.14.4 + +# Causal inference. +econml==0.16.0 + +# Bayesian inference. pymc==5.16.2 -scikit-learn -scipy -seaborn -statsmodels -tqdm +arviz==0.18.0 + +# Utilities. +tqdm==4.67.1 diff --git a/research/A_Causal_Analysis_of_Success_in_Modern_Society/run_jupyter.sh b/research/A_Causal_Analysis_of_Success_in_Modern_Society/run_jupyter.sh index 0e4e5ab60..d725c3fe7 100755 --- a/research/A_Causal_Analysis_of_Success_in_Modern_Society/run_jupyter.sh +++ b/research/A_Causal_Analysis_of_Success_in_Modern_Society/run_jupyter.sh @@ -1,4 +1,4 @@ -#!/bin/bash -xe +#!/bin/bash # """ # Launch Jupyter Lab server. # @@ -10,60 +10,26 @@ # - Vim keybindings can be enabled via JUPYTER_USE_VIM environment variable # """ -mkdir -p ~/.jupyter/lab/user-settings/@axlair/jupyterlab_vim -if [[ $JUPYTER_USE_VIM == 1 ]]; then - echo "Enabling vim." - cat < ~/.jupyter/lab/user-settings/\@axlair/jupyterlab_vim/plugin.jupyterlab-settings -{ - "enabled": true, - "enabledInEditors": true, - "extraKeybindings": [] -} -EOF -else - echo "Disabling vim." - cat < ~/.jupyter/lab/user-settings/\@axlair/jupyterlab_vim/plugin.jupyterlab-settings -{ - "enabled": false, - "enabledInEditors": false, - "extraKeybindings": [] -} -EOF -fi; +# Exit immediately if any command exits with a non-zero status. +set -e -mkdir -p ~/.jupyter/lab/user-settings/@jupyterlab/apputils-extension -cat < ~/.jupyter/lab/user-settings/\@jupyterlab/apputils-extension/notification.jupyterlab-settings -{ - // Notifications - // @jupyterlab/apputils-extension:notification - // Notifications settings. +# Print each command to stdout before executing it. +#set -x - // Fetch official Jupyter news - // Whether to fetch news from the Jupyter news feed. If Always (`true`), it will make a request to a website. - "fetchNews": "false", - "checkForUpdates": false -} -EOF +# Import the utility functions from /git_root. +GIT_ROOT=/git_root +source $GIT_ROOT/class_project/project_template/utils.sh -# Initialize Jupyter Lab command with base configuration. -JUPYTER_ARGS=( - "--port=8888" - "--no-browser" - "--ip=0.0.0.0" - "--allow-root" - "--ServerApp.token=''" - "--ServerApp.password=''" -) +# Load Docker configuration variables for this script. +get_docker_vars_script ${BASH_SOURCE[0]} +source $DOCKER_NAME +print_docker_vars -# Note: jupyterlab-vim extension can be disabled via JupyterLab settings if needed. +# Setup Jupyter Lab environment. +setup_jupyter_environment -# Start Jupyter Lab with development-friendly settings. -jupyter lab "${JUPYTER_ARGS[@]}" +# Initialize Jupyter Lab command with base configuration. +JUPYTER_ARGS=$(get_jupyter_args) -# Alternative: Use classic Jupyter Notebook instead of Jupyter Lab. -#jupyter-notebook \ -# --port=8888 \ -# --no-browser --ip=0.0.0.0 \ -# --allow-root \ -# --NotebookApp.token='' \ -# --NotebookApp.password='' +# Start Jupyter Lab with development-friendly settings. +run "jupyter lab $JUPYTER_ARGS" diff --git a/research/A_Causal_Analysis_of_Success_in_Modern_Society/test/test_docker_all.py b/research/A_Causal_Analysis_of_Success_in_Modern_Society/test/test_docker_all.py new file mode 100644 index 000000000..1a779a8d4 --- /dev/null +++ b/research/A_Causal_Analysis_of_Success_in_Modern_Society/test/test_docker_all.py @@ -0,0 +1,48 @@ +""" +Run each notebook in research/A_Causal_Analysis_of_Success_in_Modern_Society/ inside Docker using docker_cmd.sh. + +Import as: + +import research.A_Causal_Analysis_of_Success_in_Modern_Society.test.test_docker_all as racaosimstda +""" + +import logging + +import pytest + +import helpers.hdocker_tests as hdoctest + +_LOG = logging.getLogger(__name__) + + +# ############################################################################# +# Test_docker +# ############################################################################# + + +class Test_docker(hdoctest.DockerTestCase): + """ + Run all Docker tests for research/A_Causal_Analysis_of_Success_in_Modern_Society/. + """ + + _test_file = __file__ + + @pytest.mark.slow + def test1(self) -> None: + """ + Test that causal_success.example.ipynb runs without error inside Docker. + """ + # Prepare inputs. + notebook_name = "causal_success.example.ipynb" + # Run test. + self._helper(notebook_name) + + @pytest.mark.slow + def test2(self) -> None: + """ + Test that causal_success.API.ipynb runs without error inside Docker. + """ + # Prepare inputs. + notebook_name = "causal_success.API.ipynb" + # Run test. + self._helper(notebook_name) diff --git a/research/A_Causal_Analysis_of_Success_in_Modern_Society/test_causal_success_utils.py b/research/A_Causal_Analysis_of_Success_in_Modern_Society/test_causal_success_utils.py index 4a0bd1f9a..8730c13c8 100644 --- a/research/A_Causal_Analysis_of_Success_in_Modern_Society/test_causal_success_utils.py +++ b/research/A_Causal_Analysis_of_Success_in_Modern_Society/test_causal_success_utils.py @@ -3,7 +3,7 @@ Import as: -import research.A_Causal_Analysis_of_Success_in_Modern_Society.test_causal_success_utils as tcsu +import research.A_Causal_Analysis_of_Success_in_Modern_Society.test_causal_success_utils as racaosimstcsu """ import logging @@ -11,7 +11,7 @@ import numpy as np import helpers.hunit_test as hunitest -import research.A_Causal_Analysis_of_Success_in_Modern_Society.causal_success_utils as csu +import research.A_Causal_Analysis_of_Success_in_Modern_Society.causal_success_utils as racaosimscsu _LOG = logging.getLogger(__name__) @@ -36,7 +36,7 @@ def test1(self) -> None: iq = 0.6 networking = 0.7 # Run test. - agent = csu.Agent(agent_id, intensity, iq, networking) + agent = racaosimscsu.Agent(agent_id, intensity, iq, networking) # Check outputs. self.assertEqual(agent.id, 0) self.assertAlmostEqual(agent.capital, 1.0) @@ -55,7 +55,7 @@ def test2(self) -> None: networking = 0.5 initial_capital = 5.0 # Run test. - agent = csu.Agent( + agent = racaosimscsu.Agent( agent_id, intensity, iq, networking, initial_capital=initial_capital ) # Check outputs. @@ -72,7 +72,7 @@ def test3(self) -> None: iq = -0.5 networking = 0.5 # Run test. - agent = csu.Agent(agent_id, intensity, iq, networking) + agent = racaosimscsu.Agent(agent_id, intensity, iq, networking) # Check outputs. self.assertAlmostEqual(agent.talent["intensity"], 1.0) self.assertAlmostEqual(agent.talent["iq"], 0.0) @@ -89,13 +89,18 @@ def test4(self) -> None: networking = 0.5 initial_capital = 0.001 # Run test. - agent = csu.Agent( + agent = racaosimscsu.Agent( agent_id, intensity, iq, networking, initial_capital=initial_capital ) # Check outputs. self.assertAlmostEqual(agent.capital, 0.01) +# ############################################################################# +# Test_talent_norm +# ############################################################################# + + class Test_talent_norm(hunitest.TestCase): """ Test the talent_norm property of Agent class. @@ -106,7 +111,7 @@ def test1(self) -> None: Test talent_norm returns correct Euclidean norm of talent vector. """ # Prepare inputs. - agent = csu.Agent(0, 0.3, 0.4, 0.5, initial_capital=1.2) + agent = racaosimscsu.Agent(0, 0.3, 0.4, 0.5, initial_capital=1.2) # Run test. norm = agent.talent_norm # Check outputs. @@ -118,7 +123,7 @@ def test2(self) -> None: Test talent_norm with all talents equal to 0.5. """ # Prepare inputs. - agent = csu.Agent(0, 0.5, 0.5, 0.5, initial_capital=0.5) + agent = racaosimscsu.Agent(0, 0.5, 0.5, 0.5, initial_capital=0.5) # Run test. norm = agent.talent_norm # Check outputs. @@ -130,7 +135,7 @@ def test3(self) -> None: Test talent_norm with edge case values (0 and 1). """ # Prepare inputs. - agent = csu.Agent(0, 0.0, 1.0, 0.0, initial_capital=1.0) + agent = racaosimscsu.Agent(0, 0.0, 1.0, 0.0, initial_capital=1.0) # Run test. norm = agent.talent_norm # Check outputs. @@ -138,14 +143,17 @@ def test3(self) -> None: self.assertAlmostEqual(norm, expected, places=5) +# ############################################################################# +# Test_get_event_probability +# ############################################################################# + + class Test_get_event_probability(hunitest.TestCase): """ Test the get_event_probability method of Agent class. """ - def helper( - self, intensity_val: float, expected_range: tuple - ) -> None: + def helper(self, intensity_val: float, expected_range: tuple) -> None: """ Test helper for get_event_probability. @@ -153,7 +161,7 @@ def helper( :param expected_range: Tuple of (min, max) expected probability """ # Run test. - agent = csu.Agent(0, intensity_val, 0.5, 0.5) + agent = racaosimscsu.Agent(0, intensity_val, 0.5, 0.5) prob = agent.get_event_probability() # Check outputs. self.assertGreaterEqual(prob, expected_range[0]) @@ -166,7 +174,7 @@ def test1(self) -> None: # Prepare inputs. # At intensity=0.5, sigmoid should return 0.5 (midpoint of [0, 1]). # Run test. - agent = csu.Agent(0, 0.5, 0.5, 0.5) + agent = racaosimscsu.Agent(0, 0.5, 0.5, 0.5) prob = agent.get_event_probability() # Check outputs. self.assertAlmostEqual(prob, 0.5, places=2) @@ -196,12 +204,20 @@ def test4(self) -> None: # Prepare inputs. intensities = [0.0, 0.25, 0.5, 0.75, 1.0] # Run test. - probs = [csu.Agent(0, i, 0.5, 0.5).get_event_probability() for i in intensities] + probs = [ + racaosimscsu.Agent(0, i, 0.5, 0.5).get_event_probability() + for i in intensities + ] # Check outputs. for i in range(len(probs) - 1): self.assertLessEqual(probs[i], probs[i + 1]) +# ############################################################################# +# Test_apply_event +# ############################################################################# + + class Test_apply_event(hunitest.TestCase): """ Test the apply_event method of Agent class. @@ -212,7 +228,7 @@ def test1(self) -> None: Test applying a lucky event increases capital. """ # Prepare inputs. - agent = csu.Agent(0, 0.5, 0.5, 0.5, initial_capital=1.0) + agent = racaosimscsu.Agent(0, 0.5, 0.5, 0.5, initial_capital=1.0) impact = 0.25 # Run test. agent.apply_event("lucky", impact) @@ -224,7 +240,7 @@ def test2(self) -> None: Test applying an unlucky event decreases capital. """ # Prepare inputs. - agent = csu.Agent(0, 0.5, 0.5, 0.5, initial_capital=1.0) + agent = racaosimscsu.Agent(0, 0.5, 0.5, 0.5, initial_capital=1.0) impact = 0.15 # Run test. agent.apply_event("unlucky", impact) @@ -236,7 +252,7 @@ def test3(self) -> None: Test applying an unlucky event respects minimum capital floor (0.01). """ # Prepare inputs. - agent = csu.Agent(0, 0.5, 0.5, 0.5, initial_capital=0.05) + agent = racaosimscsu.Agent(0, 0.5, 0.5, 0.5, initial_capital=0.05) impact = 0.99 # Run test. agent.apply_event("unlucky", impact) @@ -248,7 +264,7 @@ def test4(self) -> None: Test applying an event increments the appropriate event counter. """ # Prepare inputs. - agent = csu.Agent(0, 0.5, 0.5, 0.5) + agent = racaosimscsu.Agent(0, 0.5, 0.5, 0.5) # Run test. agent.apply_event("lucky", 0.1) agent.apply_event("unlucky", 0.1) @@ -262,7 +278,7 @@ def test5(self) -> None: Test capital_history is updated after each event. """ # Prepare inputs. - agent = csu.Agent(0, 0.5, 0.5, 0.5, initial_capital=1.0) + agent = racaosimscsu.Agent(0, 0.5, 0.5, 0.5, initial_capital=1.0) # Run test. agent.apply_event("lucky", 0.25) agent.apply_event("unlucky", 0.1) @@ -277,7 +293,7 @@ def test6(self) -> None: Test apply_event raises error for invalid event_type. """ # Prepare inputs. - agent = csu.Agent(0, 0.5, 0.5, 0.5) + agent = racaosimscsu.Agent(0, 0.5, 0.5, 0.5) # Run test and check output. with self.assertRaises(ValueError): agent.apply_event("invalid", 0.1) @@ -287,7 +303,7 @@ def test7(self) -> None: Test negative impact magnitude is converted to absolute value. """ # Prepare inputs. - agent = csu.Agent(0, 0.5, 0.5, 0.5, initial_capital=1.0) + agent = racaosimscsu.Agent(0, 0.5, 0.5, 0.5, initial_capital=1.0) # Run test. agent.apply_event("lucky", -0.25) # Check outputs. @@ -311,7 +327,7 @@ def test1(self) -> None: # Prepare inputs. n_agents = 50 # Run test. - agents = csu.create_population(n_agents=n_agents, seed=42) + agents = racaosimscsu.create_population(n_agents=n_agents, seed=42) # Check outputs. self.assertEqual(len(agents), n_agents) @@ -322,7 +338,7 @@ def test2(self) -> None: # Prepare inputs. n_agents = 20 # Run test. - agents = csu.create_population(n_agents=n_agents, seed=42) + agents = racaosimscsu.create_population(n_agents=n_agents, seed=42) # Check outputs. for agent in agents: self.assertGreaterEqual(agent.talent["intensity"], 0.0) @@ -339,7 +355,7 @@ def test3(self) -> None: # Prepare inputs. n_agents = 15 # Run test. - agents = csu.create_population(n_agents=n_agents, seed=42) + agents = racaosimscsu.create_population(n_agents=n_agents, seed=42) # Check outputs. for agent in agents: self.assertAlmostEqual(agent.capital, 1.0) @@ -352,13 +368,17 @@ def test4(self) -> None: n_agents = 10 seed = 123 # Run test. - agents1 = csu.create_population(n_agents=n_agents, seed=seed) - agents2 = csu.create_population(n_agents=n_agents, seed=seed) + agents1 = racaosimscsu.create_population(n_agents=n_agents, seed=seed) + agents2 = racaosimscsu.create_population(n_agents=n_agents, seed=seed) # Check outputs. for a1, a2 in zip(agents1, agents2): - self.assertAlmostEqual(a1.talent["intensity"], a2.talent["intensity"]) + self.assertAlmostEqual( + a1.talent["intensity"], a2.talent["intensity"] + ) self.assertAlmostEqual(a1.talent["iq"], a2.talent["iq"]) - self.assertAlmostEqual(a1.talent["networking"], a2.talent["networking"]) + self.assertAlmostEqual( + a1.talent["networking"], a2.talent["networking"] + ) def test5(self) -> None: """ @@ -368,7 +388,7 @@ def test5(self) -> None: n_agents = 0 # Run test and check output. with self.assertRaises(AssertionError): - csu.create_population(n_agents=n_agents, seed=42) + racaosimscsu.create_population(n_agents=n_agents, seed=42) def test6(self) -> None: """ @@ -377,7 +397,7 @@ def test6(self) -> None: # Prepare inputs. n_agents = 25 # Run test. - agents = csu.create_population(n_agents=n_agents, seed=42) + agents = racaosimscsu.create_population(n_agents=n_agents, seed=42) # Check outputs. for i, agent in enumerate(agents): self.assertEqual(agent.id, i) @@ -401,7 +421,7 @@ def helper(self, values_arr: np.ndarray, expected_gini_val: float) -> None: :param expected_gini_val: Expected Gini coefficient """ # Run test. - gini = csu.calculate_gini(values_arr) + gini = racaosimscsu.calculate_gini(values_arr) # Check outputs. self.assertAlmostEqual(gini, expected_gini_val, places=3) @@ -423,7 +443,7 @@ def test2(self) -> None: # Prepare inputs. values = np.array([0.1, 0.1, 0.1, 100.0], dtype=float) # Run test. - gini = csu.calculate_gini(values) + gini = racaosimscsu.calculate_gini(values) # Check outputs. self.assertGreater(gini, 0.7) @@ -434,7 +454,7 @@ def test3(self) -> None: # Prepare inputs. values = np.array([1.0, 2.0, 3.0, 4.0, 5.0], dtype=float) # Run test. - gini = csu.calculate_gini(values) + gini = racaosimscsu.calculate_gini(values) # Check outputs. self.assertGreaterEqual(gini, 0.0) self.assertLessEqual(gini, 1.0) @@ -446,7 +466,7 @@ def test4(self) -> None: # Prepare inputs. values = np.array([5.0], dtype=float) # Run test. - gini = csu.calculate_gini(values) + gini = racaosimscsu.calculate_gini(values) # Check outputs. self.assertAlmostEqual(gini, 0.0) @@ -458,7 +478,7 @@ def test5(self) -> None: values = np.array([], dtype=float) # Run test and check output. with self.assertRaises(AssertionError): - csu.calculate_gini(values) + racaosimscsu.calculate_gini(values) def test6(self) -> None: """ @@ -468,7 +488,7 @@ def test6(self) -> None: values = np.array([1.0, 2.0, -1.0], dtype=float) # Run test and check output. with self.assertRaises(AssertionError): - csu.calculate_gini(values) + racaosimscsu.calculate_gini(values) def test7(self) -> None: """ @@ -477,7 +497,7 @@ def test7(self) -> None: # Prepare inputs. values = np.array([0.0, 0.0, 0.0], dtype=float) # Run test. - gini = csu.calculate_gini(values) + gini = racaosimscsu.calculate_gini(values) # Check outputs. self.assertAlmostEqual(gini, 0.0) @@ -497,9 +517,9 @@ def test1(self) -> None: Test get_results_dataframe converts agents to correct columns. """ # Prepare inputs. - agents = csu.create_population(n_agents=5, seed=42) + agents = racaosimscsu.create_population(n_agents=5, seed=42) # Run test. - df = csu.get_results_dataframe(agents) + df = racaosimscsu.get_results_dataframe(agents) # Check outputs. expected_cols = [ "id", @@ -522,7 +542,7 @@ def test2(self) -> None: # Prepare inputs. agents = [] # Run test. - df = csu.get_results_dataframe(agents) + df = racaosimscsu.get_results_dataframe(agents) # Check outputs. self.assertTrue(df.empty) @@ -531,12 +551,12 @@ def test3(self) -> None: Test get_results_dataframe computes net_events correctly. """ # Prepare inputs. - agent = csu.Agent(0, 0.5, 0.5, 0.5) + agent = racaosimscsu.Agent(0, 0.5, 0.5, 0.5) agent.apply_event("lucky", 0.1) agent.apply_event("lucky", 0.1) agent.apply_event("unlucky", 0.1) # Run test. - df = csu.get_results_dataframe([agent]) + df = racaosimscsu.get_results_dataframe([agent]) # Check outputs. net = df.iloc[0]["net_events"] self.assertEqual(net, 1) @@ -546,9 +566,9 @@ def test4(self) -> None: Test get_results_dataframe includes talent_norm computation. """ # Prepare inputs. - agents = csu.create_population(n_agents=3, seed=42) + agents = racaosimscsu.create_population(n_agents=3, seed=42) # Run test. - df = csu.get_results_dataframe(agents) + df = racaosimscsu.get_results_dataframe(agents) # Check outputs. for idx, agent in enumerate(agents): self.assertAlmostEqual( @@ -560,9 +580,9 @@ def test5(self) -> None: Test get_results_dataframe with single agent. """ # Prepare inputs. - agent = csu.Agent(0, 0.3, 0.4, 0.5, initial_capital=2.0) + agent = racaosimscsu.Agent(0, 0.3, 0.4, 0.5, initial_capital=2.0) # Run test. - df = csu.get_results_dataframe([agent]) + df = racaosimscsu.get_results_dataframe([agent]) # Check outputs. self.assertEqual(len(df), 1) self.assertEqual(df.iloc[0]["id"], 0) @@ -584,9 +604,9 @@ def test1(self) -> None: Test generate_summary_statistics returns correct keys. """ # Prepare inputs. - agents = csu.create_population(n_agents=10, seed=42) + agents = racaosimscsu.create_population(n_agents=10, seed=42) # Run test. - stats = csu.generate_summary_statistics(agents) + stats = racaosimscsu.generate_summary_statistics(agents) # Check outputs. expected_keys = [ "n_agents", @@ -611,9 +631,9 @@ def test2(self) -> None: Test generate_summary_statistics with single agent. """ # Prepare inputs. - agent = csu.Agent(0, 0.5, 0.5, 0.5, initial_capital=2.0) + agent = racaosimscsu.Agent(0, 0.5, 0.5, 0.5, initial_capital=2.0) # Run test. - stats = csu.generate_summary_statistics([agent]) + stats = racaosimscsu.generate_summary_statistics([agent]) # Check outputs. self.assertEqual(stats["n_agents"], 1.0) self.assertAlmostEqual(stats["mean_capital"], 2.0) @@ -627,7 +647,7 @@ def test3(self) -> None: # Prepare inputs. agents = [] # Run test. - stats = csu.generate_summary_statistics(agents) + stats = racaosimscsu.generate_summary_statistics(agents) # Check outputs. self.assertEqual(stats["n_agents"], 0) @@ -636,9 +656,9 @@ def test4(self) -> None: Test top_10_pct_share sums to approximately 1.0 portion. """ # Prepare inputs. - agents = csu.create_population(n_agents=100, seed=42) + agents = racaosimscsu.create_population(n_agents=100, seed=42) # Run test. - stats = csu.generate_summary_statistics(agents) + stats = racaosimscsu.generate_summary_statistics(agents) # Check outputs. total_share = ( stats["top_10_pct_share"] @@ -652,9 +672,12 @@ def test5(self) -> None: Test mean_capital equals median_capital for equal wealth. """ # Prepare inputs. - agents = [csu.Agent(i, 0.5, 0.5, 0.5, initial_capital=1.0) for i in range(10)] + agents = [ + racaosimscsu.Agent(i, 0.5, 0.5, 0.5, initial_capital=1.0) + for i in range(10) + ] # Run test. - stats = csu.generate_summary_statistics(agents) + stats = racaosimscsu.generate_summary_statistics(agents) # Check outputs. self.assertAlmostEqual(stats["mean_capital"], stats["median_capital"]) @@ -663,9 +686,9 @@ def test6(self) -> None: Test capital_range is positive. """ # Prepare inputs. - agents = csu.create_population(n_agents=20, seed=42) + agents = racaosimscsu.create_population(n_agents=20, seed=42) # Run test. - stats = csu.generate_summary_statistics(agents) + stats = racaosimscsu.generate_summary_statistics(agents) # Check outputs. self.assertGreater(stats["capital_range"], 0.0) @@ -685,9 +708,9 @@ def test1(self) -> None: Test validate_simulation_results returns True for valid agents. """ # Prepare inputs. - agents = csu.create_population(n_agents=10, seed=42) + agents = racaosimscsu.create_population(n_agents=10, seed=42) # Run test. - result = csu.validate_simulation_results(agents) + result = racaosimscsu.validate_simulation_results(agents) # Check outputs. self.assertTrue(result) @@ -699,41 +722,41 @@ def test2(self) -> None: agents = [] # Run test and check output. with self.assertRaises(AssertionError): - csu.validate_simulation_results(agents) + racaosimscsu.validate_simulation_results(agents) def test3(self) -> None: """ Test validate_simulation_results detects negative capital. """ # Prepare inputs. - agent = csu.Agent(0, 0.5, 0.5, 0.5, initial_capital=1.0) + agent = racaosimscsu.Agent(0, 0.5, 0.5, 0.5, initial_capital=1.0) agent.capital = -0.5 # Run test and check output. with self.assertRaises(AssertionError): - csu.validate_simulation_results([agent]) + racaosimscsu.validate_simulation_results([agent]) def test4(self) -> None: """ Test validate_simulation_results detects capital_history inconsistencies. """ # Prepare inputs. - agent = csu.Agent(0, 0.5, 0.5, 0.5) + agent = racaosimscsu.Agent(0, 0.5, 0.5, 0.5) agent.lucky_events = 5 # capital_history should have 6 entries (1 initial + 5 events) # but we'll leave it with 1. # Run test and check output. with self.assertRaises(AssertionError): - csu.validate_simulation_results([agent]) + racaosimscsu.validate_simulation_results([agent]) def test5(self) -> None: """ Test validate_simulation_results after simulations pass validation. """ # Prepare inputs. - agents = csu.create_population(n_agents=10, seed=42) - agents = csu.run_simulation(agents, n_periods=5, seed=42) + agents = racaosimscsu.create_population(n_agents=10, seed=42) + agents = racaosimscsu.run_simulation(agents, n_periods=5, seed=42) # Run test. - result = csu.validate_simulation_results(agents) + result = racaosimscsu.validate_simulation_results(agents) # Check outputs. self.assertTrue(result) @@ -753,22 +776,22 @@ def test1(self) -> None: Test run_simulation with default parameters. """ # Prepare inputs. - agents = csu.create_population(n_agents=10, seed=42) + agents = racaosimscsu.create_population(n_agents=10, seed=42) # Run test. - result = csu.run_simulation(agents, n_periods=10, seed=42) + result = racaosimscsu.run_simulation(agents, n_periods=10, seed=42) # Check outputs. self.assertEqual(result, agents) - self.assertTrue(csu.validate_simulation_results(agents)) + self.assertTrue(racaosimscsu.validate_simulation_results(agents)) def test2(self) -> None: """ Test run_simulation with zero events per period. """ # Prepare inputs. - agents = csu.create_population(n_agents=5, seed=42) + agents = racaosimscsu.create_population(n_agents=5, seed=42) initial_capitals = [a.capital for a in agents] # Run test. - csu.run_simulation( + racaosimscsu.run_simulation( agents, n_periods=10, n_lucky_events_per_period=0, @@ -785,12 +808,12 @@ def test3(self) -> None: Test run_simulation with seed produces reproducible results. """ # Prepare inputs. - agents1 = csu.create_population(n_agents=10, seed=42) - agents2 = csu.create_population(n_agents=10, seed=42) + agents1 = racaosimscsu.create_population(n_agents=10, seed=42) + agents2 = racaosimscsu.create_population(n_agents=10, seed=42) seed = 123 # Run test. - csu.run_simulation(agents1, n_periods=5, seed=seed) - csu.run_simulation(agents2, n_periods=5, seed=seed) + racaosimscsu.run_simulation(agents1, n_periods=5, seed=seed) + racaosimscsu.run_simulation(agents2, n_periods=5, seed=seed) # Check outputs. for a1, a2 in zip(agents1, agents2): self.assertAlmostEqual(a1.capital, a2.capital, places=5) @@ -800,10 +823,10 @@ def test4(self) -> None: Test run_simulation modifies agents in-place. """ # Prepare inputs. - agents = csu.create_population(n_agents=5, seed=42) + agents = racaosimscsu.create_population(n_agents=5, seed=42) agents_ref = agents # Run test. - result = csu.run_simulation(agents, n_periods=5, seed=42) + result = racaosimscsu.run_simulation(agents, n_periods=5, seed=42) # Check outputs. self.assertIs(result, agents_ref) @@ -812,9 +835,9 @@ def test5(self) -> None: Test run_simulation respects capital floor of 0.01. """ # Prepare inputs. - agents = csu.create_population(n_agents=10, seed=42) + agents = racaosimscsu.create_population(n_agents=10, seed=42) # Run test. - csu.run_simulation(agents, n_periods=20, seed=42) + racaosimscsu.run_simulation(agents, n_periods=20, seed=42) # Check outputs. for agent in agents: self.assertGreaterEqual(agent.capital, 0.01) @@ -824,10 +847,10 @@ def test6(self) -> None: Test run_simulation raises error for non-positive n_periods. """ # Prepare inputs. - agents = csu.create_population(n_agents=5, seed=42) + agents = racaosimscsu.create_population(n_agents=5, seed=42) # Run test and check output. with self.assertRaises(AssertionError): - csu.run_simulation(agents, n_periods=0, seed=42) + racaosimscsu.run_simulation(agents, n_periods=0, seed=42) def test7(self) -> None: """ @@ -837,7 +860,7 @@ def test7(self) -> None: agents = [] # Run test and check output. with self.assertRaises(AssertionError): - csu.run_simulation(agents, n_periods=5, seed=42) + racaosimscsu.run_simulation(agents, n_periods=5, seed=42) def test8(self) -> None: """ @@ -845,11 +868,13 @@ def test8(self) -> None: """ # Prepare inputs. # Create agent with high IQ to capitalize on lucky events. - agent_high_iq = csu.Agent(0, 0.5, 0.99, 0.5, initial_capital=1.0) + agent_high_iq = racaosimscsu.Agent( + 0, 0.5, 0.99, 0.5, initial_capital=1.0 + ) # Create agent with low IQ to fail capitalizing. - agent_low_iq = csu.Agent(1, 0.5, 0.01, 0.5, initial_capital=1.0) + agent_low_iq = racaosimscsu.Agent(1, 0.5, 0.01, 0.5, initial_capital=1.0) # Run test. - csu.run_simulation( + racaosimscsu.run_simulation( [agent_high_iq, agent_low_iq], n_periods=50, n_lucky_events_per_period=10, @@ -865,9 +890,9 @@ def test9(self) -> None: Test networking spillover mechanism with 10% spillover probability. """ # Prepare inputs. - agents = csu.create_population(n_agents=10, seed=42) + agents = racaosimscsu.create_population(n_agents=10, seed=42) # Run test. - csu.run_simulation( + racaosimscsu.run_simulation( agents, n_periods=100, n_lucky_events_per_period=10, @@ -895,10 +920,10 @@ def test1(self) -> None: Test run_policy_simulation with egalitarian policy. """ # Prepare inputs. - agents = csu.create_population(n_agents=10, seed=42) + agents = racaosimscsu.create_population(n_agents=10, seed=42) resource_amount = 50.0 # Run test. - result = csu.run_policy_simulation( + result = racaosimscsu.run_policy_simulation( agents, policy="egalitarian", resource_amount=resource_amount, @@ -906,17 +931,17 @@ def test1(self) -> None: seed=42, ) # Check outputs. - self.assertTrue(csu.validate_simulation_results(result)) + self.assertTrue(racaosimscsu.validate_simulation_results(result)) def test2(self) -> None: """ Test run_policy_simulation with meritocratic policy. """ # Prepare inputs. - agents = csu.create_population(n_agents=10, seed=42) + agents = racaosimscsu.create_population(n_agents=10, seed=42) resource_amount = 50.0 # Run test. - result = csu.run_policy_simulation( + result = racaosimscsu.run_policy_simulation( agents, policy="meritocratic", resource_amount=resource_amount, @@ -924,17 +949,17 @@ def test2(self) -> None: seed=42, ) # Check outputs. - self.assertTrue(csu.validate_simulation_results(result)) + self.assertTrue(racaosimscsu.validate_simulation_results(result)) def test3(self) -> None: """ Test run_policy_simulation with performance policy. """ # Prepare inputs. - agents = csu.create_population(n_agents=10, seed=42) + agents = racaosimscsu.create_population(n_agents=10, seed=42) resource_amount = 50.0 # Run test. - result = csu.run_policy_simulation( + result = racaosimscsu.run_policy_simulation( agents, policy="performance", resource_amount=resource_amount, @@ -942,17 +967,17 @@ def test3(self) -> None: seed=42, ) # Check outputs. - self.assertTrue(csu.validate_simulation_results(result)) + self.assertTrue(racaosimscsu.validate_simulation_results(result)) def test4(self) -> None: """ Test run_policy_simulation with random policy. """ # Prepare inputs. - agents = csu.create_population(n_agents=10, seed=42) + agents = racaosimscsu.create_population(n_agents=10, seed=42) resource_amount = 50.0 # Run test. - result = csu.run_policy_simulation( + result = racaosimscsu.run_policy_simulation( agents, policy="random", resource_amount=resource_amount, @@ -960,18 +985,18 @@ def test4(self) -> None: seed=42, ) # Check outputs. - self.assertTrue(csu.validate_simulation_results(result)) + self.assertTrue(racaosimscsu.validate_simulation_results(result)) def test5(self) -> None: """ Test run_policy_simulation with cate_optimal policy. """ # Prepare inputs. - agents = csu.create_population(n_agents=10, seed=42) + agents = racaosimscsu.create_population(n_agents=10, seed=42) resource_amount = 50.0 cate_values = np.array([0.5] * 10, dtype=float) # Run test. - result = csu.run_policy_simulation( + result = racaosimscsu.run_policy_simulation( agents, policy="cate_optimal", resource_amount=resource_amount, @@ -980,18 +1005,18 @@ def test5(self) -> None: seed=42, ) # Check outputs. - self.assertTrue(csu.validate_simulation_results(result)) + self.assertTrue(racaosimscsu.validate_simulation_results(result)) def test6(self) -> None: """ Test run_policy_simulation egalitarian allocates equally. """ # Prepare inputs. - agents = csu.create_population(n_agents=10, seed=42) + agents = racaosimscsu.create_population(n_agents=10, seed=42) resource_amount = 100.0 # Check allocation by comparing the change in total capital. initial_total = sum(a.capital for a in agents) - csu.run_policy_simulation( + racaosimscsu.run_policy_simulation( agents, policy="egalitarian", resource_amount=resource_amount, @@ -1001,18 +1026,20 @@ def test6(self) -> None: # Check outputs. final_total = sum(a.capital for a in agents) # Final total should be close to initial + resource allocation. - self.assertGreaterEqual(final_total, initial_total + resource_amount - 10.0) + self.assertGreaterEqual( + final_total, initial_total + resource_amount - 10.0 + ) def test7(self) -> None: """ Test run_policy_simulation total capital is preserved after allocation. """ # Prepare inputs. - agents = csu.create_population(n_agents=10, seed=42) + agents = racaosimscsu.create_population(n_agents=10, seed=42) initial_total = sum(a.capital for a in agents) resource_amount = 50.0 # Run test. - csu.run_policy_simulation( + racaosimscsu.run_policy_simulation( agents, policy="egalitarian", resource_amount=resource_amount, @@ -1022,17 +1049,19 @@ def test7(self) -> None: # Check outputs. # Total capital should be at least initial + allocated (may change during simulation). final_total = sum(a.capital for a in agents) - self.assertGreaterEqual(final_total, initial_total + resource_amount - 5.0) + self.assertGreaterEqual( + final_total, initial_total + resource_amount - 5.0 + ) def test8(self) -> None: """ Test run_policy_simulation raises error for invalid policy. """ # Prepare inputs. - agents = csu.create_population(n_agents=5, seed=42) + agents = racaosimscsu.create_population(n_agents=5, seed=42) # Run test and check output. with self.assertRaises(ValueError): - csu.run_policy_simulation( + racaosimscsu.run_policy_simulation( agents, policy="invalid_policy", resource_amount=50.0, @@ -1045,10 +1074,10 @@ def test9(self) -> None: Test run_policy_simulation cate_optimal requires cate_values. """ # Prepare inputs. - agents = csu.create_population(n_agents=5, seed=42) + agents = racaosimscsu.create_population(n_agents=5, seed=42) # Run test and check output. with self.assertRaises(AssertionError): - csu.run_policy_simulation( + racaosimscsu.run_policy_simulation( agents, policy="cate_optimal", resource_amount=50.0, @@ -1061,10 +1090,10 @@ def test10(self) -> None: Test run_policy_simulation with negative CATE values clamped to zero. """ # Prepare inputs. - agents = csu.create_population(n_agents=5, seed=42) + agents = racaosimscsu.create_population(n_agents=5, seed=42) cate_values = np.array([-1.0, 0.5, -0.5, 0.8, 0.0], dtype=float) # Run test. - csu.run_policy_simulation( + racaosimscsu.run_policy_simulation( agents, policy="cate_optimal", resource_amount=50.0, @@ -1074,7 +1103,7 @@ def test10(self) -> None: ) # Check outputs. # Agents with negative CATE should get 0 allocation. - self.assertTrue(csu.validate_simulation_results(agents)) + self.assertTrue(racaosimscsu.validate_simulation_results(agents)) # ############################################################################# @@ -1092,11 +1121,11 @@ def test1(self) -> None: Test fit_bayesian_luck_model returns model and idata. """ # Prepare inputs. - agents = csu.create_population(n_agents=20, seed=42) - csu.run_simulation(agents, n_periods=10, seed=42) - df = csu.get_results_dataframe(agents) + agents = racaosimscsu.create_population(n_agents=20, seed=42) + racaosimscsu.run_simulation(agents, n_periods=10, seed=42) + df = racaosimscsu.get_results_dataframe(agents) # Run test. - model, idata = csu.fit_bayesian_luck_model( + model, idata = racaosimscsu.fit_bayesian_luck_model( df, draws=100, tune=100, random_seed=42 ) # Check outputs. @@ -1113,25 +1142,27 @@ def test2(self) -> None: df = pd.DataFrame({"capital": [1.0, 2.0, 3.0]}) # Run test and check output. with self.assertRaises(AssertionError): - csu.fit_bayesian_luck_model(df, draws=10, tune=10, random_seed=42) + racaosimscsu.fit_bayesian_luck_model( + df, draws=10, tune=10, random_seed=42 + ) def test3(self) -> None: """ Test fit_bayesian_luck_model with seed produces reproducible results. """ # Prepare inputs. - agents1 = csu.create_population(n_agents=15, seed=42) - csu.run_simulation(agents1, n_periods=8, seed=42) - df1 = csu.get_results_dataframe(agents1) + agents1 = racaosimscsu.create_population(n_agents=15, seed=42) + racaosimscsu.run_simulation(agents1, n_periods=8, seed=42) + df1 = racaosimscsu.get_results_dataframe(agents1) - agents2 = csu.create_population(n_agents=15, seed=42) - csu.run_simulation(agents2, n_periods=8, seed=42) - df2 = csu.get_results_dataframe(agents2) + agents2 = racaosimscsu.create_population(n_agents=15, seed=42) + racaosimscsu.run_simulation(agents2, n_periods=8, seed=42) + df2 = racaosimscsu.get_results_dataframe(agents2) # Run test. - _, idata1 = csu.fit_bayesian_luck_model( + _, idata1 = racaosimscsu.fit_bayesian_luck_model( df1, draws=50, tune=50, random_seed=123 ) - _, idata2 = csu.fit_bayesian_luck_model( + _, idata2 = racaosimscsu.fit_bayesian_luck_model( df2, draws=50, tune=50, random_seed=123 ) # Check outputs. @@ -1154,14 +1185,14 @@ def test1(self) -> None: Test summarize_bayesian_fit returns DataFrame with correct columns. """ # Prepare inputs. - agents = csu.create_population(n_agents=20, seed=42) - csu.run_simulation(agents, n_periods=10, seed=42) - df = csu.get_results_dataframe(agents) - _, idata = csu.fit_bayesian_luck_model( + agents = racaosimscsu.create_population(n_agents=20, seed=42) + racaosimscsu.run_simulation(agents, n_periods=10, seed=42) + df = racaosimscsu.get_results_dataframe(agents) + _, idata = racaosimscsu.fit_bayesian_luck_model( df, draws=100, tune=100, random_seed=42 ) # Run test. - summary = csu.summarize_bayesian_fit(idata) + summary = racaosimscsu.summarize_bayesian_fit(idata) # Check outputs. self.assertIsNotNone(summary) self.assertGreater(len(summary), 0) @@ -1171,14 +1202,14 @@ def test2(self) -> None: Test summarize_bayesian_fit includes default parameters. """ # Prepare inputs. - agents = csu.create_population(n_agents=20, seed=42) - csu.run_simulation(agents, n_periods=10, seed=42) - df = csu.get_results_dataframe(agents) - _, idata = csu.fit_bayesian_luck_model( + agents = racaosimscsu.create_population(n_agents=20, seed=42) + racaosimscsu.run_simulation(agents, n_periods=10, seed=42) + df = racaosimscsu.get_results_dataframe(agents) + _, idata = racaosimscsu.fit_bayesian_luck_model( df, draws=100, tune=100, random_seed=42 ) # Run test. - summary = csu.summarize_bayesian_fit(idata) + summary = racaosimscsu.summarize_bayesian_fit(idata) # Check outputs. # Should include default parameters. self.assertIn("alpha", summary.index) @@ -1189,14 +1220,16 @@ def test3(self) -> None: Test summarize_bayesian_fit with custom var_names parameter. """ # Prepare inputs. - agents = csu.create_population(n_agents=20, seed=42) - csu.run_simulation(agents, n_periods=10, seed=42) - df = csu.get_results_dataframe(agents) - _, idata = csu.fit_bayesian_luck_model( + agents = racaosimscsu.create_population(n_agents=20, seed=42) + racaosimscsu.run_simulation(agents, n_periods=10, seed=42) + df = racaosimscsu.get_results_dataframe(agents) + _, idata = racaosimscsu.fit_bayesian_luck_model( df, draws=100, tune=100, random_seed=42 ) # Run test. - summary = csu.summarize_bayesian_fit(idata, var_names=["alpha", "sigma"]) + summary = racaosimscsu.summarize_bayesian_fit( + idata, var_names=["alpha", "sigma"] + ) # Check outputs. self.assertIn("alpha", summary.index) self.assertIn("sigma", summary.index) @@ -1218,14 +1251,14 @@ def test1(self) -> None: Test posterior_predictive_check returns correct keys. """ # Prepare inputs. - agents = csu.create_population(n_agents=20, seed=42) - csu.run_simulation(agents, n_periods=10, seed=42) - df = csu.get_results_dataframe(agents) - model, idata = csu.fit_bayesian_luck_model( + agents = racaosimscsu.create_population(n_agents=20, seed=42) + racaosimscsu.run_simulation(agents, n_periods=10, seed=42) + df = racaosimscsu.get_results_dataframe(agents) + model, idata = racaosimscsu.fit_bayesian_luck_model( df, draws=100, tune=100, random_seed=42 ) # Run test. - ppc = csu.posterior_predictive_check( + ppc = racaosimscsu.posterior_predictive_check( model, idata, df, random_seed=123 ) # Check outputs. @@ -1237,14 +1270,14 @@ def test2(self) -> None: Test posterior_predictive_check PPC arrays have correct shape. """ # Prepare inputs. - agents = csu.create_population(n_agents=20, seed=42) - csu.run_simulation(agents, n_periods=10, seed=42) - df = csu.get_results_dataframe(agents) - model, idata = csu.fit_bayesian_luck_model( + agents = racaosimscsu.create_population(n_agents=20, seed=42) + racaosimscsu.run_simulation(agents, n_periods=10, seed=42) + df = racaosimscsu.get_results_dataframe(agents) + model, idata = racaosimscsu.fit_bayesian_luck_model( df, draws=100, tune=100, random_seed=42 ) # Run test. - ppc = csu.posterior_predictive_check( + ppc = racaosimscsu.posterior_predictive_check( model, idata, df, random_seed=123 ) # Check outputs. @@ -1252,3 +1285,148 @@ def test2(self) -> None: self.assertEqual(len(ppc["y_obs"]), n_obs) self.assertEqual(len(ppc["y_pred_mean"]), n_obs) self.assertEqual(len(ppc["y_pred_std"]), n_obs) + + +# ############################################################################# +# Test_fit_dml_model +# ############################################################################# + + +class Test_fit_dml_model(hunitest.TestCase): + """ + Test the fit_dml_model function. + """ + + def _prepare_df(self): + """ + Build a small simulated DataFrame for causal inference tests. + """ + agents = racaosimscsu.create_population(n_agents=40, seed=42) + racaosimscsu.run_simulation(agents, n_periods=20, seed=42) + return racaosimscsu.get_results_dataframe(agents) + + def test1(self) -> None: + """ + Test fit_dml_model returns four values of the expected types. + """ + # Prepare inputs. + df = self._prepare_df() + # Run test. + dml_model, ate_estimates, ate_mean, ate_std = racaosimscsu.fit_dml_model( + df, n_estimators=10, max_depth=5, random_state=42 + ) + # Check outputs. + self.assertIsNotNone(dml_model) + self.assertEqual(len(ate_estimates), len(df)) + self.assertIsInstance(ate_mean, float) + self.assertIsInstance(ate_std, float) + + def test2(self) -> None: + """ + Test fit_dml_model is deterministic under a fixed random_state. + """ + # Prepare inputs. + df = self._prepare_df() + # Run test. + _, _, ate_mean1, _ = racaosimscsu.fit_dml_model( + df, n_estimators=10, max_depth=5, random_state=42 + ) + _, _, ate_mean2, _ = racaosimscsu.fit_dml_model( + df, n_estimators=10, max_depth=5, random_state=42 + ) + # Check outputs. + self.assertAlmostEqual(ate_mean1, ate_mean2, places=6) + + +# ############################################################################# +# Test_fit_causal_forest +# ############################################################################# + + +class Test_fit_causal_forest(hunitest.TestCase): + """ + Test the fit_causal_forest function. + """ + + def _prepare_df(self): + """ + Build a small simulated DataFrame for causal inference tests. + """ + agents = racaosimscsu.create_population(n_agents=40, seed=42) + racaosimscsu.run_simulation(agents, n_periods=20, seed=42) + return racaosimscsu.get_results_dataframe(agents) + + def test1(self) -> None: + """ + Test fit_causal_forest returns a model and per-agent CATE estimates. + """ + # Prepare inputs. + df = self._prepare_df() + # Run test. + cf_model, cate_estimates = racaosimscsu.fit_causal_forest( + df, n_estimators=10, max_depth=5, random_state=42 + ) + # Check outputs. + self.assertIsNotNone(cf_model) + self.assertEqual(len(cate_estimates), len(df)) + + +# ############################################################################# +# Test_compare_allocation_policies +# ############################################################################# + + +class Test_compare_allocation_policies(hunitest.TestCase): + """ + Test the compare_allocation_policies function. + """ + + def _prepare_df_with_cate(self): + """ + Build a simulated DataFrame with a 'cate' column. + """ + agents = racaosimscsu.create_population(n_agents=60, seed=42) + racaosimscsu.run_simulation(agents, n_periods=20, seed=42) + df = racaosimscsu.get_results_dataframe(agents) + # Add synthetic CATE estimates so the CATE-optimal policy can run. + df["cate"] = np.linspace(0.01, 0.5, len(df)) + return df + + def test1(self) -> None: + """ + Test policy comparison returns five rows and expected columns. + """ + # Prepare inputs. + df = self._prepare_df_with_cate() + # Run test. + comparison = racaosimscsu.compare_allocation_policies(df) + # Check outputs. + self.assertEqual(len(comparison), 5) + expected_policies = { + "Egalitarian", + "Meritocratic", + "Random", + "Winner-Take-More", + "CATE-Optimal", + } + self.assertEqual(set(comparison["Policy"]), expected_policies) + for col in [ + "Total Capital", + "Gini Coefficient", + "Top 10% Share", + "Bottom 50% Share", + ]: + self.assertIn(col, comparison.columns) + + def test2(self) -> None: + """ + Test Gini coefficients from policy comparison stay in [0, 1]. + """ + # Prepare inputs. + df = self._prepare_df_with_cate() + # Run test. + comparison = racaosimscsu.compare_allocation_policies(df) + # Check outputs. + for gini in comparison["Gini Coefficient"]: + self.assertGreaterEqual(gini, 0.0) + self.assertLessEqual(gini, 1.0) From c2e04964ed374bdc10756ec684bba1abcf3a8b73 Mon Sep 17 00:00:00 2001 From: Krishna Kishore Buddi Date: Mon, 6 Apr 2026 19:23:17 -0400 Subject: [PATCH 2/2] Remove local Claude settings from tracking --- .../.claude/settings.local.json | 12 ------------ .../.gitignore | 1 + 2 files changed, 1 insertion(+), 12 deletions(-) delete mode 100644 research/A_Causal_Analysis_of_Success_in_Modern_Society/.claude/settings.local.json diff --git a/research/A_Causal_Analysis_of_Success_in_Modern_Society/.claude/settings.local.json b/research/A_Causal_Analysis_of_Success_in_Modern_Society/.claude/settings.local.json deleted file mode 100644 index 50971c39e..000000000 --- a/research/A_Causal_Analysis_of_Success_in_Modern_Society/.claude/settings.local.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "permissions": { - "allow": [ - "Bash(ls -lh /c/Users/kisho/gpsaggese.github.io/tutorials/Autogen/*.ipynb)", - "Bash(xargs grep:*)", - "Bash(python -c 'import json; f=open\\('\\\\''causal_success.API.ipynb'\\\\'','\\\\''r'\\\\'',encoding='\\\\''utf-8'\\\\''\\); nb=json.load\\(f\\); f.close\\(\\); changed=False:*)", - "Bash(python _fix_refs.py)", - "Bash(rm _fix_refs.py)", - "Bash(ls *.ipynb *.py)" - ] - } -} diff --git a/research/A_Causal_Analysis_of_Success_in_Modern_Society/.gitignore b/research/A_Causal_Analysis_of_Success_in_Modern_Society/.gitignore index 0fbd9cc2b..1c92833be 100644 --- a/research/A_Causal_Analysis_of_Success_in_Modern_Society/.gitignore +++ b/research/A_Causal_Analysis_of_Success_in_Modern_Society/.gitignore @@ -58,3 +58,4 @@ dist/ # ---- Cache ---- .cache/ *.tmp +.claude/