Skip to content

Structural Diagnostics

This page documents diagnostics for structural misspecification checks after fitting:

  • posterior pair plots for geometry and parameter dependence,
  • residual-versus-predictor plots for nonlinearity detection.

Both write outputs to 50_diagnostics/.

from src.diagnostics.pair_plot import generate_pair_plot
generate_pair_plot(
model: Any,
config: dict[str, Any],
results_dir: str,
) -> str | None
FilenameStage folderDescription
pair_plot.png50_diagnostics/Pairwise scatter plot for available variables among beta_channel, alpha, lam, with divergence markers when available.
  • Requires at least two target posterior variables to plot.
  • Uses divergences=True only when idata.sample_stats["diverging"] exists.
  • Returns saved path on success, else None.
from src.diagnostics.residuals_vs_predictors import generate_residuals_vs_predictors
generate_residuals_vs_predictors(
model: Any,
X_train: pd.DataFrame,
y_train: pd.Series | np.ndarray,
config: dict[str, Any],
results_dir: str,
) -> list[str]
Filename patternStage folderDescription
residuals_vs_{channel}.png50_diagnostics/One plot per media spend column from config["media"][*]["spend_col"], with residual scatter and LOWESS trend (if statsmodels is available).
  • Computes residuals as observed - median posterior predictive.
  • Attempts inverse-transform if target scaling is active.
  • Returns list of saved paths (possibly empty).
DiagnosticSignalTypical interpretation
Pair plot with divergence concentrationSampler geometry issuePotential funnel/identifiability problem; revisit parameterisation and priors.
Strong curved LOWESS in residuals vs spendMissed nonlinearitySaturation/adstock specification may be inadequate for that channel.
Residual trend around non-zero meanSystematic biasRevisit controls, trend/seasonality design, or likelihood assumptions.
from src.diagnostics.pair_plot import generate_pair_plot
from src.diagnostics.residuals_vs_predictors import generate_residuals_vs_predictors
generate_pair_plot(driver.model, driver.config, driver.results_dir)
paths = generate_residuals_vs_predictors(
driver.model,
driver.X_train,
driver.y_train,
driver.config,
driver.results_dir,
)
print(f"Generated {len(paths)} residual plots")
  • Stage: 50_diagnostics/.
  • These are structural diagnostics that complement hard machine gates.
  • They support analyst gate review and model revision decisions when residual shape or posterior geometry indicates misspecification.