File size: 2,004 Bytes
b0add2b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
"""Tests for the offline baseline comparison script."""

import pytest

from scripts.compare_baselines import run_comparison

ONLINE_KEY = "Mahalanobis + ADWIN (online)"


def test_comparison_returns_three_methods():
    """run_comparison returns results for all three methods."""
    results = run_comparison(seed=42, verbose=False)
    assert "Z-Score (max |z|>2.5)" in results
    assert "Isolation Forest (batch)" in results
    assert ONLINE_KEY in results


def test_all_metrics_in_valid_range():
    """All returned metrics are floats in [0, 1] (or nan for AUC edge cases)."""
    results = run_comparison(seed=42, verbose=False)
    for name, m in results.items():
        for key in ("precision", "recall", "f1"):
            assert 0.0 <= m[key] <= 1.0, f"{name} {key}={m[key]} out of range"
        if m["roc_auc"] == m["roc_auc"]:  # skip NaN
            assert 0.0 <= m["roc_auc"] <= 1.0, f"{name} roc_auc={m['roc_auc']} out of range"


def test_online_method_has_latency():
    """The online method reports mean per-observation latency in microseconds."""
    results = run_comparison(seed=42, verbose=False)
    online = results[ONLINE_KEY]
    assert "mean_latency_us" in online
    assert online["mean_latency_us"] > 0


def test_mahalanobis_beats_zscore_on_f1():
    """Mahalanobis + ADWIN should outperform Z-Score on F1 (catches contextual anomalies)."""
    results = run_comparison(seed=42, verbose=False)
    online_f1 = results[ONLINE_KEY]["f1"]
    zscore_f1 = results["Z-Score (max |z|>2.5)"]["f1"]
    assert online_f1 > zscore_f1, (
        f"Mahalanobis F1={online_f1:.3f} should exceed Z-Score F1={zscore_f1:.3f}"
    )


def test_results_are_reproducible():
    """Two runs with the same seed produce identical results."""
    r1 = run_comparison(seed=42, verbose=False)
    r2 = run_comparison(seed=42, verbose=False)
    for name in r1:
        for key in ("precision", "recall", "f1"):
            assert r1[name][key] == r2[name][key], f"{name} {key} not reproducible"