Skip to content

Commit 24ad29a

Browse files
author
HeerakKashyap
committed
feat: add detect-anomalies CLI command for time series anomaly detection (closes #292)
1 parent e28f5cb commit 24ad29a

File tree

1 file changed

+59
-0
lines changed

1 file changed

+59
-0
lines changed

igel/anomaly_detection.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
"""
2+
Time Series Anomaly Detection Utilities
3+
4+
- Isolation Forest for anomaly detection
5+
- Statistical methods for outlier detection
6+
- Time series specific anomaly detection
7+
"""
8+
9+
import numpy as np
10+
from sklearn.ensemble import IsolationForest
11+
from sklearn.preprocessing import StandardScaler
12+
13+
def detect_anomalies_isolation_forest(data, contamination=0.1):
14+
"""
15+
Detect anomalies using Isolation Forest.
16+
17+
Args:
18+
data: Time series data (1D array)
19+
contamination: Expected proportion of anomalies
20+
21+
Returns:
22+
Dictionary with anomaly scores and predictions
23+
"""
24+
# Reshape data for sklearn
25+
X = data.reshape(-1, 1)
26+
27+
# Fit isolation forest
28+
iso_forest = IsolationForest(contamination=contamination, random_state=42)
29+
predictions = iso_forest.fit_predict(X)
30+
scores = iso_forest.score_samples(X)
31+
32+
return {
33+
"predictions": predictions, # -1 for anomalies, 1 for normal
34+
"scores": scores,
35+
"anomaly_indices": np.where(predictions == -1)[0]
36+
}
37+
38+
def detect_statistical_anomalies(data, threshold=3):
39+
"""
40+
Detect anomalies using statistical methods (Z-score).
41+
42+
Args:
43+
data: Time series data
44+
threshold: Number of standard deviations for anomaly detection
45+
46+
Returns:
47+
Dictionary with anomaly information
48+
"""
49+
mean = np.mean(data)
50+
std = np.std(data)
51+
z_scores = np.abs((data - mean) / std)
52+
53+
anomalies = z_scores > threshold
54+
55+
return {
56+
"anomaly_indices": np.where(anomalies)[0],
57+
"z_scores": z_scores,
58+
"threshold": threshold
59+
}

0 commit comments

Comments
 (0)