Skip to main content

pymc-marketing-mmm

Expert on PyMC-Marketing's Marketing Mix Model (MMM) framework including adstock transformations, saturation functions, hierarchical models, and GAM components. Use for MMM modeling, prior configuration, or pymc-marketing API questions.

Ir para a instalação

Informações da origem

Repositório
pymc-labs/decision-lab
Última atividade na origem
31 de março de 2026 às 12:08
Idioma detectado do SKILL.md
inglês
Estrelas
190
Forks
14

Opções de instalação

Por padrão, está selecionado o prompt que primeiro revisa a origem. Você pode mudar para um comando direto ou baixar uma cópia local.

Revise os arquivos de origem

Leia o SKILL.md e os arquivos complementares exibidos pelo SkillsMP antes de decidir se vai instalar.

Exibindo SKILL.md

SKILL.md
Instruções da origem · Visualização somente leitura
name
PyMC-Marketing MMM
description
Expert on PyMC-Marketing's Marketing Mix Model (MMM) framework including adstock transformations, saturation functions, hierarchical models, and GAM components. Use for MMM modeling, prior configuration, or pymc-marketing API questions.
# PyMC-Marketing GAM Options and Advanced Model Architectures ## Overview PyMC-Marketing extends beyond traditional Marketing Mix Modeling to support custom **Bayesian Generalized Additive Models (GAMs)** with flexible architectures for complex probabilistic inference. This skill covers advanced modeling patterns, multidimensional hierarchical structures, and custom model components. ## MMM Import Use `from pymc_marketing.mmm.multidimensional import MMM`. This handles both single time series (dims=None) and panel data with `dims=(<DIM>,)`. **CRITICAL: The `dims` value MUST match the exact column name from your dataframe.** Inspect the data columns first, then use the actual column name. Do NOT assume a column name — always verify it exists in the data. **WARNING: `from pymc_marketing.mmm import MMM` is DEPRECATED and will break save/load. Always use `from pymc_marketing.mmm.multidimensional import MMM`.** ## CRITICAL: Channel-Specific Parameters vs Dimensional Hierarchy **These are TWO DIFFERENT things - don't confuse them!** | Concept | What It Controls | Example | |---------|------------------|---------| | **`dims` parameter** | Hierarchical structure across *data dimensions* | Different baseline per region, pooled learning across regions | | **Channel-specific parameters** | Per-channel adstock (alpha) and saturation (lambda) | TV has slower decay than Digital | **WRONG: Single alpha/lambda shared across ALL channels** ```python # This defeats the purpose of MMM! mmm = MMM( channel_columns=["tv", "digital", "radio"], dims=<EXTRA_DIMS>, adstock=GeometricAdstock(l_max=8), # Single alpha shared by all channels saturation=LogisticSaturation(), # Single lambda shared by all channels ) ``` **CORRECT: PyMC-Marketing gives each channel its own parameters by default** When you specify `channel_columns=["tv", "digital", "radio"]`, PyMC-Marketing automatically creates: - `alpha[tv]`, `alpha[digital]`, `alpha[radio]` (3 separate adstock decay rates) - `lam[tv]`, `lam[digital]`, `lam[radio]` (3 separate saturation parameters) - `beta_channel[tv]`, `beta_channel[digital]`, `beta_channel[radio]` (3 separate effect sizes) **The `dims` parameter adds ADDITIONAL hierarchy on top of this.** For example with `dims=<EXTRA_DIMS>`: - `alpha[tv, dim_val_a]`, `alpha[tv, dim_val_b]`, `alpha[digital, dim_val_a]`, etc. (per channel AND per extra dimension) **Key insight:** If you only see a SINGLE `alpha` and SINGLE `lam` in your trace plots (not arrays), something is wrong with your model configuration! **After fitting, ALWAYS verify you have the right parameter shapes:** ```python # Verify channel-specific parameters exist # Parameter names: adstock_alpha, saturation_lam, saturation_beta print(mmm.fit_result['adstock_alpha'].dims) # Should be ('chain', 'draw', 'channel') print(mmm.fit_result['saturation_lam'].dims) # Should be ('chain', 'draw', 'channel') print(mmm.fit_result['saturation_beta'].dims) # Should be ('chain', 'draw', 'channel') # Check shapes - should have n_channels in the last dimension print(mmm.fit_result['adstock_alpha'].shape) # e.g., (4, 2000, 3) for 4 chains, 2000 draws, 3 channels # If using dims=<EXTRA_DIMS>, shapes should be (chain, draw, channel, *<EXTRA_DIMS>) # NOT just (chain, draw) with a single scalar value! ``` ## ⛔⛔⛔ CRITICAL: You MUST Configure Priors with dims - Default Does NOT Work! **❌ WRONG - Creates USELESS models (parameters same for all dimension levels):** ```python mmm = MMM( dims=<EXTRA_DIMS>, adstock=GeometricAdstock(l_max=12), # NO priors! All dim levels share same alpha! saturation=LogisticSaturation(), # NO priors! All dim levels share same params! ) ``` **The default `GeometricAdstock(l_max=12)` without `priors=` does NOT create dimension-specific parameters!** **✅ CORRECT - Configure priors with dims:** ```python from pymc_extras.prior import Prior adstock = GeometricAdstock( priors={"alpha": Prior("Beta", alpha=<ALPHA>, beta=<BETA>, dims=("channel", <DIM>))}, l_max=12 ) saturation = LogisticSaturation( priors={ "lam": Prior("Gamma", mu=<MU>, sigma=<SIGMA>, dims=("channel", <DIM>)), "beta": Prior("Gamma", mu=<MU>, sigma=<SIGMA>, dims=("channel", <DIM>)), } ) mmm = MMM(dims=<EXTRA_DIMS>, adstock=adstock, saturation=saturation) ``` ## Parameter Pooling Strategies for Multidimensional MMM When using `MMM` with dimensions like `dims=<EXTRA_DIMS>`, you MUST configure how parameters vary across dimensions. There are **three strategies**: ### Strategy 1: Fully Pooled (Shared across all dimension levels) **Same parameter for all dimension levels - one value per channel, shared everywhere.** ```python from pymc_marketing.mmm.multidimensional import MMM from pymc_marketing.mmm import GeometricAdstock, LogisticSaturation from pymc_extras.prior import Prior # Fully pooled: dims="channel" only (no extra dimension) adstock = GeometricAdstock( priors={"alpha": Prior("Beta", alpha=<VALUE>, beta=<VALUE>, dims=("channel",))}, l_max=8 ) saturation = LogisticSaturation( priors={ "lam": Prior("Gamma", mu=<VALUE>, sigma=<VALUE>, dims=("channel",)), "beta": Prior("Gamma", mu=<VALUE>, sigma=<VALUE>, dims=("channel",)), } ) mmm = MMM( date_column="date", target_column="sales", channel_columns=["tv", "radio", "digital"], dims=<EXTRA_DIMS>, adstock=adstock, saturation=saturation, ) ``` **Use when:** - Limited data per dimension level - You believe channel effects are truly the same across all dimension levels - Starting simple **Result:** 3 alpha values (one per channel), shared across all dimension levels. ### Strategy 2: Unpooled (Independent per dimension-channel) **Separate parameter for every dimension-channel combination - no information sharing.** ```python from pymc_marketing.mmm.multidimensional import MMM from pymc_marketing.mmm import GeometricAdstock, LogisticSaturation from pymc_extras.prior import Prior # Unpooled: dims includes both channel AND the extra dimension adstock = GeometricAdstock( priors={"alpha": Prior("Beta", alpha=<ALPHA>, beta=<BETA>, dims=("channel", <DIM>))}, l_max=8 ) saturation = LogisticSaturation( priors={ "lam": Prior("Gamma", mu=<MU>, sigma=<SIGMA>, dims=("channel", <DIM>)), "beta": Prior("Gamma", mu=<MU>, sigma=<SIGMA>, dims=("channel", <DIM>)), } ) mmm = MMM( date_column="date", target_column="sales", channel_columns=["tv", "radio", "digital"], dims=<EXTRA_DIMS>, adstock=adstock, saturation=saturation, ) ``` **Use when:** - Lots of data per dimension level (50+ observations per level recommended) - You believe effects truly vary by market - Markets are very different (e.g., different countries with different media landscapes) **Result:** 3 channels × N dimension levels = 3N alpha values, each estimated independently. ### Strategy 3: Hierarchical / Partial Pooling (RECOMMENDED) **Dimension levels share information through channel-level hyperparameters, but still get dimension-specific estimates.** ```python from pymc_marketing.mmm.multidimensional import MMM from pymc_marketing.mmm import GeometricAdstock, LogisticSaturation from pymc_extras.prior import Prior # Hierarchical: hyperparameters have dims="channel", final param has dims=("channel", <DIM>) adstock = GeometricAdstock( priors={ "alpha": Prior( "Beta", alpha=Prior("Gamma", mu=2, sigma=1, dims="channel"), # Shared across dimension levels beta=Prior("Gamma", mu=5, sigma=2, dims="channel"), # Shared across dimension levels dims=("channel", <DIM>), # But dimension-specific values ) }, l_max=8 ) saturation = LogisticSaturation( priors={ # Lambda: fully pooled (channel efficiency assumed similar across dimension levels) "lam": Prior("Gamma", mu=<MU>, sigma=<SIGMA>, dims="channel"), # Beta: hierarchical (max impact varies by dimension but channels share structure) "beta": Prior( "Normal", mu=Prior("Gamma", mu=0.25, sigma=0.10, dims="channel"), sigma=Prior("Exponential", scale=0.10, dims="channel"), dims=("channel", <DIM>), centered=False, # Non-centered helps MCMC convergence ), } ) mmm = MMM( date_column="date", target_column="sales", channel_columns=["tv", "radio", "digital"], dims=<EXTRA_DIMS>, adstock=adstock, saturation=saturation, ) ``` **Use when:** - Moderate data per dimension level - You want dimension levels to "borrow strength" from each other - Markets are related but not identical (e.g., different US states) **Key insight:** The hierarchical prior allows TV in geo_a to inform TV in geo_b (through shared hyperparameters), while TV never influences radio (independent channel effects). ### Strategy 4: Mixed Pooling (Practical Default) **Mix different strategies for different parameters based on domain knowledge.** ```python from pymc_marketing.mmm.multidimensional import MMM from pymc_marketing.mmm import GeometricAdstock, LogisticSaturation from pymc_extras.prior import Prior # Adstock: unpooled (memory effects can vary significantly by market) adstock = GeometricAdstock( priors={"alpha": Prior("Beta", alpha=<ALPHA>, beta=<BETA>, dims=("channel", <DIM>))}, l_max=<LMAX>, ) # Saturation: mixed saturation = LogisticSaturation( priors={ # Lambda (channel efficiency): pooled - assume similar efficiency across markets "lam": Prior("Gamma", mu=<MU>, sigma=<SIGMA>, dims="channel"), # Beta (max impact): unpooled - market size/potential varies "beta": Prior("Gamma", mu=<MU>, sigma=<SIGMA>, dims=("channel", <DIM>)), } ) mmm = MMM( date_column="date", target_column="sales", channel_columns=["tv", "radio", "digital"], dims=<EXTRA_DIMS>, adstock=adstock, saturation=saturation, ) ``` **This is often the most practical starting point:** - Adstock alpha varies by dimension (different media consumption patterns) - Lambda pooled (channel response shape similar across markets) - Beta varies by dimension (different market sizes) ### Best Practice: Start Simple, Add Complexity From the PyMC-Marketing documentation: > "The choice is primarily driven by computational considerations. Partial pooling is generally a more reasonable assumption but it can make the model slower to estimate, more complicated to debug, and more difficult to reason about." **Recommended progression:** 1. Start with **fully pooled** or **mixed pooling** (Strategy 1 or 4) 2. Fit model, check convergence, validate results 3. If you have enough data and see evidence of dimension-level variation, try **unpooled** (Strategy 2) 4. Only use **hierarchical** (Strategy 3) if you need information sharing AND have convergence issues with unpooled ### Verifying Parameter Shapes After Fitting **ALWAYS check that you got the dimensionality you expected:** ```python # After fitting print("Adstock alpha dims:", mmm.fit_result['adstock_alpha'].dims) print("Adstock alpha shape:", mmm.fit_result['adstock_alpha'].shape) # Expected for 3 channels, 5 dimension levels: # Fully pooled: ('chain', 'draw', 'channel') → shape (N_CHAINS, TOTAL_DRAWS, 3) # Unpooled: ('chain', 'draw', 'channel', <DIM>) → shape (N_CHAINS, TOTAL_DRAWS, 3, 5) # Hierarchical: ('chain', 'draw', 'channel', <DIM>) → shape (N_CHAINS, TOTAL_DRAWS, 3, 5) # If you see shape (N_CHAINS, TOTAL_DRAWS) with no channel/extra dimension, something is WRONG! ``` ## Key Concept: MMM as a GAM Framework PyMC-Marketing is **not only a framework for marketing optimization but also a general-purpose engine for building interpretable Bayesian GAMs**. The architecture enables seamless transitions from standard MMM to fully specified graphical models capturing richer causal relationships. ## Core Capabilities ### 1. Flexible Architecture Progression The framework supports progression from simple to complex models: 1. **Simple Linear Regression** - Automatic scaling and preprocessing - Basic channel effects 2. **Linear MMM with Transformations** - Adstock transformations (carryover effects) - Saturation transformations (diminishing returns) 3. **Multidimensional Hierarchical Models** - Country/region/product dimensions - Dimension-specific parameters - Automatic broadcasting across dimensions 4. **Custom Bayesian GAMs** - Temporal components (trends, seasonality) - Custom additive effects - Fully specified graphical models ### 2. Composable Components All components can be mixed and matched: - Adstock transformations - Saturation functions - Temporal effects - Hierarchical priors - Multiple dimensions ## Model Components in Detail ### Adstock Transformations **Purpose**: Model how marketing impact decays over time (carryover effects)
Ver no GitHub
Este SKILL.md e muito grande, entao o SkillsMP mostra aqui apenas a primeira secao. Ver no GitHub