Machine Learning

Machine learning for outlier detection: an Isolation Forest example in Python

Use machine learning to flag unusual rows for review. Run an Isolation Forest example, compare simple rules and understand thresholds and false alarms.

Machine learning for outlier detection assigns unusualness to observations so you can decide which rows deserve review. A flag is not proof that a value is incorrect. It may reveal a data-entry error, a rare valid event or a pattern the model does not represent well.

Start with a clear review question and a simple rule. Add a learned detector when combinations of measurements make a fixed rule inadequate. This article uses invented processing batches to show an Isolation Forest example with inline code and output.

Outlier detection and novelty detection

Outlier detection looks for unusual observations in a dataset that may already contain them. Novelty detection learns a reference pattern from data intended to represent normal behavior, then assesses new observations. The training assumptions and supported prediction operations differ between methods.

For this example, the same small dataset contains ordinary-looking batches and one deliberately distant batch. We fit and flag that dataset as an outlier-detection demonstration. It is not an evaluation of how well the method will detect future operational failures.

Decide what should happen after a flag

Possible findingWhat to checkSensible next step
A negative processing durationData validation and unitsCorrect or reject the invalid record
A large but valid batchContext and workloadKeep the row and explain the size
An unusual combination of measurementsSource logs and comparable batchesInvestigate before changing data
Many newly flagged rowsChanges in inputs or workloadReview the detector and reference data

A negative duration does not need machine learning. An unusually long duration for an otherwise ordinary batch might. Distinguishing the two prevents a model from replacing straightforward validation.

Run an Isolation Forest example

Our ten invented batches have two columns: request count and total processing seconds. The first nine are close together. The last contains 120 requests and 900 seconds. We choose a review fraction of 0.1 for this demonstration.

Use Python 3 in a virtual environment. In a terminal, install scikit-learn, which also installs NumPy:

python -m venv .venv
source .venv/bin/activate
python -m pip install scikit-learn

On Windows, activate with .venv\Scripts\activate instead. Copy the Python block into a .py file and run it with python filename.py, or use a notebook cell. The example was run with Python 3.12.3, NumPy 2.5.4 and scikit-learn 1.9.1. All data is invented and included inline.

import numpy as np
from sklearn.ensemble import IsolationForest

# Invented batches: [request count, total processing seconds].
X = np.array([
    [10, 20], [11, 22], [9, 18], [12, 24], [10, 21],
    [11, 21], [9, 19], [12, 23], [10, 19], [120, 900],
])
model = IsolationForest(n_estimators=200, contamination=0.1, random_state=42)
flags = model.fit_predict(X)
flagged = np.flatnonzero(flags == -1)
print("Rows to review (zero-based):", flagged.tolist())
print("Flagged measurements:", X[flagged].tolist())
print("Review count:", len(flagged))
assert set(flags).issubset({-1, 1})

Expected output:

Rows to review (zero-based): [9]
Flagged measurements: [[120, 900]]
Review count: 1

Explain the flag and the threshold

The zero-based index 9 refers to the tenth row. Its measurements are far from the other invented batches, so it becomes the row to inspect under these settings. The estimator uses -1 for flagged observations and 1 for inliers. Those values are flags, not probabilities of an error.

The contamination=0.1 setting influences the training-score threshold. It is a chosen assumption here, not a measured error rate. It does not mean that 10% of real batches are bad, nor guarantee an exact review fraction on every dataset with ties or on future data.

Isolation Forest uses random splits to isolate observations and combines results across trees. The example fixes the random seed and tree count for a reproducible demonstration. A different detector can flag different rows because it encodes a different view of unusualness.

Try it yourself: replace the final row with [120, 240]. That batch is larger but has two processing seconds per request, similar to the small batches. Compare the flags before and after adding a processing-seconds-per-request feature. Decide whether batch size or unusually slow processing is the question you actually care about.

Do not divide by request count without handling zero. A ratio can make sense for this question, but it changes the meaning of the detector's inputs. You must state which representation you used.

Compare the detector with a rule

For our original data, a rule such as total_seconds > 100 also flags only the tenth row. That does not make either approach broadly successful: we deliberately made the example easy. On real data, compare both on the same reviewed cases and count missed cases as well as unnecessary flags.

If the review team can inspect five rows per day, report how many the detector sends them. A high anomaly score has little operational value if the queue is unmanageable or reviewers cannot explain the findings.

When examples have verified outcomes, record precision among reviewed flags and the kinds of known issues missed. Without those outcomes, describe the output as a review queue and measure investigation results as you collect them. Avoid presenting unsupervised flags as detection accuracy.

Common questions

Should I delete all outliers before training another model?

No. A rare valid case may be important to the problem. Investigate the source and document your handling. Removing difficult examples can make later evaluation less representative.

Is an outlier the same as fraud or a failure?

No. Those are outcomes that require their own definitions and evidence. This detector identifies unusual measurements in a fictional batch dataset; it does not determine intent or diagnose a cause.

How do I choose the contamination setting?

Use the method's documentation, reviewed data where available and the consequences of different review volumes. Treat a guessed fraction as an assumption to evaluate, not a discovered property of the data.

Learn to inspect data before fitting detectors

Start with SchoolWhool's lessons on spread and the interquartile range, box plots and data cleaning. They help separate invalid measurements from unusual but plausible observations.

The Data Tools course connects data inspection to Python estimators. Use the Machine Learning syllabus to plan your next model topics and check lesson availability. A free account adds quizzes and saved progress. Pro adds practice for every lesson, projects, certificates and weekly live sessions with Gaurav.

References

The official outlier and novelty detection guide explains the task distinction. The IsolationForest API documents the flags and threshold parameters used here. The batch data and interpretation exercise are original.

Related course

The four libraries every machine learning notebook uses: NumPy arrays and broadcasting, pandas tables, readable Matplotlib charts, and the scikit-learn API.

Open lessons' parts and key terms are free to read, with no account.

What you will be able to do

  • Reason about an array's shape and dtype before an operation runs.
  • Select, filter, group and join tables with pandas.
  • Make charts that answer one question clearly.
  • Use scikit-learn's fit, transform and predict with confidence.