Rare observations can distort monitoring, fraud review, and data-quality workflows even when no anomaly labels exist. An Isolation Forest learns which numeric rows are easier to isolate from the rest and can flag those rows without a labeled target column.
Every training and incoming row must use the same ordered numeric features. Categorical fields need numeric encoding and missing measurements need imputation before fitting so the detector receives a consistent feature shape.
The contamination value sets the expected outlier share used to choose the decision threshold, while random_state makes the randomized tree splits reproducible. predict() returns 1 for an inlier and -1 for an outlier; a negative decision_function() value places a row on the outlier side of the threshold.
Steps to train an anomaly detector with scikit-learn:
- Create train_anomaly_detector.py with the imports and controlled training rows.
- train_anomaly_detector.py
import numpy as np from sklearn.ensemble import IsolationForest training_names = np.array( [ "baseline-01", "baseline-02", "baseline-03", "baseline-04", "baseline-05", "baseline-06", "spike-01", ] ) training_rows = np.array( [ [10.0, 200.0], [10.4, 198.0], [9.8, 202.0], [10.2, 201.0], [10.1, 199.0], [10.5, 203.0], [42.0, 410.0], ] )
The first six rows form a tight baseline, while spike-01 supplies a known anomaly for the training smoke test.
- Add the unseen evaluation rows below the training arrays.
- train_anomaly_detector.py
evaluation_names = np.array(["incoming-normal", "incoming-spike"]) evaluation_rows = np.array( [ [10.3, 200.5], [35.0, 390.0], ] )
- Add the result formatter below the evaluation rows.
- train_anomaly_detector.py
def print_results(title, names, labels, scores): print(title) for name, label, score in zip(names, labels, scores): state = "outlier" if label == -1 else "inlier" print(f"{name:15s} {state:7s} label={label:2d} score={score: .3f}")
- Add the fitted IsolationForest block below the formatter.
- train_anomaly_detector.py
detector = IsolationForest(contamination=0.15, random_state=42) detector.fit(training_rows)
A contamination value of 0.15 expects roughly one outlier among the seven controlled training rows. Production thresholds should reflect the share of rows that can receive anomaly review.
- Add the prediction and decision-score block below the fitted detector.
- train_anomaly_detector.py
training_labels = detector.predict(training_rows) training_scores = detector.decision_function(training_rows) evaluation_labels = detector.predict(evaluation_rows) evaluation_scores = detector.decision_function(evaluation_rows)
- Add the training and incoming-row reports below the scoring block.
- train_anomaly_detector.py
print_results("Training rows", training_names, training_labels, training_scores) print() print_results( "Incoming rows", evaluation_names, evaluation_labels, evaluation_scores, )
- Add fail-capable anomaly assertions below the report calls.
- train_anomaly_detector.py
assert training_labels[training_names == "spike-01"].item() == -1 assert evaluation_labels[evaluation_names == "incoming-spike"].item() == -1 assert evaluation_scores[evaluation_names == "incoming-spike"].item() < 0
- Run the completed script to verify the known and incoming spikes cross the anomaly threshold.
$ python3 train_anomaly_detector.py Training rows baseline-01 inlier label= 1 score= 0.114 baseline-02 inlier label= 1 score= 0.052 baseline-03 inlier label= 1 score= 0.053 baseline-04 inlier label= 1 score= 0.123 baseline-05 inlier label= 1 score= 0.111 baseline-06 inlier label= 1 score= 0.031 spike-01 outlier label=-1 score=-0.280 Incoming rows incoming-normal inlier label= 1 score= 0.110 incoming-spike outlier label=-1 score=-0.206
The baseline-shaped incoming row remains an inlier, while both spike rows return -1 with negative decision scores. A failed assertion stops the script with a nonzero exit status.
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.