Skip to main content

Lightweight drift and anomaly monitoring for production ML models.

Project description

canary-ml

Drop-in drift and anomaly monitoring for production ML models.

PyPI Python License: MIT Tests

One line wraps your model. Every .predict() call logs drift metrics, detects anomalies, and fires an alert when something shifts — without adding latency or requiring any infrastructure.

Project page · Guide & manual · Live demo


Install

pip install "canary-ml[keras]"

Keras/TensorFlow support included. For a minimal install without Keras:

pip install canary-ml

Requires Python 3.9+. Core dependencies: numpy, scipy, scikit-learn, rich.


Quickstart

from canary_ml import ModelMonitor

monitor = ModelMonitor(
    model=your_model,           # any sklearn-compatible model
    reference_data=X_train,     # baseline distribution
    alert_threshold=0.2,        # PSI threshold for alerts
    log_path="./canary_logs",
    verbose=True,
)

# Drop-in replacement — monitoring is a side effect of predict()
predictions = monitor.predict(X_new)

# Inspect the latest report
report = monitor.get_report()
print(report.summary())
# DriftReport | psi=0.41 | features_drifted=3/8 | anomaly_rate=3.2% | ALERT

# Launch the live dashboard
monitor.serve_dashboard(port=8501)
# → http://localhost:8501

What it monitors

  • PSI — global distribution shift. < 0.1 stable · 0.1–0.2 moderate · > 0.2 alert. Requires ≥ 200 samples per batch; use drift_detected (KS-based) for smaller batches.
  • KS test — per-feature Kolmogorov-Smirnov (continuous features, p < 0.05 = drift). Sample-size–corrected.
  • Chi² test — per-feature chi-squared (categorical features, ≤ 20 unique values).
  • Anomaly detection — ensemble of Isolation Forest + z-score (|z| > 3).
  • Confidence estimate — label-free accuracy proxy from predicted probabilities. Accurate when probabilities are well-calibrated; overestimates if the model is overconfident.

Alert callback

def my_alert(report):
    send_slack(f"Drift alert: PSI={report.psi_score:.2f}")

monitor = ModelMonitor(..., on_alert=my_alert)

Dashboard

monitor.serve_dashboard(port=8501)

Stdlib HTTP server, no extra dependencies. Auto-refreshes every 5 seconds. Can also run standalone:

python -m canary_ml.server ./canary_logs 8501

API reference

ModelMonitor

ModelMonitor(
    model,                      # sklearn-compatible model with .predict()
    reference_data,             # np.ndarray or pd.DataFrame, shape (n, features)
    alert_threshold=0.2,        # PSI threshold for drift alert
    performance_threshold=0.05, # accuracy drop (pp) below reference that fires a perf alert
    anomaly_contamination=0.05, # expected fraction of anomalies; alert fires at 3×
    categorical_threshold=20,   # max unique values for a feature to be treated as categorical
    log_path="./canary_logs",
    verbose=False,
    on_alert=None,              # callable(DriftReport) fired on alert
)
Method Returns Description
.predict(X) same as model Runs model + monitoring as a side effect
.get_report() DriftReport | None Latest monitoring report
.serve_dashboard(port=8501) Starts dashboard server in background thread

DriftReport

Attribute Type Description
psi_score float Global PSI vs reference
drift_detected bool True if any feature's KS/chi² p < 0.05 (soft warning)
ks_results dict Per-feature {statistic, p_value, drifted}
features_drifted int Count of features with p < 0.05 (computed property)
anomaly_rate float Fraction of samples flagged as anomalies
alert_triggered bool True if PSI > threshold, anomaly rate is high, or performance drops
estimated_accuracy float | None Confidence estimate; None if no predict_proba
reference_accuracy float | None Confidence estimate on reference data
performance_delta float | None estimated_accuracy − reference_accuracy
performance_alert bool True if delta < −performance_threshold
timestamp str ISO 8601

Testing

pip install -e ".[dev]"
pytest                        # 44 tests
pytest --cov=canary_ml

License

MIT © Aitor Bazo

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

canary_ml-1.1.0.tar.gz (29.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

canary_ml-1.1.0-py3-none-any.whl (25.9 kB view details)

Uploaded Python 3

File details

Details for the file canary_ml-1.1.0.tar.gz.

File metadata

  • Download URL: canary_ml-1.1.0.tar.gz
  • Upload date:
  • Size: 29.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for canary_ml-1.1.0.tar.gz
Algorithm Hash digest
SHA256 56fc6375ff0dfd20b31d4d00a92ec2681cbc2195c3aa7b0768f5fa81c1981dd6
MD5 816e160bf817c0bfca57ec7c2e35b62a
BLAKE2b-256 cba8f67ab65f2105be8d1efea4b38db410394c2156cd2eba699ebc117b423ef3

See more details on using hashes here.

File details

Details for the file canary_ml-1.1.0-py3-none-any.whl.

File metadata

  • Download URL: canary_ml-1.1.0-py3-none-any.whl
  • Upload date:
  • Size: 25.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for canary_ml-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 235251a36c63d8ad3f7e15307e8caf635cd747d654bcd99fcbee0e43f4740b6c
MD5 2aeb4f13aada1a342f616f0bcd96c387
BLAKE2b-256 656555d0bcf951c66df3edaa99b3ac2bbe257a5a618c6e6c806afa0cd85b78f2

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page