Skip to main content

Statistical Testing & Calibration

4.4 Statistical Testing & Calibration​

Statistical Testing​

The simudyne.engine.statistics module provides non-parametric tests for comparing model outputs, distribution distance metrics, and multiple-comparison corrections.

Two-Sample Tests (each returns a TestResult with statistic, p_value, reject_null, effect_size):

FunctionSignatureDescription
ks_two_sample(x, y, alpha=0.05) -> TestResultKolmogorov-Smirnov: max CDF difference
anderson_darling_two_sample(x, y, alpha=0.05) -> TestResultAnderson-Darling: weighted tail sensitivity
permutation_test(x, y, statistic_fn=None, n_permutations=10000, seed=42, alpha=0.05) -> TestResultPermutation: exact p-value via resampling
mann_whitney_u(x, y, alternative="two-sided", alpha=0.05) -> TestResultMann-Whitney U: rank-based location test

Bootstrap Methods:

FunctionDescription
bootstrap_ci(data, statistic_fn, n_bootstrap=10000, alpha=0.05, seed=42)BCa confidence interval for any statistic
bootstrap_two_sample(x, y, statistic_fn, n_bootstrap=10000, seed=42, alpha=0.05)Two-sample bootstrap test

Distribution Distances (each returns a float):

FunctionSignatureDescription
wasserstein_distance(x, y) -> floatEarth mover's distance (L1 optimal transport)
energy_distance(x, y) -> floatEnergy distance (Szekely & Rizzo)
mmd_distance(x, y, kernel="rbf", bandwidth=None) -> floatMaximum Mean Discrepancy with RBF kernel
jsd_distance(x, y, n_bins=50) -> floatJensen-Shannon divergence (symmetric KL)

Multiple-Comparison Corrections (for controlling family-wise error rate when running many tests):

FunctionSignatureDescription
bonferroni_correction(results: List[TestResult], alpha=0.05) -> MultipleTestResultConservative: alpha/n
holm_correction(results: List[TestResult], alpha=0.05) -> MultipleTestResultStep-down Holm-Bonferroni
benjamini_hochberg_fdr(results: List[TestResult], alpha=0.05) -> MultipleTestResultBH-FDR: controls false discovery rate
benjamini_yekutieli_fdr(results: List[TestResult], alpha=0.05) -> MultipleTestResultBY-FDR: handles dependent tests

ABC-SMC Calibration​

The ABCSMCCalibrator performs likelihood-free Bayesian calibration using Approximate Bayesian Computation with Sequential Monte Carlo. It does not require a likelihood function --- instead, it compares simulated features to observed features using a distance metric, and uses importance sampling with adaptive epsilon contraction to converge on the posterior distribution of parameters.

class ABCSMCCalibrator:
def __init__(
self,
priors: List[Prior], # Prior distributions for each parameter
feature_fn: Callable, # Function that extracts features from traces
epsilon_decay: float = 0.9, # Per-generation epsilon contraction rate
min_acceptance_rate: float = 0.01, # Stop if acceptance rate drops below this
) -> None

def calibrate(
self,
model_cls: Type[ABMModel],
obs_features: Dict[str, float], # Observed feature values to match
base_config: Dict[str, Any], # Base model config (non-calibrated params)
n_particles: int = 500, # Number of particles in the population
n_generations: int = 10, # Maximum number of SMC generations
mc_seeds: int = 5, # Seeds per particle evaluation
max_workers: int = 0, # Parallel workers (0 = auto)
progress_callback: Optional[Callable] = None,
) -> ABCSMCResult

The Prior dataclass supports five distribution types:

DistributionParametersDescription
"uniform"low, highFlat prior over [low, high]
"log_uniform"low, highUniform in log-space (for scale parameters)
"truncated_normal"mean, std, low, highGaussian truncated to [low, high]
"beta"alpha, beta, low, highBeta distribution scaled to [low, high]
"scipy"scipy_distAny frozen scipy.stats distribution

The ABCSMCResult provides posterior analysis:

Method / PropertyReturn TypeDescription
map_estimate()Dict[str, float]Maximum a posteriori parameter values
posterior_meanDict[str, float]Weighted posterior mean
posterior_stdDict[str, float]Weighted posterior standard deviation
posterior_ci_95Dict[str, Tuple]95% credible intervals
effective_sample_sizefloatESS of weighted particles
summary_table()strFormatted table of all posteriors
posterior_samples(n)np.ndarrayWeighted resamples from posterior
posterior_predictive(feature_fn, n)Dict[str, ndarray]Predictive distribution of features

The compare_models() function calibrates multiple competing models and ranks them by complexity-penalised distance, implementing the "description over fitting" principle: a simpler model that fits nearly as well is preferred over a complex model that fits marginally better.