Anomaly detection sounds fancy, but in my experience, 80% of real-world cases can be solved with surprisingly simple methods.
The Problem
You have a metric—revenue, signups, errors, whatever—and you want to know when something unusual happens. Not just “the number went up” but “the number went up more than expected.”
Method 1: Simple Z-Score
Compare today is value to the historical mean and standard deviation:
z_score = (current_value - historical_mean) / historical_std
is_anomaly = abs(z_score) > 3
When to use: Stable metrics without strong seasonality.
Limitations: Does not handle trends or weekly patterns.
Method 2: Rolling Statistics
Use a rolling window to adapt to changing baselines:
rolling_mean = df["metric"].rolling(window=28).mean()
rolling_std = df["metric"].rolling(window=28).std()
z_score = (df["metric"] - rolling_mean) / rolling_std
When to use: Metrics with gradual trends.
Limitations: Still struggles with seasonality.
Method 3: Seasonal Decomposition
Decompose the time series into trend, seasonal, and residual components. Flag anomalies in the residuals.
from statsmodels.tsa.seasonal import seasonal_decompose
result = seasonal_decompose(df["metric"], period=7)
residuals = result.resid
# Apply z-score to residuals
When to use: Metrics with weekly/monthly patterns.
Method 4: Prophet-based Detection
Facebook Prophet provides uncertainty intervals out of the box:
from prophet import Prophet
model = Prophet(interval_width=0.99)
model.fit(df)
forecast = model.predict(df)
# Flag points outside yhat_upper/yhat_lower
When to use: Complex seasonality, holiday effects.
Practical Tips
- Start simple: Z-scores solve more problems than you would think. I usually start here.
- Tune thresholds: 3-sigma is a starting point, not a rule. Adjust based on your tolerance for false positives.
- Handle missing data: Anomaly detectors hate gaps—fill them thoughtfully.
- Alert fatigue is real: Better to miss some anomalies than cry wolf constantly. I have learned this the hard way.
- Investigate before alerting: Many “anomalies” have mundane explanations.
The Meta-Problem
The hardest part of anomaly detection is not the algorithm—it is defining what counts as an anomaly worth acting on. Work backwards from “what would we do if we saw this alert?” to set appropriate thresholds. If the answer is “nothing,” maybe you do not need that alert.