Incrementality.compute_joint_incremental_contribution#
- Incrementality.compute_joint_incremental_contribution(frequency, start_date=None, end_date=None, include_carryover=True, num_samples=None, random_state=None, counterfactual_spend_factor=0.0, central_tendency='median')[source]#
Compute the incremental contribution of all channels together.
Perturbs every channel in the same counterfactual and returns one number per period, rather than perturbing channels one at a time.
This is a different estimand from summing
compute_incremental_contribution()overchannel, and the difference is not an error in either of them. Per-channel increments are unilateral: each answers “what changes if this channel’s spend is scaled by α, holding the others at their actual spend” – at the default α = 0, “what would we lose without this channel”. Whenever the response is not additive in the channels – underlink="log", or when amu_effectmixes channels before they reach the response – the two disagree by the interaction between the channels. Underlink="identity"with no channel-dependent effects they coincide exactly.The direction of the disagreement is not fixed. With strictly positive contributions at α = 0 the unilateral numbers sum to more than the joint, since interaction mass is counted by every channel that touches it; with contributions of mixed sign, or with α > 1, the sum can fall short instead. Either way it is not a total.
Report this number when the question is “how much of the target does media drive in total”, and the per-channel ones when the question is “which channel should I cut”. Adding the per-channel numbers up answers neither.
- Parameters:
- frequency{“original”, “weekly”, “monthly”, “quarterly”, “yearly”, “all_time”}
Time aggregation frequency, as in
compute_incremental_contribution().- start_date
strorpd.Timestamp, optional Start date for evaluation window. If None, uses start of fitted data.
- end_date
strorpd.Timestamp, optional End date for evaluation window. If None, uses end of fitted data.
- include_carryoverbool, default=True
Include adstock carryover effects.
- num_samples
intorNone, optional Number of posterior samples to use.
- random_state
RandomStateorGeneratororNone, optional Random state for reproducible subsampling.
- counterfactual_spend_factor
float, default=0.0 Multiplicative factor applied to every channel’s spend.
- central_tendency{“median”, “mean”}, default=”median”
Central tendency of the predictions being differenced.
- Returns:
xr.DataArrayJoint incremental contribution in original scale, with dimensions
(chain, draw, date, *custom_dims), or withoutdatewhenfrequency == "all_time". There is nochanneldimension: the number is not attributable to a single channel.
See also
compute_incremental_contributionPer-channel, unilateral increments.
Examples
Total media incrementality, and how far the per-channel numbers are from it:
joint = mmm.incrementality.compute_joint_incremental_contribution( frequency="all_time" ) unilateral = mmm.incrementality.compute_incremental_contribution( frequency="all_time" ) interaction = ( unilateral.sum("channel").mean(("chain", "draw")) / joint.mean(("chain", "draw")) - 1 )