OUTLIER-DETECTION
LedoitWolf
LedoitWolf Estimator.
Example of usage
Identify unusual pump readings or estimate the covariance structure among motor temperature, vibration, and power consumption.
Domains of usage
Portfolio risk modelling · High-dimensional sensing · Medical data analysis
Usage / limitations
+Use when: Use this method to analyse dependencies and variability in multivariate measurements.
−Limitations: Estimates depend on feature scaling, sample size and the modelling assumptions; validate them for the application.
Mathematical formula
Σ̂ = (1 − λ)S + λμI
Shrinkage blends empirical covariance with a scaled identity matrix to reduce noisy covariance estimates.
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)
sensor_readings = {'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}]}
# 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 LedoitWolf
# 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 = LedoitWolf()
# Fit the model to the readings.
model.fit(X)
# Collect the algorithm output in an interpretable result.
result = dict(zip(feature_names, np.round(np.diag(model.covariance_), 3).tolist()))
# Display the result for inspection.
print('variance_by_feature:', result)
# Expected output: verify the model result against known readings.
expected = {'motor_temp_c': 1.0, 'vibration_mm_s': 1.0, 'power_kw': 1.0}
# Compare rounded estimates within 0.001 to allow tiny numeric differences.
assert result.keys() == expected.keys() and all(
abs(result[feature] - expected[feature]) <= 0.001
for feature in expected
), ("Unexpected estimates:", result)
print("Expected output verified")
# 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 LedoitWolf
# 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 = LedoitWolf()
# Fit the model to the readings.
model.fit(X)
# Collect the algorithm output in an interpretable result.
result = dict(zip(feature_names, np.round(np.diag(model.covariance_), 3).tolist()))
# Display the result for inspection.
print('variance_by_feature:', result)
# Expected output: verify the model result against known readings.
expected = {'motor_temp_c': 1.0, 'vibration_mm_s': 1.0, 'power_kw': 1.0}
# Compare rounded estimates within 0.001 to allow tiny numeric differences.
assert result.keys() == expected.keys() and all(
abs(result[feature] - expected[feature]) <= 0.001
for feature in expected
), ("Unexpected estimates:", result)
print("Expected output verified")