Outlier detection often begins with a rule such as “flag values more than three standard deviations from the mean.” That works reasonably well for approximately normal data without severe contamination, but the same extreme observations you want to detect can move both the mean and the standard deviation.

Median absolute deviation, usually abbreviated MAD, provides a more robust alternative.

Why mean and standard deviation can be fragile

Consider response times in milliseconds:

98, 101, 103, 99, 102, 100, 97, 3100

The value 3100 is obviously unusual. It also pulls the mean upward and inflates the standard deviation, making the threshold less representative of the typical observations.

The median changes much less when one extreme value appears. MAD builds on that property.

Compute MAD in two steps

For observations x, first compute the median:

m = median(x)

Then compute each absolute deviation from that median and take their median:

MAD = median(|x - m|)

A simple Python implementation using only the standard library is:

from statistics import median


def median_absolute_deviation(values):
    center = median(values)
    return median(abs(value - center) for value in values)

The result is a robust measure of spread around the median.

Turn MAD into a comparable score

A common robust score is based on the distance from the median divided by MAD:

def mad_scores(values):
    center = median(values)
    mad = median(abs(value - center) for value in values)
    if mad == 0:
        raise ValueError("MAD is zero")
    return [abs(value - center) / mad for value in values]

Larger values are farther from the typical center relative to the robust spread.

When comparing the score with familiar normal-distribution thresholds, practitioners sometimes multiply by a consistency factor so MAD estimates the standard deviation for normal data. The factor is useful only when that interpretation matters; the core robust ranking does not depend on it.

Thresholds are domain decisions

There is no universal MAD cutoff that turns every observation into objectively normal or abnormal.

A threshold should reflect:

  • the cost of false positives;
  • the cost of missed anomalies;
  • sample size;
  • expected distribution shape;
  • whether the data is naturally heavy-tailed;
  • whether values are independent or time-dependent.

A useful workflow is to rank observations by robust score, inspect the tail, and choose a threshold with validation data or domain expertise.

Do not pick a number simply because another dataset used it.

Handle zero MAD explicitly

MAD can be zero when at least half the observations equal the median.

For example:

5, 5, 5, 5, 6, 20

The median absolute deviation is zero, so division-based scores are undefined.

This is not a numerical inconvenience to hide with a tiny epsilon. It says the central portion of the sample has no observed spread at the measurement resolution.

Possible responses include:

  • use a domain-specific absolute tolerance;
  • increase measurement precision;
  • use another robust scale estimator;
  • treat any deviation from the dominant value as a separate categorical condition.

Choose deliberately rather than silently forcing a finite score.

Segment before detecting outliers

A global distribution can mix several legitimate populations.

Suppose API latency differs strongly by endpoint. A 400 ms request might be abnormal for /health and completely normal for /reports/export.

Compute robust statistics within meaningful groups when the groups represent different generating processes:

endpoint -> median -> MAD -> robust score

The same principle applies to regions, device classes, product tiers, or operating modes.

Too much segmentation, however, creates tiny samples and unstable estimates. Set minimum sample requirements and fall back to broader groups when necessary.

Time series need temporal context

A single global median can hide regime changes. In a time series, compare observations with a rolling or seasonal baseline when recent context matters.

For example:

value at t
  compared with
median and MAD of the previous N comparable observations

Be careful not to let future observations influence a historical anomaly decision if the method will run online. The evaluation pipeline should mimic the information available at prediction time.

Outliers are not automatically bad data

A statistically unusual observation can be:

  • a genuine rare event;
  • a measurement error;
  • a new operating regime;
  • an attack or abuse signal;
  • an important customer behavior;
  • a data-pipeline defect.

Detection should trigger investigation or downstream policy, not unconditional deletion.

Removing every outlier before modeling can erase the exact events a system needs to understand.

Compare robust and non-robust summaries

A useful diagnostic table includes both:

mean
standard deviation
median
MAD
minimum / maximum
selected quantiles

Large differences between robust and non-robust summaries can reveal skew, heavy tails, or contamination.

This comparison is often more informative than an outlier flag alone.

Common pitfalls

Assuming normality because a threshold looks familiar

MAD is robust, but a chosen score cutoff still needs validation for the actual distribution.

Ignoring groups with different baselines

Mixtures can make legitimate observations look anomalous or hide true anomalies.

Dividing by zero MAD without thinking

Zero spread requires a policy, not an arbitrary numerical patch.

Deleting flagged rows automatically

Outliers can contain the most valuable information in the dataset.

Evaluating time-series rules with future data

Use historical windows that match the eventual operating environment.

Use robust statistics as a diagnostic tool

MAD is attractive because it is simple, interpretable, and resistant to a small number of extreme observations. It is especially useful as a first-line detector when the mean and standard deviation are visibly unstable.

The best results come from combining robust scores with domain segmentation, realistic thresholds, and investigation of flagged cases. Outlier detection is not just a formula for removing points; it is a method for identifying observations whose behavior deserves a closer look.