Skip to content
Open
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
b2b881e
completed phase 1
isofer Nov 12, 2025
6dbd6ce
adds plan
isofer Nov 12, 2025
a6ec594
add research
isofer Nov 13, 2025
3fe9969
add arviz to 3 functions
isofer Nov 17, 2025
278e9bb
a lot of changes to plot.py
isofer Nov 19, 2025
d6331a0
clean up for plot.py
isofer Nov 19, 2025
f5574d3
doing research
isofer Nov 19, 2025
e140362
change to research
isofer Nov 20, 2025
ef02276
finished milestone 1.4
isofer Nov 20, 2025
2632822
finished 3.2
isofer Nov 20, 2025
dc67ab0
working on 3.3
isofer Nov 21, 2025
84eadc9
done milestone 4
isofer Nov 21, 2025
ddce5b9
add check for valid keys in mmm_config
isofer Nov 21, 2025
f354005
small change to commit
isofer Nov 21, 2025
26da1d4
small update
isofer Nov 21, 2025
b36d0e9
Merge branch 'main' into feature/mmmplotsuite-arviz
isofer Nov 21, 2025
d5d4bae
adds test_legacy_plot
isofer Nov 21, 2025
c321039
remove old test
isofer Nov 21, 2025
2d4723f
small changes
isofer Nov 21, 2025
cdb4877
update Claude.md
isofer Nov 22, 2025
3741bb2
update env
isofer Nov 22, 2025
8cb9d07
update pyproject.toml
isofer Nov 22, 2025
cb9dccc
update pyproject.toml
isofer Nov 22, 2025
b612ac8
Merge branch 'main' into feature/mmmplotsuite-arviz
isofer Nov 22, 2025
9728128
increase coverage of config.py to 100
isofer Nov 22, 2025
599d1f4
Merge branch 'main' into feature/mmmplotsuite-arviz
cetagostini Nov 24, 2025
1dbe00b
Merge branch 'main' into feature/mmmplotsuite-arviz
williambdean Nov 26, 2025
93eeb63
addressed 2 comments
isofer Nov 27, 2025
cfea8e5
remove versionadded
isofer Nov 27, 2025
3c82941
remove tests
isofer Nov 27, 2025
153583e
update docstrings
isofer Nov 27, 2025
00c269d
changes name of MMMConfig to MMMPlotConfig
isofer Nov 27, 2025
e9a05ba
Address feedback: Combine tests using pytest.mark.parametrize (#2103)
Copilot Nov 28, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
272 changes: 272 additions & 0 deletions CLAUDE.md
Copy link
Contributor

Choose a reason for hiding this comment

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

remove this

Copy link
Author

Choose a reason for hiding this comment

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

We already added claude commands and skills to the repo so it seems appropriate to add this file.

Copy link
Contributor

Choose a reason for hiding this comment

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

Can it be renamed to AGENTS.md then if this if general enough then.

Copy link
Author

Choose a reason for hiding this comment

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

Claude.md, like the skills and commands that were already uploaded, are used by Claude code. It expect for a with that name and these set of folders.
The text in Claude.md like the skills and command is very generic and can be used by any AI Platform, but we need this specific structure to get the most of Claude code.
So I don't think it make sense to change the name of this file while leaving all the .claude folder.

The current status of the repo is weird, we uploaded skills and command which mean we support Claude Code, but we are missing Claude.md, so Claude Code cannot run on this repo.
I think we should either go all-in and support claude code and add the Claude.md file, or remove the .claude folder. I prefer to add Claude.md

Original file line number Diff line number Diff line change
@@ -0,0 +1,272 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project Overview

PyMC-Marketing is a Bayesian marketing analytics library built on PyMC, providing three main modeling capabilities:

- **Marketing Mix Modeling (MMM)**: Measure marketing channel effectiveness with adstock, saturation, and budget optimization
- **Customer Lifetime Value (CLV)**: Predict customer value using probabilistic models (BG/NBD, Pareto/NBD, Gamma-Gamma, etc.)
- **Customer Choice Analysis**: Understand product selection with Multivariate Interrupted Time Series (MVITS) and discrete choice models

## Development Commands

### Environment Setup
```bash
# Create and activate conda environment (recommended)
conda env create -f environment.yml
conda activate pymc-marketing-dev

# Install package in editable mode
make init
```

### Testing and Quality
To use pytest you first need to activate the enviroment:
```bash
source ~/miniconda3/etc/profile.d/conda.sh && conda activate pymc-marketing-dev
```

Running tests:
```bash
# first need to activate the enviorment:

# Run all tests with coverage
make test

# Run specific test file (you first need to activate the conda env: conda activate pymc-marketing-dev)
pytest tests/path/to/test_file.py

# Run specific test function (you first need to activate the conda env: conda activate pymc-marketing-dev)
pytest tests/path/to/test_file.py::test_function_name

# Check linting (ruff + mypy)
make check_lint

# Auto-fix linting issues
make lint

# Check code formatting
make check_format

# Auto-format code
make format
```

### Documentation
```bash
# Build HTML documentation
make html

# Clean docs and rebuild from scratch
make cleandocs && make html

# Run notebooks to verify examples
make run_notebooks # All notebooks
make run_notebooks_mmm # MMM notebooks only
make run_notebooks_other # Non-MMM notebooks
```

### Other Utilities
```bash
# Generate UML diagrams for architecture
make uml

# Start MLflow tracking server
make mlflow_server
```

## High-Level Architecture

### Core Base Classes

**ModelBuilder** ([pymc_marketing/model_builder.py](pymc_marketing/model_builder.py))
- Abstract base class for all PyMC-Marketing models
- Defines the model lifecycle: `build_model()` β†’ `fit()` β†’ `predict()`
- Provides save/load functionality via NetCDF and InferenceData
- Manages `model_config` (priors) and `sampler_config` (MCMC settings)

**RegressionModelBuilder** (extends ModelBuilder)
- Adds scikit-learn-like API: `fit(X, y)`, `predict(X)`
- Base class for MMM and some customer choice models
- Handles prior/posterior predictive sampling

**CLVModel** ([pymc_marketing/clv/models/basic.py](pymc_marketing/clv/models/basic.py))
- Base class for CLV models (BetaGeo, ParetoNBD, GammaGamma, etc.)
- Takes data in constructor, not fit method: `model = BetaGeoModel(data=df)`
- Supports multiple inference methods: `method="mcmc"` (default), `"map"`, `"advi"`, etc.

### Module 1: MMM Architecture

**Class Hierarchy:**
```
RegressionModelBuilder
└── MMMModelBuilder (mmm/base.py)
β”œβ”€β”€ BaseMMM/MMM (mmm/mmm.py) - Single market
└── MMM (mmm/multidimensional.py) - Panel/hierarchical data
```

**Component-Based Design:**

MMM uses composable transformation components:

1. **Adstock Transformations** ([pymc_marketing/mmm/components/adstock.py](pymc_marketing/mmm/components/adstock.py))
- Model carryover effects of advertising
- Built-in: GeometricAdstock, DelayedAdstock, WeibullCDFAdstock, WeibullPDFAdstock
- All extend `AdstockTransformation` base class

2. **Saturation Transformations** ([pymc_marketing/mmm/components/saturation.py](pymc_marketing/mmm/components/saturation.py))
- Model diminishing returns
- Built-in: LogisticSaturation, HillSaturation, MichaelisMentenSaturation, TanhSaturation
- All extend `SaturationTransformation` base class

3. **Transformation Protocol** ([pymc_marketing/mmm/components/base.py](pymc_marketing/mmm/components/base.py))
- Base class defining transformation interface
- Requires: `function()`, `prefix`, `default_priors`
- Custom transformations should extend this

**Validation and Preprocessing System:**

MMM models use a decorator-based system:
- Methods tagged with `_tags = {"validation_X": True}` run during `fit(X, y)`
- Methods tagged with `_tags = {"preprocessing_y": True}` transform data before modeling
- Built-in validators in [pymc_marketing/mmm/validating.py](pymc_marketing/mmm/validating.py)
- Built-in preprocessors in [pymc_marketing/mmm/preprocessing.py](pymc_marketing/mmm/preprocessing.py)

**Key MMM Features:**
- Time-varying parameters via HSGP (Hilbert Space Gaussian Process)
- Lift test calibration for experiments
- Budget optimization ([pymc_marketing/mmm/budget_optimizer.py](pymc_marketing/mmm/budget_optimizer.py))
- Causal DAG support ([pymc_marketing/mmm/causal.py](pymc_marketing/mmm/causal.py))
- Additive effects system ([pymc_marketing/mmm/additive_effect.py](pymc_marketing/mmm/additive_effect.py)) for custom components

**Multidimensional MMM vs Base MMM:**
- Base MMM ([pymc_marketing/mmm/mmm.py](pymc_marketing/mmm/mmm.py)): Single market, simpler API
- Multidimensional MMM ([pymc_marketing/mmm/multidimensional.py](pymc_marketing/mmm/multidimensional.py)): Panel data, per-channel transformations via `MediaConfigList`, more flexible

### Module 2: CLV Architecture

**Available Models:**
- BetaGeoModel: Beta-Geometric/NBD for continuous non-contractual settings
- ParetoNBDModel: Pareto/NBD alternative formulation
- GammaGammaModel: Monetary value prediction
- ShiftedBetaGeoModel, ModifiedBetaGeoModel: Variants
- BetaGeoBetaBinomModel: Discrete time variant

**CLV Pattern:**
```python
# Data passed to constructor, not fit()
model = clv.BetaGeoModel(data=df)

# Fit with various inference methods
model.fit(method="mcmc") # or "map", "advi", "fullrank_advi"

# Predict for known customers
model.expected_purchases(customer_id, t)
model.probability_alive(customer_id)
```

**Custom Distributions:**
CLV models use custom distributions in [pymc_marketing/clv/distributions.py](pymc_marketing/clv/distributions.py)

### Module 3: Customer Choice

- **MVITS** ([pymc_marketing/customer_choice/mv_its.py](pymc_marketing/customer_choice/mv_its.py)): Multivariate Interrupted Time Series for product launch incrementality
- **Discrete Choice Models**: Logit models in [pymc_marketing/customer_choice/](pymc_marketing/customer_choice/)

### Cross-Cutting Systems

**Prior Configuration System** ([pymc_marketing/prior.py](pymc_marketing/prior.py), now in pymc_extras)
- Declarative prior specification outside PyMC context
- Example: `Prior("Normal", mu=0, sigma=1)`
- Supports hierarchical priors, non-centered parameterization, transformations
- Used in all `model_config` dictionaries

**Model Configuration** ([pymc_marketing/model_config.py](pymc_marketing/model_config.py))
- `parse_model_config()` converts dicts to Prior objects
- Handles nested priors for hierarchical models
- Supports HSGP kwargs for Gaussian processes

**Save/Load Infrastructure**
- Models save to NetCDF via ArviZ InferenceData
- `model.save("filename.nc")` serializes model + data + config
- `Model.load("filename.nc")` reconstructs from file
- Training data stored in `idata.fit_data` group

**MLflow Integration** ([pymc_marketing/mlflow.py](pymc_marketing/mlflow.py))
- `autolog()` patches PyMC and PyMC-Marketing functions
- Automatically logs: model structure, diagnostics (r_hat, ESS, divergences), MMM/CLV configs
- Start server with: `make mlflow_server`

## Code Style and Testing

**Linting:**
- Uses Ruff for linting and formatting
- Uses mypy for type checking
- Config in [pyproject.toml](pyproject.toml) under `[tool.ruff]` and `[tool.mypy]`
- Docstrings follow NumPy style guide

**Testing:**
- pytest with coverage reporting
- Config in [pyproject.toml](pyproject.toml) under `[tool.pytest.ini_options]`
- Test files mirror package structure in [tests/](tests/)

**Pre-commit Hooks:**
```bash
pre-commit install # Set up hooks
pre-commit run --all-files # Run manually
```

## Important Patterns and Conventions

### Adding a New MMM Transformation

1. Extend `AdstockTransformation` or `SaturationTransformation` from [pymc_marketing/mmm/components/base.py](pymc_marketing/mmm/components/base.py)
2. Implement: `function()`, `prefix` property, `default_priors` property
3. Add to [pymc_marketing/mmm/components/adstock.py](pymc_marketing/mmm/components/adstock.py) or [saturation.py](pymc_marketing/mmm/components/saturation.py)
4. Export in [pymc_marketing/mmm/__init__.py](pymc_marketing/mmm/__init__.py)

### Adding a New CLV Model

1. Extend `CLVModel` from [pymc_marketing/clv/models/basic.py](pymc_marketing/clv/models/basic.py)
2. Implement: `build_model()`, prediction methods (e.g., `expected_purchases()`)
3. Define required data columns in `__init__`
4. Add tests in [tests/clv/models/](tests/clv/models/)

### Adding a New Additive Effect (MMM)

1. Implement `MuEffect` protocol from [pymc_marketing/mmm/additive_effect.py](pymc_marketing/mmm/additive_effect.py)
2. Required methods: `create_data()`, `create_effect()`, `set_data()`
3. See FourierEffect, LinearTrendEffect as examples

### Model Lifecycle

All models follow this pattern:
1. **Configuration**: Store data and config in `__init__`
2. **Build**: `build_model()` creates PyMC model, attaches to `self.model`
3. **Fit**: `fit()` calls `pm.sample()` or alternative inference
4. **Store**: Results stored in `self.idata` (ArviZ InferenceData)
5. **Predict**: `sample_posterior_predictive()` with new data

## Documentation and Examples

**Notebooks:**
- MMM examples: [docs/source/notebooks/mmm/](docs/source/notebooks/mmm/)
- CLV examples: [docs/source/notebooks/clv/](docs/source/notebooks/clv/)
- Customer choice: [docs/source/notebooks/customer_choice/](docs/source/notebooks/customer_choice/)

**Gallery Generation:**
- [scripts/generate_gallery.py](scripts/generate_gallery.py) creates notebook gallery for docs
- Run with `make html`

**UML Diagrams:**
- Architecture diagrams in [docs/source/uml/](docs/source/uml/)
- Generate with `make uml`
- See [CONTRIBUTING.md](CONTRIBUTING.md) for package/class diagrams

## Community and Support

- [GitHub Issues](https://github.com/pymc-labs/pymc-marketing/issues) for bugs/features
- [PyMC Discourse](https://discourse.pymc.io/) for general discussion
- [PyMC-Marketing Discussions](https://github.com/pymc-labs/pymc-marketing/discussions) for Q&A
2 changes: 2 additions & 0 deletions pymc_marketing/mmm/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
TanhSaturationBaselined,
saturation_from_dict,
)
from pymc_marketing.mmm.config import mmm_config
from pymc_marketing.mmm.fourier import MonthlyFourier, WeeklyFourier, YearlyFourier
from pymc_marketing.mmm.hsgp import (
HSGP,
Expand Down Expand Up @@ -109,6 +110,7 @@
"create_eta_prior",
"create_m_and_L_recommendations",
"mmm",
"mmm_config",
"preprocessing",
"preprocessing_method_X",
"preprocessing_method_y",
Expand Down
Loading
Loading