This repository aims to replicate the lifecycle savings and labor supply model presented in Imai and Keane (2004). The replication is done in Python.
This work represents a direct contribution to the REMARK project led by the open-source community at Econ-ARK. The primary objective of REMARK is to promote reproducibility and transparency across computational economics.
The central piece of this repository is an educational and interactive Jupyter Notebook. This notebook reviews the insights of the original paper, breaking down the model and introducing the computational machinery and algorithms necessary for a complete replication.
Imai and Keane (2004) studies the dynamics of lifecycle savings and labor supply decisions when wages are endogenous. At its core, the study highlights how the accumulation of human capital may explain the divergence between micro- and macro-estimates of the intertemporal elasticity of subsitution.
The authors established that when the future return to human capital is appropriately accounted for in the modeling, the elasticity of intertemporal substitution in labor supply emerges significantly higher than estimated by preceding, less nuanced models.
By shifting this paradigm into Python, we ensure that the model behaves transparently and is accessible to researchers, academics, and students alike within the broader economics community.
An hour of work today rewards the agent with income, but it also increases utility through the rest of the lifecycle by increasing human capital and thus leading to higher earnings throughout the lifecycle. Because of this dynamic, at younger ages the true return to work may be much larger than the observed wage. When agents are older, their wages are higher but the returns to increased human capital are lower because they have fewer future years of work. The net result is a reasonably flat shadow wage which captures the net returns to work.
If the econometrician focuses solely on the variation between hourly wage and hours of work, the reasonably flat lifetime profile of hours and reasonably steep profile of wages will erroneously suggest a weak relationship between the two. Accounting for the full returns to work inclusive of human capital accumulation leads to a much higher responsiveness and leads to the higher i.e.s. that Imai and Keane find.
The utility function modeled has agents receive utility from consumption, given by a CRRA specification. In order to discourage agents from borrowing when young to smooth consumption, the authors introduce age effects into utility. They do so with a linear spline
Wages are determined by human capital in a perfectly competitive labor market. Workers receive a rental rate for their human capital. Because the market is competitive and human capital is homogeneous, the wage rate is directly tied to the level of human capital an agent possesses.
A complication emerges here because I solve the problem with no borrowing so that
First, I loop through the points of
This codebase is systematically organized to isolate specific concerns and enable easy navigation:
binder/: The directory dedicated to the interactive Binder environment configuration. It housesenvironment.ymlfor broad Python environment definitions andrequirements.txtidentifying specific dependency versions.data/: The folder containing pre-processed datasets or configuration files specifically formatted to feed the replication processes.auxcode/: A supplementary folder comprising underlying helper functions, solvers, and utilities. This code is imported and leveraged by the main notebook, keeping the educational notebook clean and readable.results/: A folder intended to catch the generated outputs, tables, and serialized representations arising from the completed replication runs.Imai_and_Keane_2004.ipynb: The flagship Jupyter Notebook. It acts as both a written review of the paper and a step-by-step interactive demonstration of the reproduction code.reproduce.sh: A top-level bash script functioning as the primary entry point for executing the entire replication automatically.do_all.py: A centralized Python orchestration script that executes the computational load when triggered byreproduce.sh.myst.yml: A configuration file enabling seamless integration with the MyST Markdown system for enhanced documentation rendering.
To run the replication completely isolated from your host system using Docker, ensuring that environmental factors do not interfere with the results:
- Clone the project locally:
git clone https://github.com/JohnRGreen/ImaiKeane_replication.git - Navigate into the folder:
cd ImaiKeane_replication - Process the
Dockerfileto create an image:docker build -t imai_keane_container . - Deploy the replication via a disposable container shell:
docker run --rm imai_keane_container - The output should be successfully captured the
resultsdirectory.
If you prefer executing the code directly on your local workstation without Docker abstraction:
- Confirm that Python 3.10 or a slightly newer compatible version is cleanly installed in your path.
- Initialize a local virtual environment to avoid polluting host packages.
- Install dependencies from the
binderspecification:pip install -r binder/requirements.txt - Trigger the end-to-end execution workflow by simply invoking:
./reproduce.sh - Alternatively, run the python file directly:
python do_all.py
This repository is currently tagged as a work in progress. While the foundational scaffolding, environments, and basic solvers exist, we expect continuous iterations moving forward. The logic will be frequently updated with improved algorithms, enriched methodologies, and finalized replication matrices. We are actively aiming to provide full parity with the outputs highlighted in the original Imai and Keane publication.
We aim to keep this repository well-documented. If you'd like to help test the accuracy of the structural economic models, debug dependencies, or port the legacy code, please submit a pull request against the active branch. Ensure reproduce.sh works seamlessly before marking your pull request as ready for review.
The repository follows a test-driven development cycle locally to prevent regressions. All major equations and model transformations are coded modularly to permit isolation tracing.
When reporting an issue, clearly list out the parameters, dataset utilized, and python runtime environment so we can smoothly troubleshoot the unexpected behaviour.
This project and entirely of its corresponding code is distributed openly under the permissive MIT License. Please consult the supplementary LICENSE file found at the root of the repository for detailed warranty disclaimers and specific attribution terms.