Uncertainty Module#
Drop-in uncertainty-quantification estimators for fitted MaldiDeepKit
classifiers. Three methods share a single
predict_with_uncertainty()
interface and return a common
UncertaintyResult dataclass, so
downstream code can swap methods without touching call sites.
MCDropoutEstimator- Monte Carlo Dropout (Gal and Ghahramani, 2016) with epistemic / aleatoric decomposition.LaplaceEstimator- last-layer or full-network Laplace approximation via the optionallaplace-torchdependency.ConformalPredictor- split conformal prediction with the LAC non-conformity score.
The Laplace estimator requires the uncertainty extra; install it
with pip install "maldideepkit[uncertainty]" (see
Installation). Monte Carlo Dropout and split conformal
prediction need no extras.
UncertaintyResult#
- class maldideepkit.uncertainty.UncertaintyResult(predictions, proba_mean, uncertainty, epistemic, aleatoric, method, metadata=<factory>)[source]#
Bases:
objectContainer for the output of a
BaseUncertaintyEstimator.- Variables:
predictions (ndarray of shape (n_samples,)) – Hard labels drawn from the classifier’s
classes_.proba_mean (ndarray of shape (n_samples, n_classes)) – Mean softmax probabilities. For non-Bayesian methods this is simply the classifier’s
predict_proba()output.uncertainty (ndarray of shape (n_samples,)) – Scalar per-sample uncertainty in
[0, 1]where possible. The precise semantics are method-specific and documented on the producing class.epistemic (ndarray of shape (n_samples,) or None) – Model-uncertainty component, when the method decomposes total uncertainty into epistemic and aleatoric parts.
Nonefor methods that do not decompose.aleatoric (ndarray of shape (n_samples,) or None) – Data-uncertainty component, paired with
epistemic.Nonefor methods that do not decompose.method (str) – Name of the method that produced this result (e.g.
"mc_dropout","laplace","conformal").metadata (dict) – Method-specific extras (per-pass samples for MC Dropout, prediction sets for conformal, predictive variance for Laplace, …).
- Parameters:
BaseUncertaintyEstimator#
- class maldideepkit.uncertainty.BaseUncertaintyEstimator(classifier)[source]#
Bases:
objectAbstract base for every estimator in
maldideepkit.uncertainty.- Parameters:
classifier (
BaseSpectralClassifier) – A fitted MaldiDeepKit classifier. Its preprocessing pipeline (warping, input transform, legacy standardisation) is reused so the uncertainty estimate is produced on inputs identical to those seen at training time.- Raises:
sklearn.exceptions.NotFittedError – If
classifierhas not been fitted.
- __init__(classifier)[source]#
- Parameters:
classifier (
BaseSpectralClassifier)- Return type:
None
- abstractmethod predict_with_uncertainty(X)[source]#
Return predictions and per-sample uncertainty for
X.- Parameters:
X (
Any) – Spectra to score. Must matchclassifier.input_dim_.- Returns:
Predictions, probability mean, scalar uncertainty, optional epistemic / aleatoric decomposition, and method-specific metadata.
- Return type:
MCDropoutEstimator#
- class maldideepkit.uncertainty.MCDropoutEstimator(classifier, n_samples=30, batch_size=None)[source]#
Bases:
BaseUncertaintyEstimatorMonte Carlo Dropout estimator (Gal and Ghahramani, 2016).
Runs
n_samplesstochastic forward passes throughclassifier.model_with dropout layers active and aggregates the resulting softmax distribution into a predictive mean plus an epistemic / aleatoric decomposition.- Parameters:
classifier (
BaseSpectralClassifier) – A fitted classifier whose architecture contains at least onetorch.nn.Dropout(or its 1-D / 2-D / 3-D variants). A warning is emitted if it does not, but the estimator still runs - in that degenerate case alln_samplespasses are identical and epistemic uncertainty collapses to0.n_samples (
int) – Number of stochastic forward passes per call topredict_with_uncertainty(). Higher values reduce variance of the estimate at a linear cost in compute.batch_size (
int|None) – Mini-batch size used to chunk the input through each forward pass. WhenNone, falls back toclassifier.batch_size.
Notes
The scalar
UncertaintyResult.uncertaintyfield is the normalised entropy of the predictive meanH(E[p]). The epistemic / aleatoric decomposition follows Depeweg et al. (2018):aleatoric = E_w[H(p)](mean of per-pass entropies)epistemic = H(E[p]) - E[H(p)](mutual information)
Both components are normalised to
[0, 1]by dividing the raw entropies bylog(n_classes).- __init__(classifier, n_samples=30, batch_size=None)[source]#
- Parameters:
classifier (
BaseSpectralClassifier)n_samples (
int)
- Return type:
None
LaplaceEstimator#
- class maldideepkit.uncertainty.LaplaceEstimator(classifier, subset_of_weights='last_layer', hessian_structure='diag', sigma_noise=1.0)[source]#
Bases:
BaseUncertaintyEstimatorLaplace-approximation uncertainty estimator.
A thin wrapper around the
laplace-torchpackage (aleximmer/Laplace) that fits a Gaussian posterior over the classifier’s weights and turns the predictive variance into a per-sample uncertainty estimate.- Parameters:
classifier (
BaseSpectralClassifier) – A fitted classifier; itsmodel_is reused as the network whose posterior is approximated.subset_of_weights (
str) – Which subset of weights to model."last_layer"is the standard, cheap default and works for any of the MaldiDeepKit backbones whose final layer is atorch.nn.Linear.hessian_structure (
str) – Approximation structure for the Hessian."diag"is the cheapest;"kron"(Kronecker-factored) is more accurate at a moderate compute cost.sigma_noise (
float) – Forwarded tolaplace-torch. For classification it has no effect (it controls the regression noise scale) but is exposed for interface symmetry.
- Raises:
ImportError – If
laplace-torchis not installed.
- __init__(classifier, subset_of_weights='last_layer', hessian_structure='diag', sigma_noise=1.0)[source]#
- Parameters:
classifier (
BaseSpectralClassifier)subset_of_weights (
str)hessian_structure (
str)sigma_noise (
float)
- Return type:
None
- calibrate(X_cal, y_cal, *, batch_size=None)[source]#
Fit the Laplace approximation on
(X_cal, y_cal).Applies the classifier’s preprocessing to
X_cal, builds an internalDataLoader, fits the Laplace approximation, and runs marginal-likelihood prior precision optimisation.- Parameters:
- Returns:
self, with the fitted Laplace approximation stored onla_.- Return type:
- predict_with_uncertainty(X)[source]#
Return predictions and Laplace-derived uncertainty for
X.Uses
pred_type="glm"andlink_approx="probit"to map the weight-space posterior into a softmax-domain predictive distribution. Per-sample predictive variance is summarised as the mean diagonal entry, then squashed into[0, 1]via1 - exp(-v)and stored asepistemic. The scalarUncertaintyResult.uncertaintyfield is the normalised entropy of the predictive mean;aleatoricis the non-negative residualuncertainty - epistemic.- Raises:
RuntimeError – If
calibrate()has not been called.- Parameters:
X (
Any)- Return type:
ConformalPredictor#
- class maldideepkit.uncertainty.ConformalPredictor(classifier, alpha=0.1, score='lac')[source]#
Bases:
BaseUncertaintyEstimatorSplit conformal predictor with the LAC non-conformity score.
- Parameters:
classifier (
BaseSpectralClassifier) – A fitted classifier whosepredict_proba()-style softmax scores act as the underlying probability estimate.alpha (
float) – Miscoverage level in(0, 1). The target marginal coverage is1 - alpha.score (
str) – Non-conformity score. Currently only"lac"is supported:s(x, y) = 1 - p_hat(y | x).
Notes
The
UncertaintyResult.uncertaintyfield is the prediction set size normalised byn_classes:1 / n_classesfor a singleton set,1.0when every class is included. Empty sets (which can occur with very small calibration sets) yield0and are flagged in metadata via the empty-set count.- __init__(classifier, alpha=0.1, score='lac')[source]#
- Parameters:
classifier (
BaseSpectralClassifier)alpha (
float)score (
str)
- Return type:
None
- calibrate(X_cal, y_cal)[source]#
Compute the conformal quantile from calibration data.
- Parameters:
- Returns:
self, withquantile_,calibration_coverage_, andn_calibration_populated.- Return type:
- predict_with_uncertainty(X)[source]#
Return conformal predictions and prediction sets for
X.- Returns:
method="conformal"withepistemicandaleatoricset toNone. Boolean prediction sets are stored inmetadata["prediction_sets"]with shape(n_samples, n_classes); the empirical calibration coverage is stored inmetadata["calibration_coverage"].- Return type:
- Raises:
RuntimeError – If
calibrate()has not been called.- Parameters:
X (
Any)
Examples#
Monte Carlo Dropout on a fitted attention-MLP:
import numpy as np
from maldideepkit import MaldiMLPClassifier
from maldideepkit.uncertainty import MCDropoutEstimator
rng = np.random.default_rng(0)
X = rng.standard_normal((200, 6000)).astype("float32")
y = rng.integers(0, 2, size=200)
clf = MaldiMLPClassifier(random_state=0).fit(X, y)
est = MCDropoutEstimator(clf, n_samples=30)
result = est.predict_with_uncertainty(X[:10])
# result.predictions, result.proba_mean, result.uncertainty,
# result.epistemic, result.aleatoric
Split conformal prediction with calibration:
from sklearn.model_selection import train_test_split
from maldideepkit.uncertainty import ConformalPredictor
X_tr, X_cal, y_tr, y_cal = train_test_split(
X, y, test_size=0.3, stratify=y, random_state=0,
)
clf = MaldiMLPClassifier(random_state=0).fit(X_tr, y_tr)
cp = ConformalPredictor(clf, alpha=0.1).calibrate(X_cal, y_cal)
result = cp.predict_with_uncertainty(X[:10])
sets = result.metadata["prediction_sets"] # (10, n_classes) bool
Laplace approximation (requires the optional laplace-torch
dependency):
from maldideepkit.uncertainty import LaplaceEstimator
la = LaplaceEstimator(clf, subset_of_weights="last_layer",
hessian_structure="diag")
la.calibrate(X_cal, y_cal)
result = la.predict_with_uncertainty(X[:10])