Datalens.ai
← All algorithms

OUTLIER-DETECTION

LocalOutlierFactor

Unsupervised Outlier Detection using the Local Outlier Factor (LOF).

Example of usage

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

Domains of usage

Fraud detection · Network intrusion detection · Equipment monitoring

Usage / limitations

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

−Limitations: Neighbour count and feature scaling strongly affect results; high-dimensional data can reduce contrast.

Mathematical formula

LOFₖ(x) = avgₒ∈Nₖ(x) lrdₖ(o) / lrdₖ(x)

LOF compares local neighbour density; unusually low density compared with nearby points suggests an outlier.

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.neighbors import LocalOutlierFactor

# 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 = LocalOutlierFactor(n_neighbors=8, contamination=0.10)
# Collect the algorithm output in an interpretable result.
result = [row["machine_id"] for row, flag in zip(sensor_readings["records"], model.fit_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-001', 'PUMP-007', 'PUMP-024'], ("Unexpected anomaly_ids:", result)
print("Expected output verified")