Ensemble Model

Ensemble combinator for anomaly detectors.

This module defines an AnomalyEnsemble that can wrap multiple BaseDetector compatible detectors and combine their scores into a single ensemble score and anomaly decision.

class telemetry_anomdet.models.ensemble.AnomalyEnsemble(models: Mapping[str, BaseDetector], combine: str = 'mean', normalize: str = 'robust', percentile: float = 95.0)[source]

Bases: BaseDetector

Stacking ensemble of anomaly detectors.

Parameters:
  • models (Mapping[str, BaseDetector]) –

    Named detectors to include in the ensemble. Example:

    {

    “pca”: PCAAnomaly(n_components = 10), “iso”: IsolationForestAnomaly(), “gdn”: GDN(epochs = 50), “tranad”: TranAD(window_size = 50),

    }

  • combine (str, default = "mean") – Strategy for combining normalized per-model scores. One of "mean", "median", "max".

  • normalize (str, default = "robust") – Per-model score normalization before combining. One of "none", "minmax", "robust". Statistics are estimated from training data.

  • percentile (float, default = 95.0) – Percentile of ensemble training scores used as the default anomaly threshold. Passed to BaseDetector._set_post_fit().

  • fit) (Attributes (set after)

  • --------------------------

  • decision_scores (np.ndarray, shape (n_windows,)) – Ensemble anomaly scores on training data.

  • threshold (float) – Default anomaly cutoff derived from training scores at percentile.

  • labels (np.ndarray, shape (n_windows,)) – Binary anomaly labels on training data. 0 = normal, 1 = anomaly.

fit(X: ndarray, y: ndarray | None = None) AnomalyEnsemble[source]

Fit all detectors and estimate normalization statistics.

Parameters:
  • X (np.ndarray, shape (n_windows, window_size, n_features)) – Windowed telemetry tensor from windowify().

  • y (ignored)

Returns:

self

Return type:

AnomalyEnsemble

decision_function(X: ndarray, *, normalize: bool = True) ndarray[source]

Compute ensemble anomaly scores.

Parameters:
  • X (np.ndarray, shape (n_windows, window_size, n_features))

  • normalize (bool, default=True) – Apply configured normalization before combining.

Returns:

scores – Higher = more anomalous.

Return type:

np.ndarray, shape (n_windows,)

score_components(X: ndarray) Dict[str, ndarray][source]

Per-model raw anomaly scores before combination.

This is the input to SHAPExplainer; SHAP perturbs X and measures how each channel affects each model’s score independently.

Parameters:

X (np.ndarray, shape (n_windows, window_size, n_features))

Returns:

{model_name: np.ndarray of shape (n_windows,)}

Return type:

dict

AnomalyEnsemble wraps any set of BaseDetector subclasses and combines their scores into a single ensemble score. All detectors receive 3D input (n_windows, window_size, n_features). Classical models flatten internally, deep models consume it directly. The ensemble handles all routing.

score_components() is the SHAP hook: it returns raw per-model scores before normalization or combination, allowing SHAPExplainer to attribute the ensemble decision back to individual sensor channels.

The combine strategy ("mean" / "median" / "max") and normalize method ("robust" / "minmax" / "none") are tuned on the SMAP validation split in Phase 2. "robust" + "mean" is the default.