-
Notifications
You must be signed in to change notification settings - Fork 343
MMM Plot Suite Migration: arviz_plots Multi-Backend Support #2098
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
isofer
wants to merge
33
commits into
main
Choose a base branch
from
feature/mmmplotsuite-arviz
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 19 commits
Commits
Show all changes
33 commits
Select commit
Hold shift + click to select a range
b2b881e
completed phase 1
isofer 6dbd6ce
adds plan
isofer a6ec594
add research
isofer 3fe9969
add arviz to 3 functions
isofer 278e9bb
a lot of changes to plot.py
isofer d6331a0
clean up for plot.py
isofer f5574d3
doing research
isofer e140362
change to research
isofer ef02276
finished milestone 1.4
isofer 2632822
finished 3.2
isofer dc67ab0
working on 3.3
isofer 84eadc9
done milestone 4
isofer ddce5b9
add check for valid keys in mmm_config
isofer f354005
small change to commit
isofer 26da1d4
small update
isofer b36d0e9
Merge branch 'main' into feature/mmmplotsuite-arviz
isofer d5d4bae
adds test_legacy_plot
isofer c321039
remove old test
isofer 2d4723f
small changes
isofer cdb4877
update Claude.md
isofer 3741bb2
update env
isofer 8cb9d07
update pyproject.toml
isofer cb9dccc
update pyproject.toml
isofer b612ac8
Merge branch 'main' into feature/mmmplotsuite-arviz
isofer 9728128
increase coverage of config.py to 100
isofer 599d1f4
Merge branch 'main' into feature/mmmplotsuite-arviz
cetagostini 1dbe00b
Merge branch 'main' into feature/mmmplotsuite-arviz
williambdean 93eeb63
addressed 2 comments
isofer cfea8e5
remove versionadded
isofer 3c82941
remove tests
isofer 153583e
update docstrings
isofer 00c269d
changes name of MMMConfig to MMMPlotConfig
isofer e9a05ba
Address feedback: Combine tests using pytest.mark.parametrize (#2103)
Copilot File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We already added claude commands and skills to the repo so it seems appropriate to add this file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can it be renamed to AGENTS.md then if this if general enough then.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.mdlike 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
.claudefolder.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.mdfile, or remove the.claudefolder. I prefer to addClaude.md