Skip to content

Predicted Target ≠ Sum of Contributions OOS period (Case Study Notebook) #1835

@RamiFisherTW

Description

@RamiFisherTW

(Reopen of issue 1826)

I'm experiencing a discrepancy between direct predictions and reconstructed predictions from model components when using sample_posterior_predictive.
Steps to Reproduce:

  1. Generate test predictions with component decomposition:
y_pred_test = mmm.sample_posterior_predictive(
    X_pred=X_test[0:1],
    include_last_observations=True,
    original_scale=True,
    var_names=["y", "channel_contribution", "intercept", "fourier_contribution", 
               "control_contribution", "yearly_seasonality_contribution"],
    extend_idata=False,
    progressbar=True,
    random_seed=rng
)
  1. Decompose components and reconstruct total prediction:

# Extract component contributions
control_contrib_pred_test = y_pred_test['control_contribution'].mean(dim=["sample"]).sum()
channel_contrib_pred_test = y_pred_test['channel_contribution'].mean(dim=["sample"]).sum()
intercept_pred_test = y_pred_test['intercept'].mean(dim=["sample"]) * mmm.get_target_transformer()["scaler"].scale_[0]
seasonality_pred_test = y_pred_test['yearly_seasonality_contribution'].mean(dim=["sample"]).sum()

# Reconstruct total prediction
total_prediction_test = control_contrib_pred_test + channel_contrib_pred_test + intercept_pred_test + seasonality_pred_test

Issue:

Reconstructed sum: 67,879,827.31
Direct prediction (y_pred_test['y'].mean(dim=["sample"]).sum()): 72,591,532.16
Difference: ~4,711,704.85

When using sample_response_distribution with the same allocation strategy:


response = mmm.sample_response_distribution(
    allocation_strategy=allocation_strategy,  # Using X_test[0] budget
    time_granularity=model_granularity,
    num_periods=num_periods,
    noise_level=0.0,
)

I get the same channel contribution value (27,098,727.90), which seems consistent.
Questions:

Why is there a discrepancy between direct prediction and the sum of components?
Are there any missing components in the reconstruction? - (It seems to be the intercept)
Why does budget_optimize only return channel contribution as the optimized value when I set 'total_contribution' as the response?

Any insights would be appreciated!

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions