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
آخر نشاط في المصدر
٣١ مارس ٢٠٢٦ في ١٢:٠٨
لغة SKILL.md المكتشفة
الإنجليزية
النجوم
١٩٠
التفرعات
١٤

خيارات التثبيت

يُحدَّد 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