Datalens.ai
← All algorithms

OUTLIER-DETECTION

EllipticEnvelope

An object for detecting outliers in a Gaussian distributed dataset.

Example of usage

Identify unusual pump readings or estimate the covariance structure among motor temperature, vibration, and power consumption.

Domains of usage

Industrial condition monitoring · Fraud detection · Manufacturing quality control

Usage / limitations

+Use when: Use this method to identify unusual multivariate sensor readings.

−Limitations: Assumes an approximately elliptical inlier distribution; strong non-Gaussian behaviour can impair detection.

Mathematical formula

D²(x) = (x − μ)ᵀ Σ⁻¹ (x − μ)

Mahalanobis distance measures how far a sensor observation lies from the robust centre, accounting for correlations. Large distances indicate potential anomalies.

Sample dataShow
{
  "variable": "sensor_readings",
  "domain": "industrial predictive maintenance",
  "feature_names": [
    "motor_temp_c",
    "vibration_mm_s",
    "power_kw"
  ],
  "records": [
    {
      "machine_id": "PUMP-001",
      "motor_temp_c": 57.0,
      "vibration_mm_s": 1.1,
      "power_kw": 7.3
    },
    {
      "machine_id": "PUMP-002",
      "motor_temp_c": 58.2,
      "vibration_mm_s": 1.31,
      "power_kw": 7.59
    },
    {
      "machine_id": "PUMP-003",
      "motor_temp_c": 59.4,
      "vibration_mm_s": 1.52,
      "power_kw": 7.88
    },
    {
      "machine_id": "PUMP-004",
      "motor_temp_c": 60.6,
      "vibration_mm_s": 1.73,
      "power_kw": 8.17
    },
    {
      "machine_id": "PUMP-005",
      "motor_temp_c": 61.8,
      "vibration_mm_s": 1.94,
      "power_kw": 8.46
    },
    {
      "machine_id": "PUMP-006",
      "motor_temp_c": 63.0,
      "vibration_mm_s": 1.14,
      "power_kw": 8.75
    },
    {
      "machine_id": "PUMP-007",
      "motor_temp_c": 64.2,
      "vibration_mm_s": 1.35,
      "power_kw": 7.37
    },
    {
      "machine_id": "PUMP-008",
      "motor_temp_c": 57.17,
      "vibration_mm_s": 1.56,
      "power_kw": 7.66
    },
    {
      "machine_id": "PUMP-009",
      "motor_temp_c": 58.37,
      "vibration_mm_s": 1.77,
      "power_kw": 7.95
    },
    {
      "machine_id": "PUMP-010",
      "motor_temp_c": 59.57,
      "vibration_mm_s": 1.98,
      "power_kw": 8.24
    },
    {
      "machine_id": "PUMP-011",
      "motor_temp_c": 60.77,
      "vibration_mm_s": 1.18,
      "power_kw": 8.53
    },
    {
      "machine_id": "PUMP-012",
      "motor_temp_c": 61.97,
      "vibration_mm_s": 1.39,
      "power_kw": 8.82
    },
    {
      "machine_id": "PUMP-013",
      "motor_temp_c": 63.17,
      "vibration_mm_s": 1.6,
      "power_kw": 7.44
    },
    {
      "machine_id": "PUMP-014",
      "motor_temp_c": 64.37,
      "vibration_mm_s": 1.81,
      "power_kw": 7.73
    },
    {
      "machine_id": "PUMP-015",
      "motor_temp_c": 57.34,
      "vibration_mm_s": 2.02,
      "power_kw": 8.02
    },
    {
      "machine_id": "PUMP-016",
      "motor_temp_c": 58.54,
      "vibration_mm_s": 1.22,
      "power_kw": 8.31
    },
    {
      "machine_id": "PUMP-017",
      "motor_temp_c": 59.74,
      "vibration_mm_s": 1.43,
      "power_kw": 8.6
    },
    {
      "machine_id": "PUMP-018",
      "motor_temp_c": 60.94,
      "vibration_mm_s": 1.64,
      "power_kw": 8.89
    },
    {
      "machine_id": "PUMP-019",
      "motor_temp_c": 62.14,
      "vibration_mm_s": 1.85,
      "power_kw": 7.51
    },
    {
      "machine_id": "PUMP-020",
      "motor_temp_c": 63.34,
      "vibration_mm_s": 2.06,
      "power_kw": 7.8
    },
    {
      "machine_id": "PUMP-021",
      "motor_temp_c": 64.54,
      "vibration_mm_s": 1.26,
      "power_kw": 8.09
    },
    {
      "machine_id": "PUMP-022",
      "motor_temp_c": 57.51,
      "vibration_mm_s": 1.47,
      "power_kw": 8.38
    },
    {
      "machine_id": "PUMP-023",
      "motor_temp_c": 58.71,
      "vibration_mm_s": 1.68,
      "power_kw": 8.67
    },
    {
      "machine_id": "PUMP-024",
      "motor_temp_c": 91.4,
      "vibration_mm_s": 8.9,
      "power_kw": 15.6
    }
  ]
}

Code example (Python)

# DataLens.ai example
# Domain: industrial predictive maintenance.
# Input: sensor_readings comes from the Sample data section (included when copied).

# Import NumPy for numerical arrays and feature calculations.
import numpy as np
# Import the estimator used by this method.
from sklearn.covariance import EllipticEnvelope

# Select the named sensor features to analyse.
feature_names = sensor_readings["feature_names"]
# Convert named sensor readings into a numerical feature matrix.
X = np.array([[row[feature] for feature in feature_names]
              for row in sensor_readings["records"]], dtype=float)
# Scale temperature, vibration and power to comparable units.
X = (X - X.mean(axis=0)) / X.std(axis=0)
# Create the algorithm model with its configured parameters.
model = EllipticEnvelope(contamination=0.10, random_state=0)
# Fit the model to the readings.
model.fit(X)
# Collect the algorithm output in an interpretable result.
result = [row["machine_id"] for row, flag in zip(sensor_readings["records"], model.predict(X)) if flag == -1]
# Display the result for inspection.
print('anomaly_ids:', result)

# Expected output: verify the model result against known readings.
assert result == ['PUMP-007', 'PUMP-014', 'PUMP-024'], ("Unexpected anomaly_ids:", result)
print("Expected output verified")