Response Scale Semantics

Purpose

DSAMbayes models can operate on an identity (level) or log response scale. This page defines how response scale is detected, stored, and used for post-fit reporting, so that operators understand which scale their outputs are on and how KPI-scale conversions work.

Response scale detection

Response scale is determined at construction time by detect_response_scale(), which inspects the left-hand side of the formula:

Formula LHS Detected transform Response scale label
kpi ~ ... identity response_level
log(kpi) ~ ... log response_log

The detected value is stored in two model-object fields:

  • .response_transform"identity" or "log". Describes the mathematical transform applied to the response before modelling.
  • .response_scale"identity" or "log". Used as a label when reporting whether outputs are on the model scale or the KPI scale.

Both fields are set by the constructor and confirmed by pre_flight_checks().

Model scale vs KPI scale

Concept Identity response Log response
Model scale Raw KPI units Log of KPI units
KPI scale Same as model scale exp() of model scale
Coefficient interpretation Unit change in KPI per unit change in predictor Approximate percentage change in KPI per unit change in predictor

For identity-response models, model scale and KPI scale are identical. For log-response models, fitted values and residuals on the model scale are in log units and must be exponentiated to obtain KPI-scale values.

Post-fit accessors and scale behaviour

fitted() — model scale

fitted() returns predicted values on the model scale. For identity-response models this is the KPI scale. For log-response models this is the log scale.

fit_tbl <- fitted(model)
# fit_tbl$fitted is on model scale

fitted_kpi() — KPI scale

fitted_kpi() applies the inverse transform draw-wise before summarising. For log-response models the default conversion (since v1.2.2) uses the conditional-mean estimator:

$$E[Y] = \exp\!\bigl(\mu + \tfrac{\sigma^2}{2}\bigr)$$

This is the bias-corrected back-transform that accounts for the log-normal variance term. The previous behaviour (v1.2.0) used the simpler exp(mu) estimator, which corresponds to the conditional median on the KPI scale. To retain that behaviour, pass log_response = "median":

# Default (v1.2.2): conditional mean — bias-corrected
kpi_tbl <- fitted_kpi(model)

# Explicit median — equivalent to pre-v1.2.2 behaviour
kpi_tbl <- fitted_kpi(model, log_response = "median")

The output includes source_response_scale (the model’s response scale), response_scale = "kpi", and conversion_method ("conditional_mean" or "point_exp") to label the result.

observed() — model scale

observed() returns the observed response on the model scale after unscaling (if scale=TRUE).

observed_kpi() — KPI scale

observed_kpi() returns the observed response on the KPI scale. For log-response models, this applies exp() to the model-scale observed values.

to_kpi_scale() helper

The internal function to_kpi_scale(x, response_scale) implements the conversion:

  • If response_scale == "log": returns exp(x).
  • Otherwise: returns x unchanged.

This function is used consistently by fitted_kpi(), observed_kpi(), and runner artefact writers.

Runner artefact scale conventions

Runner artefact writers use the response scale metadata to determine which scale to report:

Artefact Scale Notes
fitted.csv Model scale Direct output from fitted()
observed.csv Model scale Direct output from observed()
posterior_summary.csv Model scale Coefficient summaries on model scale
Fit time series plot KPI scale Uses fitted_kpi() and observed_kpi() for visual comparison
Fit scatter plot KPI scale Same as fit time series
Diagnostics (residuals) Model scale Residuals computed on model scale
Budget optimisation outputs KPI scale Response curves and allocations reported on KPI scale

Interaction with scale = TRUE

The scale flag and response scale are orthogonal:

  • scale = TRUE standardises predictors and response by centring and dividing by standard deviation before Stan fitting. Coefficients and fitted values are back-transformed to the original scale by get_posterior().
  • Response scale determines whether the original scale is levels (identity) or logs (log).

Both transformations compose: a log-response model with scale=TRUE first takes the log of the response (via the formula), then standardises the logged values. Post-fit, draws are first unscaled, then (for KPI-scale outputs) exponentiated.

Jensen’s inequality and draw-wise conversion

When converting log-scale posterior draws to KPI scale, DSAMbayes applies exp() to each draw individually before computing summaries (mean, median, credible intervals). This is the correct Bayesian approach because:

  • E[exp(X)] ≠ exp(E[X]) when X has non-zero variance (Jensen’s inequality).
  • Draw-wise conversion preserves the full posterior distribution on the KPI scale.
  • Summary statistics (mean, quantiles) computed after conversion correctly reflect KPI-scale uncertainty.

Practical guidance

  • Use identity-response models when the KPI is naturally additive and coefficients should represent unit changes.
  • Use log-response models when the KPI is naturally multiplicative, when variance scales with level, or when the response must remain positive.
  • Always check response_scale_label(model) before interpreting coefficient magnitudes.
  • Use fitted_kpi() for business reporting; use fitted() for diagnostics.
  • Do not manually exponentiate posterior means from log-response models. Use fitted_kpi() or to_kpi_scale() on individual draws.

Cross-references