ROAS and Metrics
Use this page for channel-efficiency outputs and aggregate predictive metrics.
Abacus 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:
These are direct ratios built from fitted media contributions and the model’s
channel inputs, stored as constant_data.channel_data. Abacus does not look
up a separate monetary spend series or convert exposures to spend.
With original_scale=True, the financial interpretations require:
| Ratio | Required units | Interpretation |
|---|---|---|
| contribution / channel input | Revenue and monetary spend in a common currency | ROAS: revenue per unit of spend |
| channel input / contribution | Monetary spend and a conversion-count target | Cost per conversion: currency per conversion |
Use consistent currency, time periods and panel aggregation for both sides of the ratio. For example, £200 of contribution divided by £100 of spend gives ROAS 2; £200 divided by 1,000 impressions gives £0.20 per impression, not ROAS. If contributions are left on the scaled target space, the result is not in original business units.
These are model-conditional contribution ratios. Their posterior intervals do not establish incremental causal returns; see Causal Identification.
The arrays are element-wise over time, channel, and any panel dims, with
posterior sample dimensions on top.
Abacus returns NaN when it would otherwise divide by zero.
Summarise ROAS
Use mmm.summary.roas(...) for a tidy summary table:
Abacus 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(...):
This is the same retained summary surface that mmm.summary.efficiency() uses
for target_type="conversion".
Use the default efficiency metric
Abacus chooses the default efficiency metric and label from the target type. This selects an accessor; it does not validate currency or convert channel inputs to spend. The financial labels below require the units stated above:
target_type |
mmm.summary.efficiency() returns |
Label |
|---|---|---|
revenue |
roas() |
ROAS |
conversion |
cost_per_target() |
CPA |
You can inspect the selected metric with:
Export channel spend
Use channel_spend() when you want the raw channel-input table with no posterior
aggregation:
This returns the observed channel inputs with columns such as date, channel,
panel dims, and channel_data. They represent spend only when the model’s
channel inputs are monetary amounts.
Predictive error metrics
Predictive metrics live under 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. See the canonical
predictive metric definitions,
including the observed-range denominator for NRMSE/NMAE and its constant-target
NaN case.
Practical guidance
- Use
roas()for revenue targets with monetary channel inputs in a common currency. - Use
cost_per_target()for conversion-count targets with monetary channel inputs. - Use
efficiency()when you want target-type-aware reporting. - Sample posterior predictive values before using predictive metrics.
Common pitfalls
- Reporting revenue per exposure as ROAS because a channel input was labelled spend without checking its units
- Forgetting that zero spend or zero contribution produces
NaN - Using predictive diagnostics before calling
sample_posterior_predictive(...)