statistics — inference layer for fragility/sensitivity studies
Purpose
The inference owner for the analysis pipeline: Pearson/Spearman/tail correlation, OLS
regression, Cliff’s delta effect size, ensemble dispersion (CI/spread/exceedance), cross-correlation
peak/lag, the near-singular-fraction band, and seeded event-study controls.
Split out of data_analyzer (Jun 18) so that module stays math-primitives-only.
Role in the system
- Companion to data_analyzer (math primitives) and metric_catalog (catalog access) — the three
files the Jun-18 split produced. - data_analyzer re-exports every public name here (
# noqa: E402,F401) so the
signal_measurement facade andtest_data_primitives.pykeep importing throughdata_analyzer. - signal_measurement imports it as
_statsand delegates all correlation/effect-size math to it. - Consumes a few reduction helpers (
finite_numeric_samples,percentile,Reductions,
longest_run_length) lazily from data_analyzer — see Footguns. - Pure consumer of NPZ-derived arrays; never reaches across pipeline boundaries.
Inputs / Outputs
- In: plain 1-D NumPy-coercible signals (paired samples, ensembles of per-run scalars, boolean
episode masks, event-index sets); all functions are NaN-aware and trim to the common finite support. - Out: floats (correlations, effect sizes, fractions),
Packagerecords (linfit,
episode_contrast),(values, survival)arrays (exceedance_curve), and seeded index/window sets
(event-study controls).
Key functions
CorrMethod— Pearson/Spearman selector;coercepermissive (default PEARSON),from_valuestrict —analysis/statistics.py:23pearson_r/spearman_rho— NaN-aware correlation (Spearman = Pearson on average ranks) —:60/:86tail_corr— correlation conditioned on the top-q% ofa(worst-decile association) —:94xcorr_peak_lag— normalized cross-correlation peak and the lag at which it occurs —:107linfit— OLS deg-1 fit →Package(slope, intercept, max_rel_resid)—:124cliffs_delta— nonparametric effect size in [-1, 1] between two samples —:136episode_contrast— the near-singular/clip/dwell fingerprint (Cliff’s delta inside vs outside a mask) —:149ci95/rel_spread/exceedance_curve— ensemble dispersion ACROSS runs/seeds —:171/:181/:191near_singular_fraction— swept-onset fraction below threshold, delegates toReductions.FRAC_BELOW—:203matched_control_pool/matched_control_windows— seeded controls off the forbidden event spans —:219/:227
Footguns
The lazy imports are a deliberate cycle-break, not style
tail_corr,cliffs_delta,episode_contrast,ci95,rel_spread,exceedance_curve, and
near_singular_fractionimportfinite_numeric_samples/percentile/Reductions/
longest_run_lengthfunction-locally. Those live in data_analyzer, which RE-EXPORTS this
module’s names — a module-level import would be a cycle. This file has no module-level dependency
on data_analyzer, so it always imports cleanly regardless of load order. (analysis/INSIGHTS.md)
xcorr_peak_laglag sign is reversed fromnp.correlatePositive lag means
aprecedesb(b is the delayed copy). The lag axis is flipped relative to
np.correlate’s center-relative convention. (analysis/INSIGHTS.md)
near_singular_fractionmust delegate, not re-implementIt routes through
Reductions.FRAC_BELOW(the canonicalnp.mean(x < t)) so a swept-onset
measurement and the catalog’s pinned-0.025frac_belowband (ons_min_Jinmetrics.yaml)
can never drift apart. This function takes an arbitrary onset on any singular-value signal.
(analysis/INSIGHTS.md)
CorrMethod.coercedefaults to PEARSON silentlyAny value that is not
"spearman"or aCorrMethodmember maps to PEARSON (the historical default).
Usefrom_valuewhen an unknown selector should raise. Enum values are lowercase names
(SPEARMAN.value == "spearman"). (analysis/INSIGHTS.md)
Pseudocode (the episode fingerprint)
sig, m = align(signal, mask) # common length, mask → bool
near = finite(sig[m]) # samples during the episode
healthy = finite(sig[~m]) # samples outside it
return Package(
delta = cliffs_delta(near, healthy), # > 0 ⇒ LARGER during the episode
near_mean, healthy_mean, # both finite means
near_frac = mean(m), # episode duty cycle
longest_run = longest_run_length(m), # longest contiguous episode
n_near, n_healthy) # sample counts
Related
data_analyzer · metric_catalog · signal_measurement · orchestrator · terminology
- Long-form derivations:
generated_reports/math/analysis_correlations.md. - Golden tests pin every function against numpy/scipy:
validation/test_data_primitives.py.