Skip to content

Feature Request: Add support for Demand Generation vs. Demand Capture channel distinction in MMM #1840

@lfiaschi

Description

@lfiaschi

Feature Description

Add the ability to distinguish between "demand generation" and "demand capture" marketing channels in the MMM class, recognizing that these channel types have fundamentally different behaviors and causal relationships.

Motivation

In real-world marketing, channels can be broadly categorized into two types:

  1. Demand Generation Channels: Channels where marketers can directly control spend levels (e.g., TV, Facebook, YouTube, display advertising)
  2. Demand Capture Channels: Channels where spend levels are essentially "pulled" by existing demand rather than "pushed" by the advertiser (e.g., branded search, affiliates, shopping/marketplace ads)

Currently, PyMC-Marketing treats all channels equally, which can lead to:

  • Misattribution of causal effects
  • Incorrect budget optimization recommendations
  • Failure to capture the true dynamics where demand generation activities drive demand capture spending

This distinction is particularly important for:

  • Brands with significant branded search spend
  • E-commerce companies with affiliate programs
  • Any business where some channels respond to demand rather than create it

Proposed Implementation

1. Channel Type Specification

Allow users to specify channel types when initializing the MMM:

mmm = MMM(
    channel_columns=['tv', 'facebook', 'youtube', 'branded_search', 'affiliates'],
    channel_types={
        'tv': 'demand_generation',
        'facebook': 'demand_generation',
        'youtube': 'demand_generation', 
        'branded_search': 'demand_capture',
        'affiliates': 'demand_capture'
    },
    # ... other parameters
)

2. Model Structure Changes

For demand capture channels, the model should:

  • Include dependencies on demand generation channel activities
  • Model the induced spend as a function of demand generation activities
  • Apply different saturation curves (demand capture channels often have different saturation patterns)

Conceptually:

demand_capture_spend[t] = f(baseline_demand[t] + sum(demand_gen_effects[t]))

3. Implementation Details

class MMM(BaseValidateMMM):
    def __init__(
        self,
        # ... existing parameters
        channel_types: dict[str, Literal[\"demand_generation\", \"demand_capture\"]] | None = None,
        capture_dependency_lag: int = 7,  # how many days demand gen affects demand capture
    ):
        self.channel_types = channel_types or {}
        self.capture_dependency_lag = capture_dependency_lag
        
    def _create_demand_dependencies(self):
        \"\"\"Create the dependency structure between demand gen and capture channels\"\"\"
        if not self.channel_types:
            return
            
        demand_gen_channels = [ch for ch, type in self.channel_types.items() 
                               if type == \"demand_generation\"]
        demand_cap_channels = [ch for ch, type in self.channel_types.items() 
                               if type == \"demand_capture\"]
        
        # Model induced spend in demand capture channels
        for cap_channel in demand_cap_channels:
            # Create lagged effects from demand generation activities
            for gen_channel in demand_gen_channels:
                # Add dependency modeling here
                pass

4. Budget Optimization Considerations

The budget optimizer should:

  • Recognize that demand capture budgets are partially determined by demand generation activities
  • Optimize demand generation channels as primary levers
  • Treat demand capture channels as responsive rather than directly controllable

Example Use Case

A DTC brand spends on:

  • Demand Generation: TV, Facebook, YouTube (creating awareness and interest)
  • Demand Capture: Branded search, Google Shopping (capturing existing demand)

Without this distinction, the model might recommend cutting TV spend because it shows lower direct ROI, missing that TV drives branded search volume. With proper channel typing, the model would understand the full causal chain.

Benefits

  1. More Accurate Attribution: Properly accounts for indirect effects
  2. Better Budget Recommendations: Optimizes the true causal levers
  3. Realistic Modeling: Matches how marketing actually works
  4. Improved Forecasting: Better predictions when changing channel mix

References

  • Recast Technical Documentation describes this approach
  • Common in advanced MMM implementations at major brands
  • Aligns with marketing theory on push vs. pull channels

Implementation Priority

This would be a significant enhancement that would benefit many users, particularly those with:

  • Significant branded search spend
  • Affiliate programs
  • Multi-channel attribution challenges

Would love to hear thoughts from the community on this feature and potential implementation approaches!

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions