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.

설치로 이동

소스 정보

저장소
pymc-labs/decision-lab
최근 소스 활동
2026년 3월 31일 12:08
감지된 SKILL.md 언어
영어
스타
195
포크
14

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
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)
GitHub에서 보기
이 SKILL.md는 매우 커서 SkillsMP가 여기에는 첫 섹션만 미리 보여줍니다. GitHub에서 보기