ROAS and Metrics
Use this page for channel-efficiency outputs and aggregate predictive metrics.
AMMM3 separates these into two surfaces:
mmm.summaryandmmm.datafor ROAS and cost-per-target outputsmmm.diagnosticsfor RMSE, MAE, NRMSE, NMAE, and CRPS
For contribution tables that feed these ratios, see Contributions and Decomposition.
Element-wise ROAS and cost per target
The lowest-level efficiency accessors live on mmm.data:
roas_samples = mmm.data.get_elementwise_roas(original_scale=True)
cost_per_target_samples = mmm.data.get_elementwise_cost_per_target(
original_scale=True,
)
These are direct ratios built from fitted media contributions and channel spend:
- ROAS = contribution / spend
- cost per target = spend / contribution
The arrays are element-wise over time, channel, and any panel dims, with
posterior sample dimensions on top.
AMMM3 returns NaN when it would otherwise divide by zero.
Summarise ROAS
Use mmm.summary.roas(...) for a tidy summary table:
roas_df = mmm.summary.roas(
hdi_probs=[0.80, 0.94],
frequency="monthly",
start_date="2024-01-01",
end_date="2024-06-30",
)
AMMM3 applies start_date and end_date before any optional aggregation.
The returned table includes:
- identifying columns such as
date,channel, and any paneldims meanmedian- HDI bound columns such as
abs_error_94_lowerandabs_error_94_upper
Summarise cost per target
For conversion-style targets, use cost_per_target(...):
cpa_df = mmm.summary.cost_per_target(frequency="monthly")
This is the same retained summary surface that mmm.summary.efficiency() uses
for target_type="conversion".
Use the default efficiency metric
AMMM3 chooses the default efficiency metric from the target type:
target_type | mmm.summary.efficiency() returns | Label |
|---|---|---|
revenue | roas() | ROAS |
conversion | cost_per_target() | CPA |
You can inspect the selected metric with:
metric_key = mmm.summary.efficiency_metric
metric_label = mmm.summary.efficiency_metric_label
Export channel spend
Use channel_spend() when you want the raw spend table with no posterior
aggregation:
spend_df = mmm.summary.channel_spend()
This returns the observed channel spend with columns such as date, channel,
panel dims, and channel_data.
Predictive error metrics
Predictive metrics live under mmm.diagnostics.predictive_summary():
mmm.sample_posterior_predictive(
X=X,
random_seed=42,
progressbar=False,
)
predictive_metrics = mmm.diagnostics.predictive_summary()
The returned one-row DataFrame includes:
rmsemaenrmsenmaecrpsresidual_meanresidual_std
These metrics are calculated from the stored posterior predictive samples and the observed target.
Practical guidance
- Use
roas()for revenue targets. - Use
cost_per_target()for conversion targets. - Use
efficiency()when you want target-type-aware reporting. - Sample posterior predictive values before using predictive metrics.
Common pitfalls
- Interpreting AMMM3 ROAS as something other than contribution divided by spend
- Forgetting that zero spend or zero contribution produces
NaN - Using predictive diagnostics before calling
sample_posterior_predictive(...)