pod.infer_best_distribution

infer_best_distribution(residuals, X, bandwidth)

Selects the best statistical distribution for the standardized residuals using AIC.

The residuals are divided by their local standard deviation (predict_local_std) to give z-scores, which are fitted by maximum likelihood to each of 12 candidate distributions: Normal, Gumbel (right and left), Weibull (min and max), Gamma, Exponential, Logistic, Laplace, Student’s t, Beta and Uniform ([M25] Sec. 2f). The fit with the lowest AIC wins.

[digiqual] Bounded-support families (Weibull, Gamma, Exponential, Beta, Uniform) have a free location parameter, so maximum likelihood can push a support endpoint right up against the most extreme z-score. Such a degenerate fit can win on AIC yet give PoD values of exactly 0 or 1 just outside the observed range, and kinked a90/95 values. A fit is therefore only accepted if its support contains every z-score with a margin of 5 % of their range, and its log-likelihood is finite. [M25] used UQLab’s inference, which similarly excludes unsuitable distributions.

Parameters

Name Type Description Default
residuals np.ndarray Raw residuals from the mean model. required
X np.ndarray Input locations for the residuals. required
bandwidth float Bandwidth used for local standardization. required

Returns

Name Type Description
tuple[str, tuple] tuple[str, tuple]: - best_name: The SciPy name of the best-fitting distribution (e.g., ‘norm’). - best_params: The fitted parameters for that distribution (e.g., loc, scale).

Examples

import numpy as np
from digiqual.pod import infer_best_distribution

X = np.linspace(0, 10, 200)
residuals = np.random.default_rng(0).gumbel(0, 1 + 0.1 * X)
dist_name, dist_params = infer_best_distribution(residuals, X, bandwidth=0.5)
print(f"Best distribution: {dist_name}")