tsadmetrics 0.1.10__py3-none-any.whl → 0.1.12__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- docs/conf.py +43 -0
- tests/test_binary.py +6 -6
- tsadmetrics/binary_metrics.py +383 -65
- tsadmetrics/metric_utils.py +18 -5
- tsadmetrics/non_binary_metrics.py +142 -16
- tsadmetrics/utils.py +1 -1
- {tsadmetrics-0.1.10.dist-info → tsadmetrics-0.1.12.dist-info}/METADATA +1 -1
- {tsadmetrics-0.1.10.dist-info → tsadmetrics-0.1.12.dist-info}/RECORD +10 -9
- {tsadmetrics-0.1.10.dist-info → tsadmetrics-0.1.12.dist-info}/top_level.txt +1 -0
- {tsadmetrics-0.1.10.dist-info → tsadmetrics-0.1.12.dist-info}/WHEEL +0 -0
tsadmetrics/binary_metrics.py
CHANGED
@@ -9,6 +9,8 @@ from pate.PATE_metric import PATE
|
|
9
9
|
def point_wise_recall(y_true: np.array, y_pred: np.array):
|
10
10
|
"""
|
11
11
|
Calculate point-wise recall for anomaly detection in time series.
|
12
|
+
Esta métrica consiste en el recall clásico, sin tener en cuenta el contexto
|
13
|
+
temporal.
|
12
14
|
Implementation of https://link.springer.com/article/10.1007/s10618-023-00988-8
|
13
15
|
|
14
16
|
Parameters:
|
@@ -21,7 +23,6 @@ def point_wise_recall(y_true: np.array, y_pred: np.array):
|
|
21
23
|
m = Pointwise_metrics(len(y_true),y_true,y_pred)
|
22
24
|
m.set_confusion()
|
23
25
|
TP,FN = m.tp,m.fn
|
24
|
-
#TP, _, FP, FN = get_tp_tn_fp_fn_point_wise(y_true, y_pred)
|
25
26
|
if TP == 0:
|
26
27
|
return 0
|
27
28
|
return TP / (TP + FN)
|
@@ -29,6 +30,8 @@ def point_wise_recall(y_true: np.array, y_pred: np.array):
|
|
29
30
|
def point_wise_precision(y_true: np.array, y_pred: np.array):
|
30
31
|
"""
|
31
32
|
Calculate point-wise precision for anomaly detection in time series.
|
33
|
+
Esta métrica consiste en la precisión clásica, sin tener en cuenta el contexto
|
34
|
+
temporal.
|
32
35
|
Implementation of https://link.springer.com/article/10.1007/s10618-023-00988-8
|
33
36
|
|
34
37
|
Parameters:
|
@@ -38,7 +41,6 @@ def point_wise_precision(y_true: np.array, y_pred: np.array):
|
|
38
41
|
Returns:
|
39
42
|
float: The point-wise precision score, which is the ratio of true positives to the sum of true positives and false positives.
|
40
43
|
"""
|
41
|
-
#TP, _, FP, FN = get_tp_tn_fp_fn_point_wise(y_true, y_pred)
|
42
44
|
m = Pointwise_metrics(len(y_true),y_true,y_pred)
|
43
45
|
m.set_confusion()
|
44
46
|
TP,FP = m.tp,m.fp
|
@@ -49,6 +51,8 @@ def point_wise_precision(y_true: np.array, y_pred: np.array):
|
|
49
51
|
def point_wise_f_score(y_true: np.array, y_pred: np.array, beta=1):
|
50
52
|
"""
|
51
53
|
Calculate point-wise F-score for anomaly detection in time series.
|
54
|
+
Esta métrica consiste en la F-score clásica, sin tener en cuenta el contexto
|
55
|
+
temporal.
|
52
56
|
Implementation of https://link.springer.com/article/10.1007/s10618-023-00988-8
|
53
57
|
|
54
58
|
Parameters:
|
@@ -71,7 +75,12 @@ def point_wise_f_score(y_true: np.array, y_pred: np.array, beta=1):
|
|
71
75
|
|
72
76
|
def point_adjusted_recall(y_true: np.array, y_pred: np.array):
|
73
77
|
"""
|
74
|
-
|
78
|
+
This metric is based on the standard recall score, but applies a temporal adjustment
|
79
|
+
to the predictions before computing it. Specifically, for each ground-truth anomalous segment,
|
80
|
+
if at least one point within that segment is predicted as anomalous, all points in the segment
|
81
|
+
are marked as correctly detected. The adjusted predictions are then compared to the ground-truth
|
82
|
+
labels using the standard point-wise recall formulation.
|
83
|
+
|
75
84
|
Implementation of https://link.springer.com/article/10.1007/s10618-023-00988-8
|
76
85
|
|
77
86
|
Parameters:
|
@@ -84,7 +93,6 @@ def point_adjusted_recall(y_true: np.array, y_pred: np.array):
|
|
84
93
|
if np.sum(y_pred) == 0:
|
85
94
|
return 0
|
86
95
|
m = PointAdjust(len(y_true),y_true,y_pred)
|
87
|
-
#m.adjust()
|
88
96
|
TP,FN = m.tp,m.fn
|
89
97
|
if TP == 0:
|
90
98
|
return 0
|
@@ -93,6 +101,11 @@ def point_adjusted_recall(y_true: np.array, y_pred: np.array):
|
|
93
101
|
def point_adjusted_precision(y_true: np.array, y_pred: np.array):
|
94
102
|
"""
|
95
103
|
Calculate point-adjusted precision for anomaly detection in time series.
|
104
|
+
This metric is based on the standard precision score, but applies a temporal adjustment
|
105
|
+
to the predictions before computing it. Specifically, for each ground-truth anomalous segment,
|
106
|
+
if at least one point within that segment is predicted as anomalous, all points in the segment
|
107
|
+
are marked as correctly detected. The adjusted predictions are then compared to the ground-truth
|
108
|
+
labels using the standard point-wise precision formulation.
|
96
109
|
Implementation of https://link.springer.com/article/10.1007/s10618-023-00988-8
|
97
110
|
|
98
111
|
Parameters:
|
@@ -105,7 +118,6 @@ def point_adjusted_precision(y_true: np.array, y_pred: np.array):
|
|
105
118
|
if np.sum(y_pred) == 0:
|
106
119
|
return 0
|
107
120
|
m = PointAdjust(len(y_true),y_true,y_pred)
|
108
|
-
#m.adjust()
|
109
121
|
TP,FP = m.tp,m.fp
|
110
122
|
if TP == 0:
|
111
123
|
return 0
|
@@ -114,6 +126,11 @@ def point_adjusted_precision(y_true: np.array, y_pred: np.array):
|
|
114
126
|
def point_adjusted_f_score(y_true: np.array, y_pred: np.array, beta=1):
|
115
127
|
"""
|
116
128
|
Calculate point-adjusted F-score for anomaly detection in time series.
|
129
|
+
This metric is based on the standard F-score, but applies a temporal adjustment
|
130
|
+
to the predictions before computing it. Specifically, for each ground-truth anomalous segment,
|
131
|
+
if at least one point within that segment is predicted as anomalous, all points in the segment
|
132
|
+
are marked as correctly detected. The adjusted predictions are then compared to the ground-truth
|
133
|
+
labels using the standard point-wise F-Score formulation.
|
117
134
|
Implementation of https://link.springer.com/article/10.1007/s10618-023-00988-8
|
118
135
|
|
119
136
|
Parameters:
|
@@ -138,12 +155,17 @@ def point_adjusted_f_score(y_true: np.array, y_pred: np.array, beta=1):
|
|
138
155
|
def delay_th_point_adjusted_recall(y_true: np.array, y_pred: np.array, k: int):
|
139
156
|
"""
|
140
157
|
Calculate delay thresholded point-adjusted recall for anomaly detection in time series.
|
158
|
+
This metric is based on the standard recall score, but applies a temporal adjustment
|
159
|
+
to the predictions before computing it. Specifically, for each ground-truth anomalous segment,
|
160
|
+
if at least one point within the first k time steps of the segment is predicted as anomalous,
|
161
|
+
all points in the segment are marked as correctly detected. The adjusted predictions are then
|
162
|
+
used to compute the standard point-wise recall formulation.
|
141
163
|
Implementation of https://link.springer.com/article/10.1007/s10618-023-00988-8
|
142
164
|
|
143
165
|
Parameters:
|
144
166
|
y_true (np.array): The ground truth binary labels for the time series data.
|
145
167
|
y_pred (np.array): The predicted binary labels for the time series data.
|
146
|
-
k (int):
|
168
|
+
k (int): Maximum number of time steps from the start of an anomaly segment within which a prediction must occur for the segment to be considered detected.
|
147
169
|
|
148
170
|
Returns:
|
149
171
|
float: The delay thresholded point-adjusted recall score, which is the ratio of true positives to the sum of true positives and false negatives.
|
@@ -159,12 +181,17 @@ def delay_th_point_adjusted_recall(y_true: np.array, y_pred: np.array, k: int):
|
|
159
181
|
def delay_th_point_adjusted_precision(y_true: np.array, y_pred: np.array, k: int):
|
160
182
|
"""
|
161
183
|
Calculate delay thresholded point-adjusted precision for anomaly detection in time series.
|
184
|
+
This metric is based on the standard precision score, but applies a temporal adjustment
|
185
|
+
to the predictions before computing it. Specifically, for each ground-truth anomalous segment,
|
186
|
+
if at least one point within the first k time steps of the segment is predicted as anomalous,
|
187
|
+
all points in the segment are marked as correctly detected. The adjusted predictions are then
|
188
|
+
used to compute the standard point-wise precision fromulation.
|
162
189
|
Implementation of https://link.springer.com/article/10.1007/s10618-023-00988-8
|
163
190
|
|
164
191
|
Parameters:
|
165
192
|
y_true (np.array): The ground truth binary labels for the time series data.
|
166
193
|
y_pred (np.array): The predicted binary labels for the time series data.
|
167
|
-
k (int):
|
194
|
+
k (int): Maximum number of time steps from the start of an anomaly segment within which a prediction must occur for the segment to be considered detected.
|
168
195
|
|
169
196
|
Returns:
|
170
197
|
float: The delay thresholded point-adjusted precision score, which is the ratio of true positives to the sum of true positives and false positives.
|
@@ -180,12 +207,18 @@ def delay_th_point_adjusted_precision(y_true: np.array, y_pred: np.array, k: int
|
|
180
207
|
def delay_th_point_adjusted_f_score(y_true: np.array, y_pred: np.array, k: int, beta=1):
|
181
208
|
"""
|
182
209
|
Calculate delay thresholded point-adjusted F-score for anomaly detection in time series.
|
210
|
+
This metric is based on the standard F-score, but applies a temporal adjustment
|
211
|
+
to the predictions before computing it. Specifically, for each ground-truth anomalous segment,
|
212
|
+
if at least one point within the first k time steps of the segment is predicted as anomalous,
|
213
|
+
all points in the segment are marked as correctly detected. The adjusted predictions are then
|
214
|
+
used to compute the standard point-wise F-Score formulation.
|
215
|
+
|
183
216
|
Implementation of https://link.springer.com/article/10.1007/s10618-023-00988-8
|
184
217
|
|
185
218
|
Parameters:
|
186
219
|
y_true (np.array): The ground truth binary labels for the time series data.
|
187
220
|
y_pred (np.array): The predicted binary labels for the time series data.
|
188
|
-
k (int):
|
221
|
+
k (int): Maximum number of time steps from the start of an anomaly segment within which a prediction must occur for the segment to be considered detected.
|
189
222
|
beta (float): The beta value, which determines the weight of precision in the combined score.
|
190
223
|
Default is 1, which gives equal weight to precision and recall.
|
191
224
|
|
@@ -204,6 +237,12 @@ def delay_th_point_adjusted_f_score(y_true: np.array, y_pred: np.array, k: int,
|
|
204
237
|
def point_adjusted_at_k_recall(y_true: np.array, y_pred: np.array, k: float):
|
205
238
|
"""
|
206
239
|
Calculate k percent point-adjusted at K% recall for anomaly detection in time series.
|
240
|
+
This metric is based on the standard recall score, but applies a temporal adjustment
|
241
|
+
to the predictions before computing it. Specifically, for each ground-truth anomalous segment,
|
242
|
+
if at least K% of the points within that segment are predicted as anomalous, all points in
|
243
|
+
the segment are marked as correctly detected. Otherwise, the entire segment is treated as
|
244
|
+
missed, even if some points were correctly predicted. The adjusted predictions are then used
|
245
|
+
to compute the standard point-wise recall.
|
207
246
|
Implementation of https://link.springer.com/article/10.1007/s10618-023-00988-8
|
208
247
|
|
209
248
|
Parameters:
|
@@ -224,6 +263,12 @@ def point_adjusted_at_k_recall(y_true: np.array, y_pred: np.array, k: float):
|
|
224
263
|
def point_adjusted_at_k_precision(y_true: np.array, y_pred: np.array, k: float):
|
225
264
|
"""
|
226
265
|
Calculate point-adjusted at K% precision for anomaly detection in time series.
|
266
|
+
This metric is based on the standard precision score, but applies a temporal adjustment
|
267
|
+
to the predictions before computing it. Specifically, for each ground-truth anomalous segment,
|
268
|
+
if at least K% of the points within that segment are predicted as anomalous, all points in
|
269
|
+
the segment are marked as correctly detected. Otherwise, the entire segment is treated as
|
270
|
+
missed, even if some points were correctly predicted. The adjusted predictions are then used
|
271
|
+
to compute the standard point-wise precision.
|
227
272
|
Implementation of https://link.springer.com/article/10.1007/s10618-023-00988-8
|
228
273
|
|
229
274
|
Parameters:
|
@@ -234,7 +279,6 @@ def point_adjusted_at_k_precision(y_true: np.array, y_pred: np.array, k: float):
|
|
234
279
|
Returns:
|
235
280
|
float: The point-adjusted precision score, which is the ratio of true positives to the sum of true positives and false positives.
|
236
281
|
"""
|
237
|
-
#TP, _, FP, _ = get_tp_tn_fp_fn_point_adjusted_at_k(y_true, y_pred, k)
|
238
282
|
m = PointAdjustKPercent(len(y_true),y_true,y_pred,k=k)
|
239
283
|
TP,FP = m.tp,m.fp
|
240
284
|
if TP == 0:
|
@@ -244,6 +288,12 @@ def point_adjusted_at_k_precision(y_true: np.array, y_pred: np.array, k: float):
|
|
244
288
|
def point_adjusted_at_k_f_score(y_true: np.array, y_pred: np.array, k: float, beta=1):
|
245
289
|
"""
|
246
290
|
Calculate point-adjusted at K% F-score for anomaly detection in time series.
|
291
|
+
This metric is based on the standard F-Score, but applies a temporal adjustment
|
292
|
+
to the predictions before computing it. Specifically, for each ground-truth anomalous segment,
|
293
|
+
if at least K% of the points within that segment are predicted as anomalous, all points in
|
294
|
+
the segment are marked as correctly detected. Otherwise, the entire segment is treated as
|
295
|
+
missed, even if some points were correctly predicted. The adjusted predictions are then used
|
296
|
+
to compute the standard F-Score precision.
|
247
297
|
Implementation of https://link.springer.com/article/10.1007/s10618-023-00988-8
|
248
298
|
|
249
299
|
Parameters:
|
@@ -268,6 +318,14 @@ def point_adjusted_at_k_f_score(y_true: np.array, y_pred: np.array, k: float, be
|
|
268
318
|
def latency_sparsity_aw_recall(y_true: np.array, y_pred: np.array, ni: int):
|
269
319
|
"""
|
270
320
|
Calculate latency and sparsity aware recall for anomaly detection in time series.
|
321
|
+
This metric is based on the standard recall, but applies a temporal adjustment
|
322
|
+
to the predictions before computing it. Specifically, for each ground-truth anomalous segment,
|
323
|
+
all points in the segment are marked as correctly detected only after the first true positive
|
324
|
+
is predicted within that segment. This encourages early detection by delaying credit for correct
|
325
|
+
predictions until the anomaly is initially detected. Additionally, to reduce the impact of
|
326
|
+
scattered false positives, predictions are subsampled using a sparsity factor n, so that
|
327
|
+
only one prediction is considered every n time steps. The adjusted predictions are then used
|
328
|
+
to compute the standard point-wise recall.
|
271
329
|
Implementation of https://dl.acm.org/doi/10.1145/3447548.3467174
|
272
330
|
|
273
331
|
Parameters:
|
@@ -289,6 +347,14 @@ def latency_sparsity_aw_recall(y_true: np.array, y_pred: np.array, ni: int):
|
|
289
347
|
def latency_sparsity_aw_precision(y_true: np.array, y_pred: np.array, ni: int):
|
290
348
|
"""
|
291
349
|
Calculate latency and sparsity aware precision for anomaly detection in time series.
|
350
|
+
This metric is based on the standard precision, but applies a temporal adjustment
|
351
|
+
to the predictions before computing it. Specifically, for each ground-truth anomalous segment,
|
352
|
+
all points in the segment are marked as correctly detected only after the first true positive
|
353
|
+
is predicted within that segment. This encourages early detection by delaying credit for correct
|
354
|
+
predictions until the anomaly is initially detected. Additionally, to reduce the impact of
|
355
|
+
scattered false positives, predictions are subsampled using a sparsity factor n, so that
|
356
|
+
only one prediction is considered every n time steps. The adjusted predictions are then used
|
357
|
+
to compute the standard point-wise precision.
|
292
358
|
Implementation of https://dl.acm.org/doi/10.1145/3447548.3467174
|
293
359
|
|
294
360
|
Parameters:
|
@@ -310,6 +376,15 @@ def latency_sparsity_aw_precision(y_true: np.array, y_pred: np.array, ni: int):
|
|
310
376
|
def latency_sparsity_aw_f_score(y_true: np.array, y_pred: np.array, ni: int, beta=1):
|
311
377
|
"""
|
312
378
|
Calculate latency and sparsity aware F-score for anomaly detection in time series.
|
379
|
+
This metric is based on the standard F-score, but applies a temporal adjustment
|
380
|
+
to the predictions before computing it. Specifically, for each ground-truth anomalous segment,
|
381
|
+
all points in the segment are marked as correctly detected only after the first true positive
|
382
|
+
is predicted within that segment. This encourages early detection by delaying credit for correct
|
383
|
+
predictions until the anomaly is initially detected. Additionally, to reduce the impact of
|
384
|
+
scattered false positives, predictions are subsampled using a sparsity factor n, so that
|
385
|
+
only one prediction is considered every n time steps. The adjusted predictions are then used
|
386
|
+
to compute the standard point-wise F-score.
|
387
|
+
|
313
388
|
Implementation of https://dl.acm.org/doi/10.1145/3447548.3467174
|
314
389
|
|
315
390
|
Parameters:
|
@@ -335,6 +410,14 @@ def latency_sparsity_aw_f_score(y_true: np.array, y_pred: np.array, ni: int, bet
|
|
335
410
|
def segment_wise_recall(y_true: np.array, y_pred: np.array):
|
336
411
|
"""
|
337
412
|
Calculate segment-wise recall for anomaly detection in time series.
|
413
|
+
This metric is based on the standard recall, but applies a temporal adjustment
|
414
|
+
to the predictions before computing it. Specifically, each contiguous segment of anomalous points
|
415
|
+
is treated as a single unit. A true positive is counted if at least one point in a ground-truth
|
416
|
+
anomalous segment is predicted as anomalous. A false negative is counted if no point in the segment
|
417
|
+
is detected, and a false positive is recorded for each predicted anomalous segment that does not
|
418
|
+
overlap with any ground-truth anomaly. The final recall is computed using these adjusted
|
419
|
+
segment-level counts.
|
420
|
+
|
338
421
|
Implementation of https://arxiv.org/pdf/1802.04431
|
339
422
|
|
340
423
|
Parameters:
|
@@ -344,7 +427,6 @@ def segment_wise_recall(y_true: np.array, y_pred: np.array):
|
|
344
427
|
Returns:
|
345
428
|
float: The segment-wise recall score, which is the ratio of true positives to the sum of true positives and false negatives.
|
346
429
|
"""
|
347
|
-
#TP, _, FN = get_tp_fp_fn_segment_wise(y_true, y_pred)
|
348
430
|
m = Segmentwise_metrics(len(y_true),y_true,y_pred)
|
349
431
|
TP,FN = m.tp,m.fn
|
350
432
|
if TP == 0:
|
@@ -354,6 +436,13 @@ def segment_wise_recall(y_true: np.array, y_pred: np.array):
|
|
354
436
|
def segment_wise_precision(y_true: np.array, y_pred: np.array):
|
355
437
|
"""
|
356
438
|
Calculate segment-wise precision for anomaly detection in time series.
|
439
|
+
This metric is based on the standard precision, but applies a temporal adjustment
|
440
|
+
to the predictions before computing it. Specifically, each contiguous segment of anomalous points
|
441
|
+
is treated as a single unit. A true positive is counted if at least one point in a ground-truth
|
442
|
+
anomalous segment is predicted as anomalous. A false negative is counted if no point in the segment
|
443
|
+
is detected, and a false positive is recorded for each predicted anomalous segment that does not
|
444
|
+
overlap with any ground-truth anomaly. The final precision is computed using these adjusted
|
445
|
+
segment-level counts.
|
357
446
|
Implementation of https://arxiv.org/pdf/1802.04431
|
358
447
|
|
359
448
|
Parameters:
|
@@ -363,7 +452,6 @@ def segment_wise_precision(y_true: np.array, y_pred: np.array):
|
|
363
452
|
Returns:
|
364
453
|
float: The segment-wise precision score, which is the ratio of true positives to the sum of true positives and false positives.
|
365
454
|
"""
|
366
|
-
#TP, FP, _ = get_tp_fp_fn_segment_wise(y_true, y_pred)
|
367
455
|
m = Segmentwise_metrics(len(y_true),y_true,y_pred)
|
368
456
|
TP,FP = m.tp,m.fp
|
369
457
|
if TP == 0:
|
@@ -373,6 +461,13 @@ def segment_wise_precision(y_true: np.array, y_pred: np.array):
|
|
373
461
|
def segment_wise_f_score(y_true: np.array, y_pred: np.array, beta=1):
|
374
462
|
"""
|
375
463
|
Calculate segment-wise F-score for anomaly detection in time series.
|
464
|
+
This metric is based on the standard F-score, but applies a temporal adjustment
|
465
|
+
to the predictions before computing it. Specifically, each contiguous segment of anomalous points
|
466
|
+
is treated as a single unit. A true positive is counted if at least one point in a ground-truth
|
467
|
+
anomalous segment is predicted as anomalous. A false negative is counted if no point in the segment
|
468
|
+
is detected, and a false positive is recorded for each predicted anomalous segment that does not
|
469
|
+
overlap with any ground-truth anomaly. The final F-score is computed using these adjusted
|
470
|
+
segment-level counts.
|
376
471
|
Implementation of https://arxiv.org/pdf/1802.04431
|
377
472
|
|
378
473
|
Parameters:
|
@@ -400,24 +495,32 @@ def segment_wise_f_score(y_true: np.array, y_pred: np.array, beta=1):
|
|
400
495
|
def composite_f_score(y_true: np.array, y_pred: np.array, beta=1):
|
401
496
|
"""
|
402
497
|
Calculate composite F-score for anomaly detection in time series.
|
498
|
+
This metric combines aspects of the point_wise_f_score and the segment_wise_f_score.
|
499
|
+
It is defined as the harmonic mean of point_wise_precision and segment_wise_recall.
|
500
|
+
The use of point-wise precision ensures that false positives are properly penalized,
|
501
|
+
a feature that segment-wise metrics typically lack.
|
502
|
+
|
403
503
|
Implementation of https://ieeexplore.ieee.org/document/9525836
|
404
504
|
|
405
505
|
Parameters:
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
506
|
+
y_true (np.array):
|
507
|
+
The ground truth binary labels for the time series data.
|
508
|
+
y_pred (np.array):
|
509
|
+
The predicted binary labels for the time series data.
|
510
|
+
beta (float):
|
511
|
+
The beta value, which determines the weight of precision in the combined score.
|
512
|
+
Default is 1, which gives equal weight to precision and recall.
|
410
513
|
|
411
514
|
Returns:
|
412
|
-
|
515
|
+
float: The composite F-score, which is the harmonic mean of precision and recall, adjusted by the beta value.
|
413
516
|
|
414
517
|
"""
|
415
518
|
m = Composite_f(len(y_true),y_true,y_pred)
|
416
519
|
#Point wise precision
|
417
|
-
precision = m.precision()
|
520
|
+
precision = m.precision()
|
418
521
|
|
419
522
|
#Segment wise recall
|
420
|
-
recall = m.recall()
|
523
|
+
recall = m.recall()
|
421
524
|
|
422
525
|
if precision==0 or recall==0:
|
423
526
|
return 0
|
@@ -427,6 +530,12 @@ def composite_f_score(y_true: np.array, y_pred: np.array, beta=1):
|
|
427
530
|
def time_tolerant_recall(y_true: np.array, y_pred: np.array, t: int) -> float:
|
428
531
|
"""
|
429
532
|
Calculate time tolerant recall for anomaly detection in time series.
|
533
|
+
This metric is based on the standard recall, but applies a temporal adjustment
|
534
|
+
to the predictions before computing it. Specifically, a predicted anomalous point is considered
|
535
|
+
a true positive if it lies within a temporal window of size τ around any ground-truth anomalous point.
|
536
|
+
This allows for small temporal deviations in the predictions to be tolerated. The adjusted predictions are then used
|
537
|
+
to compute the standard point-wise recall.
|
538
|
+
|
430
539
|
Implementation of https://arxiv.org/pdf/1802.04431
|
431
540
|
|
432
541
|
Parameters:
|
@@ -446,6 +555,12 @@ def time_tolerant_recall(y_true: np.array, y_pred: np.array, t: int) -> float:
|
|
446
555
|
def time_tolerant_precision(y_true: np.array, y_pred: np.array, t: int) -> float:
|
447
556
|
"""
|
448
557
|
Calculate time tolerant precision for anomaly detection in time series.
|
558
|
+
This metric is based on the standard precision, but applies a temporal adjustment
|
559
|
+
to the predictions before computing it. Specifically, a predicted anomalous point is considered
|
560
|
+
a true positive if it lies within a temporal window of size τ around any ground-truth anomalous point.
|
561
|
+
This allows for small temporal deviations in the predictions to be tolerated. The adjusted predictions are then used
|
562
|
+
to compute the standard point-wise precision.
|
563
|
+
|
449
564
|
Implementation of https://arxiv.org/pdf/1802.04431
|
450
565
|
|
451
566
|
Parameters:
|
@@ -462,9 +577,15 @@ def time_tolerant_precision(y_true: np.array, y_pred: np.array, t: int) -> float
|
|
462
577
|
return m.precision()
|
463
578
|
|
464
579
|
|
465
|
-
def time_tolerant_f_score(y_true: np.array, y_pred: np.array,t: int, beta=1):
|
580
|
+
def time_tolerant_f_score(y_true: np.array, y_pred: np.array, t: int, beta=1):
|
466
581
|
"""
|
467
582
|
Calculate time tolerant F-score for anomaly detection in time series.
|
583
|
+
This metric is based on the standard F-score, but applies a temporal adjustment
|
584
|
+
to the predictions before computing it. Specifically, a predicted anomalous point is considered
|
585
|
+
a true positive if it lies within a temporal window of size τ around any ground-truth anomalous point.
|
586
|
+
This allows for small temporal deviations in the predictions to be tolerated.The adjusted predictions are then used
|
587
|
+
to compute the standard point-wise F-Score.
|
588
|
+
|
468
589
|
Implementation of https://arxiv.org/pdf/1802.04431
|
469
590
|
|
470
591
|
Parameters:
|
@@ -488,13 +609,23 @@ def time_tolerant_f_score(y_true: np.array, y_pred: np.array,t: int, beta=1):
|
|
488
609
|
def range_based_recall(y_true: np.array, y_pred: np.array, alpha: float, bias='flat', cardinality_mode='one'):
|
489
610
|
"""
|
490
611
|
Calculate range-based recall for anomaly detection in time series.
|
491
|
-
|
612
|
+
|
613
|
+
This metric extends standard recall by evaluating detection at the level of anomalous ranges
|
614
|
+
rather than individual points. For each true anomaly range, it computes a score that rewards
|
615
|
+
(1) detecting the existence of the range, (2) the proportion of overlap, and (3) penalties or
|
616
|
+
bonuses based on the position and fragmentation of predicted segments. These components are
|
617
|
+
weighted by α (existence vs. overlap) and further shaped by customizable bias functions
|
618
|
+
for positional and cardinality factors.
|
619
|
+
|
620
|
+
For more information, see the original paper:
|
621
|
+
https://proceedings.neurips.cc/paper_files/paper/2018/file/8f468c873a32bb0619eaeb2050ba45d1-Paper.pdf
|
622
|
+
|
492
623
|
Parameters:
|
493
624
|
y_true (np.array): The ground truth binary labels for the time series data.
|
494
625
|
y_pred (np.array): The predicted binary labels for the time series data.
|
495
|
-
alpha (float):
|
496
|
-
bias (str):
|
497
|
-
|
626
|
+
alpha (float): Relative importance of existence reward. 0 ≤ alpha ≤ 1.
|
627
|
+
bias (str): Positional bias. This should be "flat", "front", "middle", or "back".
|
628
|
+
cardinality_mode (str, optional): Cardinality type. This should be "one", "reciprocal" or "udf_gamma".
|
498
629
|
|
499
630
|
Returns:
|
500
631
|
float: The range-based recall score.
|
@@ -509,13 +640,21 @@ def range_based_recall(y_true: np.array, y_pred: np.array, alpha: float, bias='f
|
|
509
640
|
def range_based_precision(y_true: np.array, y_pred: np.array, alpha: float, bias='flat', cardinality_mode='one'):
|
510
641
|
"""
|
511
642
|
Calculate range-based precision for anomaly detection in time series.
|
643
|
+
|
644
|
+
This metric extends standard precision by scoring predictions at the range level. Each
|
645
|
+
predicted anomaly range is evaluated for (1) overlap with any true ranges, (2) the size of
|
646
|
+
that overlap, and (3) positional and fragmentation effects via bias functions. Cardinality
|
647
|
+
penalties can be applied when a single true range is covered by multiple predicted ranges.
|
648
|
+
|
649
|
+
For more information, see the original paper:
|
650
|
+
https://proceedings.neurips.cc/paper_files/paper/2018/file/8f468c873a32bb0619eaeb2050ba45d1-Paper.pdf
|
512
651
|
|
513
652
|
Parameters:
|
514
653
|
y_true (np.array): The ground truth binary labels for the time series data.
|
515
654
|
y_pred (np.array): The predicted binary labels for the time series data.
|
516
|
-
alpha (float):
|
517
|
-
bias (str):
|
518
|
-
|
655
|
+
alpha (float): Relative importance of existence reward. 0 ≤ alpha ≤ 1.
|
656
|
+
bias (str): Positional bias. This should be "flat", "front", "middle", or "back".
|
657
|
+
cardinality_mode (str, optional): Cardinality type. This should be "one", "reciprocal" or "udf_gamma".
|
519
658
|
|
520
659
|
Returns:
|
521
660
|
float: The range-based precision score.
|
@@ -534,15 +673,22 @@ def range_based_f_score(y_true: np.array, y_pred: np.array, p_alpha: float, r_al
|
|
534
673
|
"""
|
535
674
|
Calculate range-based F-score for anomaly detection in time series.
|
536
675
|
|
676
|
+
This metric combines range-based precision and range-based recall into a single harmonic mean.
|
677
|
+
It inherits all customizability of the underlying precision and recall—existence vs. overlap
|
678
|
+
weighting, positional bias, and cardinality factors—allowing fine-grained control over how
|
679
|
+
both missed detections and false alarms are penalized in a temporal context.
|
680
|
+
|
681
|
+
For more information, see the original paper:
|
682
|
+
https://proceedings.neurips.cc/paper_files/paper/2018/file/8f468c873a32bb0619eaeb2050ba45d1-Paper.pdf
|
683
|
+
|
684
|
+
|
537
685
|
Parameters:
|
538
686
|
y_true (np.array): The ground truth binary labels for the time series data.
|
539
687
|
y_pred (np.array): The predicted binary labels for the time series data.
|
540
|
-
alpha (float):
|
541
|
-
p_bias:
|
542
|
-
|
543
|
-
|
544
|
-
Positional bias for recall. This should be "flat", "front", "middle", or "back"
|
545
|
-
cardinality_mode (str, optional): ["one", "reciprocal", "udf_gamma"]. Defaults to "one".
|
688
|
+
alpha (float): Relative importance of existence reward. 0 ≤ alpha ≤ 1.
|
689
|
+
p_bias (str): Positional bias for precision. This should be "flat", "front", "middle", or "back".
|
690
|
+
r_bias (str): Positional bias for recall. This should be "flat", "front", "middle", or "back".
|
691
|
+
cardinality_mode (str, optional): Cardinality type. This should be "one", "reciprocal" or "udf_gamma".
|
546
692
|
beta (float): The beta value, which determines the weight of precision in the combined score.
|
547
693
|
Default is 1, which gives equal weight to precision and recall.
|
548
694
|
|
@@ -561,11 +707,27 @@ def ts_aware_recall(y_true: np.array, y_pred: np.array, alpha: float, delta: flo
|
|
561
707
|
"""
|
562
708
|
Calculate time series aware recall for anomaly detection in time series.
|
563
709
|
|
710
|
+
This metric is based on the range_based_recall, but introduces two key modifications.
|
711
|
+
First, a predicted anomalous segment is only counted as a true positive if it covers at least a fraction
|
712
|
+
θ of the ground‑truth anomaly range. Second, each labeled anomaly is extended by a tolerance window of
|
713
|
+
length δ at its end, within which any overlap contribution decays linearly from full weight down to zero.
|
714
|
+
Unlike the original range-based formulation, this variant omits cardinality and positional bias terms,
|
715
|
+
focusing solely on overlap fraction and end‑tolerance decay.
|
716
|
+
|
564
717
|
Parameters:
|
565
718
|
y_true (np.array): The ground truth binary labels for the time series data.
|
566
719
|
y_pred (np.array): The predicted binary labels for the time series data.
|
567
|
-
alpha (float):
|
568
|
-
|
720
|
+
alpha (float): Relative importance of the existence reward versus overlap reward (0 ≤ α ≤ 1).
|
721
|
+
delta (float): Tolerance window length at the end of each true anomaly segment.
|
722
|
+
- If past_range is True, δ must be a float in (0, 1], representing the fraction of the segment’s
|
723
|
+
length to extend. E.g., δ = 0.5 extends a segment of length 10 by 5 time steps.
|
724
|
+
- If past_range is False, δ must be a non-negative integer, representing an absolute number of
|
725
|
+
time steps to extend each segment.
|
726
|
+
theta (float): Minimum fraction (0 ≤ θ ≤ 1) of the true anomaly range that must be overlapped by
|
727
|
+
predictions for the segment to count as detected.
|
728
|
+
past_range (bool): Determines how δ is interpreted.
|
729
|
+
- True: δ is treated as a fractional extension of each segment’s length.
|
730
|
+
- False: δ is treated as an absolute number of time steps.
|
569
731
|
|
570
732
|
Returns:
|
571
733
|
float: The time series aware recall score.
|
@@ -579,12 +741,28 @@ def ts_aware_recall(y_true: np.array, y_pred: np.array, alpha: float, delta: flo
|
|
579
741
|
def ts_aware_precision(y_true: np.array, y_pred: np.array,alpha: float, delta: float, theta: float, past_range: bool = False):
|
580
742
|
"""
|
581
743
|
Calculate time series aware precision for anomaly detection in time series.
|
744
|
+
|
745
|
+
This metric is based on the range_based_precision, but introduces two key modifications.
|
746
|
+
First, a predicted anomalous segment is only counted as a true positive if it covers at least a fraction
|
747
|
+
θ of the ground‑truth anomaly range. Second, each labeled anomaly is extended by a tolerance window of
|
748
|
+
length δ at its end, within which any overlap contribution decays linearly from full weight down to zero.
|
749
|
+
Unlike the original range-based formulation, this variant omits cardinality and positional bias terms,
|
750
|
+
focusing solely on overlap fraction and end‑tolerance decay.
|
582
751
|
|
583
752
|
Parameters:
|
584
753
|
y_true (np.array): The ground truth binary labels for the time series data.
|
585
754
|
y_pred (np.array): The predicted binary labels for the time series data.
|
586
|
-
alpha (float):
|
587
|
-
|
755
|
+
alpha (float): Relative importance of the existence reward versus overlap reward (0 ≤ α ≤ 1).
|
756
|
+
delta (float): Tolerance window length at the end of each true anomaly segment.
|
757
|
+
- If past_range is True, δ must be a float in (0, 1], representing the fraction of the segment’s
|
758
|
+
length to extend. E.g., δ = 0.5 extends a segment of length 10 by 5 time steps.
|
759
|
+
- If past_range is False, δ must be a non-negative integer, representing an absolute number of
|
760
|
+
time steps to extend each segment.
|
761
|
+
theta (float): Minimum fraction (0 ≤ θ ≤ 1) of the true anomaly range that must be overlapped by
|
762
|
+
predictions for the segment to count as detected.
|
763
|
+
past_range (bool): Determines how δ is interpreted.
|
764
|
+
- True: δ is treated as a fractional extension of each segment’s length.
|
765
|
+
- False: δ is treated as an absolute number of time steps.
|
588
766
|
|
589
767
|
Returns:
|
590
768
|
float: The time series aware precision score.
|
@@ -600,13 +778,27 @@ def ts_aware_f_score(y_true: np.array, y_pred: np.array, beta: float, alpha: flo
|
|
600
778
|
"""
|
601
779
|
Calculate time series aware F-score for anomaly detection in time series.
|
602
780
|
|
781
|
+
This metric is based on the range_based_f_score, but introduces two key modifications.
|
782
|
+
First, a predicted anomalous segment is only counted as a true positive if it covers at least a fraction
|
783
|
+
θ of the ground‑truth anomaly range. Second, each labeled anomaly is extended by a tolerance window of
|
784
|
+
length δ at its end, within which any overlap contribution decays linearly from full weight down to zero.
|
785
|
+
Unlike the original range-based formulation, this variant omits cardinality and positional bias terms,
|
786
|
+
focusing solely on overlap fraction and end‑tolerance decay.
|
787
|
+
|
603
788
|
Parameters:
|
604
789
|
y_true (np.array): The ground truth binary labels for the time series data.
|
605
790
|
y_pred (np.array): The predicted binary labels for the time series data.
|
606
|
-
alpha (float):
|
607
|
-
|
608
|
-
|
609
|
-
|
791
|
+
alpha (float): Relative importance of the existence reward versus overlap reward (0 ≤ α ≤ 1).
|
792
|
+
delta (float): Tolerance window length at the end of each true anomaly segment.
|
793
|
+
- If past_range is True, δ must be a float in (0, 1], representing the fraction of the segment’s
|
794
|
+
length to extend. E.g., δ = 0.5 extends a segment of length 10 by 5 time steps.
|
795
|
+
- If past_range is False, δ must be a non-negative integer, representing an absolute number of
|
796
|
+
time steps to extend each segment.
|
797
|
+
theta (float): Minimum fraction (0 ≤ θ ≤ 1) of the true anomaly range that must be overlapped by
|
798
|
+
predictions for the segment to count as detected.
|
799
|
+
past_range (bool): Determines how δ is interpreted.
|
800
|
+
- True: δ is treated as a fractional extension of each segment’s length.
|
801
|
+
- False: δ is treated as an absolute number of time steps.
|
610
802
|
|
611
803
|
Returns:
|
612
804
|
float: The time series aware F-score, which is the harmonic mean of precision and recall, adjusted by the beta value.
|
@@ -628,10 +820,17 @@ def enhanced_ts_aware_recall(y_true: np.array, y_pred: np.array, theta: float):
|
|
628
820
|
"""
|
629
821
|
Calculate enhanced time series aware recall for anomaly detection in time series.
|
630
822
|
|
823
|
+
This metric is similar to the range-based recall in that it accounts for both detection existence
|
824
|
+
and overlap proportion. Additionally, it requires that a significant fraction θ of each true anomaly
|
825
|
+
segment be detected, and that a significant fraction γ of each predicted segment overlaps with the
|
826
|
+
ground truth. Finally, recall contributions from each event are weighted by the square root of the
|
827
|
+
true segment’s length, providing a compromise between point-wise and segment-wise approaches.
|
828
|
+
|
631
829
|
Parameters:
|
632
830
|
y_true (np.array): The ground truth binary labels for the time series data.
|
633
831
|
y_pred (np.array): The predicted binary labels for the time series data.
|
634
|
-
|
832
|
+
theta (float): Minimum fraction (0 ≤ θ ≤ 1) of a true segment that must be overlapped
|
833
|
+
by predictions to count as detected.
|
635
834
|
|
636
835
|
Returns:
|
637
836
|
float: The time series aware recall score.
|
@@ -648,10 +847,17 @@ def enhanced_ts_aware_precision(y_true: np.array, y_pred: np.array, theta: float
|
|
648
847
|
"""
|
649
848
|
Calculate enhanced time series aware precision for anomaly detection in time series.
|
650
849
|
|
850
|
+
This metric is similar to the range-based precision in that it accounts for both detection existence
|
851
|
+
and overlap proportion. Additionally, it requires that a significant fraction θ of each true anomaly
|
852
|
+
segment be detected, and that a significant fraction γ of each predicted segment overlaps with the
|
853
|
+
ground truth. Finally, precision contributions from each event are weighted by the square root of the
|
854
|
+
true segment’s length, providing a compromise between point-wise and segment-wise approaches.
|
855
|
+
|
651
856
|
Parameters:
|
652
857
|
y_true (np.array): The ground truth binary labels for the time series data.
|
653
858
|
y_pred (np.array): The predicted binary labels for the time series data.
|
654
|
-
|
859
|
+
theta (float): Minimum fraction (0 ≤ θ ≤ 1) of a true segment that must be overlapped
|
860
|
+
by predictions to count as detected.
|
655
861
|
|
656
862
|
Returns:
|
657
863
|
float: The time series aware precision score.
|
@@ -665,15 +871,21 @@ def enhanced_ts_aware_precision(y_true: np.array, y_pred: np.array, theta: float
|
|
665
871
|
|
666
872
|
|
667
873
|
|
668
|
-
def enhanced_ts_aware_f_score(y_true: np.array, y_pred: np.array,
|
874
|
+
def enhanced_ts_aware_f_score(y_true: np.array, y_pred: np.array, theta_p: float, theta_r: float):
|
669
875
|
"""
|
670
876
|
Calculate enhanced time series aware F-score for anomaly detection in time series.
|
877
|
+
|
878
|
+
This metric is similar to the range-based F-score in that it accounts for both detection existence
|
879
|
+
and overlap proportion. Additionally, it requires that a significant fraction θ of each true anomaly
|
880
|
+
segment be detected, and that a significant fraction γ of each predicted segment overlaps with the
|
881
|
+
ground truth. Finally, F-score contributions from each event are weighted by the square root of the
|
882
|
+
true segment’s length, providing a compromise between point-wise and segment-wise approaches.
|
671
883
|
|
672
884
|
Parameters:
|
673
885
|
y_true (np.array): The ground truth binary labels for the time series data.
|
674
886
|
y_pred (np.array): The predicted binary labels for the time series data.
|
675
|
-
|
676
|
-
|
887
|
+
theta (float): Minimum fraction (0 ≤ θ ≤ 1) of a true segment that must be overlapped
|
888
|
+
by predictions to count as detected.
|
677
889
|
|
678
890
|
Returns:
|
679
891
|
float: The time series aware F-score, which is the harmonic mean of precision and recall, adjusted by the beta value.
|
@@ -689,14 +901,16 @@ def affiliation_based_recall(y_true: np.array, y_pred: np.array):
|
|
689
901
|
"""
|
690
902
|
Calculate affiliation based recall for anomaly detection in time series.
|
691
903
|
|
904
|
+
This metric evaluates how well each labeled anomaly is affiliated with predicted points.
|
905
|
+
It computes the average distance from each ground truth anomaly point to the nearest
|
906
|
+
predicted anomaly point.
|
907
|
+
|
692
908
|
Parameters:
|
693
909
|
y_true (np.array): The ground truth binary labels for the time series data.
|
694
910
|
y_pred (np.array): The predicted binary labels for the time series data.
|
695
|
-
beta (float): The beta value, which determines the weight of precision in the combined score.
|
696
|
-
Default is 1, which gives equal weight to precision and recall.
|
697
911
|
|
698
912
|
Returns:
|
699
|
-
float: The
|
913
|
+
float: The affiliation based recall score.
|
700
914
|
"""
|
701
915
|
if np.sum(y_pred) == 0:
|
702
916
|
return 0
|
@@ -709,14 +923,17 @@ def affiliation_based_precision(y_true: np.array, y_pred: np.array):
|
|
709
923
|
"""
|
710
924
|
Calculate affiliation based F-score for anomaly detection in time series.
|
711
925
|
|
926
|
+
This metric evaluates how well each predicted anomaly is affiliated with labeled points.
|
927
|
+
It computes the average distance from each predicted anomaly point to the nearest
|
928
|
+
ground truth anomaly point.
|
929
|
+
|
712
930
|
Parameters:
|
713
931
|
y_true (np.array): The ground truth binary labels for the time series data.
|
714
932
|
y_pred (np.array): The predicted binary labels for the time series data.
|
715
|
-
|
716
|
-
Default is 1, which gives equal weight to precision and recall.
|
933
|
+
|
717
934
|
|
718
935
|
Returns:
|
719
|
-
float: The
|
936
|
+
float: The affiliation based precision score.
|
720
937
|
"""
|
721
938
|
if np.sum(y_pred) == 0:
|
722
939
|
return 0
|
@@ -729,14 +946,20 @@ def affiliation_based_f_score(y_true: np.array, y_pred: np.array, beta=1):
|
|
729
946
|
"""
|
730
947
|
Calculate affiliation based F-score for anomaly detection in time series.
|
731
948
|
|
949
|
+
This metric combines the affiliation-based precision and recall into a single score
|
950
|
+
using the harmonic mean, adjusted by a weight β to control the relative importance
|
951
|
+
of recall versus precision. Since both precision and recall are distance-based,
|
952
|
+
the F-score reflects a balance between how well predicted anomalies align with true
|
953
|
+
anomalies and vice versa.
|
954
|
+
|
732
955
|
Parameters:
|
733
956
|
y_true (np.array): The ground truth binary labels for the time series data.
|
734
957
|
y_pred (np.array): The predicted binary labels for the time series data.
|
735
958
|
beta (float): The beta value, which determines the weight of precision in the combined score.
|
736
|
-
|
959
|
+
|
737
960
|
|
738
961
|
Returns:
|
739
|
-
float: The
|
962
|
+
float: The affiliation based F-score.
|
740
963
|
"""
|
741
964
|
if np.sum(y_pred) == 0:
|
742
965
|
return 0
|
@@ -748,13 +971,18 @@ def nab_score(y_true: np.array, y_pred: np.array):
|
|
748
971
|
"""
|
749
972
|
Calculate NAB score for anomaly detection in time series.
|
750
973
|
|
974
|
+
This metric rewards early and accurate detections of anomalies while penalizing false positives.
|
975
|
+
For each ground truth anomaly segment, only the first correctly predicted anomaly point contributes
|
976
|
+
positively to the score, with earlier detections receiving higher rewards. In contrast, every false
|
977
|
+
positive prediction contributes negatively.
|
978
|
+
|
751
979
|
Parameters:
|
752
980
|
y_true (np.array): The ground truth binary labels for the time series data.
|
753
981
|
y_pred (np.array): The predicted binary labels for the time series data.
|
754
982
|
|
755
983
|
|
756
984
|
Returns:
|
757
|
-
float: The nab score
|
985
|
+
float: The nab score.
|
758
986
|
"""
|
759
987
|
|
760
988
|
m = NAB_score(len(y_true),y_true,y_pred)
|
@@ -764,6 +992,11 @@ def temporal_distance(y_true: np.array, y_pred: np.array, distance: int = 0):
|
|
764
992
|
"""
|
765
993
|
Calculate temporal distane for anomaly detection in time series.
|
766
994
|
|
995
|
+
This metric computes the sum of the distances from each labelled anomaly point to
|
996
|
+
the closest predicted anomaly point, and from each predicted anomaly point to the
|
997
|
+
closest labelled anomaly point.
|
998
|
+
|
999
|
+
|
767
1000
|
Parameters:
|
768
1001
|
y_true (np.array): The ground truth binary labels for the time series data.
|
769
1002
|
y_pred (np.array): The predicted binary labels for the time series data.
|
@@ -773,7 +1006,7 @@ def temporal_distance(y_true: np.array, y_pred: np.array, distance: int = 0):
|
|
773
1006
|
|
774
1007
|
|
775
1008
|
Returns:
|
776
|
-
float: The temporal distance
|
1009
|
+
float: The temporal distance.
|
777
1010
|
"""
|
778
1011
|
|
779
1012
|
m = Temporal_Distance(len(y_true),y_true,y_pred,distance=distance)
|
@@ -783,13 +1016,20 @@ def average_detection_count(y_true: np.array, y_pred: np.array):
|
|
783
1016
|
"""
|
784
1017
|
Calculate average detection count for anomaly detection in time series.
|
785
1018
|
|
1019
|
+
This metric computes, for each ground-truth anomalous segment, how many points within that segment
|
1020
|
+
are predicted as anomalous. It then averages these counts across all true anomaly events,
|
1021
|
+
providing an estimate of detection coverage per event.
|
1022
|
+
|
1023
|
+
For more information, see the original paper:
|
1024
|
+
https://ceur-ws.org/Vol-1226/paper31.pdf
|
1025
|
+
|
786
1026
|
Parameters:
|
787
1027
|
y_true (np.array): The ground truth binary labels for the time series data.
|
788
1028
|
y_pred (np.array): The predicted binary labels for the time series data.
|
789
1029
|
|
790
1030
|
|
791
1031
|
Returns:
|
792
|
-
float: The average detection count.
|
1032
|
+
float: The average detection count score.
|
793
1033
|
"""
|
794
1034
|
|
795
1035
|
b = Binary_detection(len(y_true),y_true,y_pred)
|
@@ -810,10 +1050,17 @@ def absolute_detection_distance(y_true: np.array, y_pred: np.array):
|
|
810
1050
|
"""
|
811
1051
|
Calculate absolute detection distance for anomaly detection in time series.
|
812
1052
|
|
1053
|
+
This metric computes, for each predicted anomaly point that overlaps a ground-truth anomaly segment,
|
1054
|
+
the distance from that point to the temporal center of the corresponding segment. It then sums all
|
1055
|
+
those distances and divides by the total number of such matching predicted points, yielding the
|
1056
|
+
mean distance to segment centers for correctly detected points.
|
1057
|
+
|
813
1058
|
Parameters:
|
814
1059
|
y_true (np.array): The ground truth binary labels for the time series data.
|
815
1060
|
y_pred (np.array): The predicted binary labels for the time series data.
|
816
1061
|
|
1062
|
+
For more information, see the original paper:
|
1063
|
+
https://ceur-ws.org/Vol-1226/paper31.pdf
|
817
1064
|
|
818
1065
|
Returns:
|
819
1066
|
float: The absolute detection distance.
|
@@ -837,13 +1084,28 @@ def total_detected_in_range(y_true: np.array, y_pred: np.array, k: int):
|
|
837
1084
|
"""
|
838
1085
|
Calculate total detected in range for anomaly detection in time series.
|
839
1086
|
|
1087
|
+
This metric measures the proportion of true anomaly events that are correctly detected.
|
1088
|
+
It is defined as:
|
1089
|
+
TDIR = (EM + DA) / (EM + DA + MA)
|
1090
|
+
|
1091
|
+
Where:
|
1092
|
+
EM (Exact Match) = number of predicted anomaly segments that exactly match a true anomaly segment.
|
1093
|
+
DA (Detected Anomaly)= number of true anomaly points not exactly matched where at least one prediction falls
|
1094
|
+
within a window [i-k, i+k] around the true point index i or within the true segment range.
|
1095
|
+
FA (False Anomaly) = number of predicted anomaly segments that do not overlap any true anomaly segment
|
1096
|
+
even within a k-step tolerance window around true points.
|
1097
|
+
|
1098
|
+
For more information, see the original paper:
|
1099
|
+
https://acta.sapientia.ro/content/docs/evaluation-metrics-for-anomaly-detection.pdf
|
1100
|
+
|
840
1101
|
Parameters:
|
841
1102
|
y_true (np.array): The ground truth binary labels for the time series data.
|
842
1103
|
y_pred (np.array): The predicted binary labels for the time series data.
|
843
|
-
k (int):
|
1104
|
+
k (int): Half-window size for tolerance around each true anomaly point. A prediction within k
|
1105
|
+
time steps of a true point counts toward detection.
|
844
1106
|
|
845
1107
|
Returns:
|
846
|
-
float: The total detected in range.
|
1108
|
+
float: The total detected in range score.
|
847
1109
|
"""
|
848
1110
|
if np.sum(y_pred) == 0:
|
849
1111
|
return 0
|
@@ -857,10 +1119,25 @@ def detection_accuracy_in_range(y_true: np.array, y_pred: np.array, k: int):
|
|
857
1119
|
"""
|
858
1120
|
Calculate detection accuracy in range for anomaly detection in time series.
|
859
1121
|
|
1122
|
+
This metric measures the proportion of predicted anomaly events that correspond to true anomalies.
|
1123
|
+
It is defined as:
|
1124
|
+
DAIR = (EM + DA) / (EM + DA + FA)
|
1125
|
+
|
1126
|
+
Where:
|
1127
|
+
EM (Exact Match) = number of predicted anomaly segments that exactly match a true anomaly segment.
|
1128
|
+
DA (Detected Anomaly)= number of true anomaly points not exactly matched where at least one prediction falls
|
1129
|
+
within a window [i-k, i+k] around the true point index i or within the true segment range.
|
1130
|
+
FA (False Anomaly) = number of predicted anomaly segments that do not overlap any true anomaly segment
|
1131
|
+
even within a k-step tolerance window around true points.
|
1132
|
+
|
1133
|
+
For more information, see the original paper:
|
1134
|
+
https://acta.sapientia.ro/content/docs/evaluation-metrics-for-anomaly-detection.pdf
|
1135
|
+
|
860
1136
|
Parameters:
|
861
1137
|
y_true (np.array): The ground truth binary labels for the time series data.
|
862
1138
|
y_pred (np.array): The predicted binary labels for the time series data.
|
863
|
-
k (int):
|
1139
|
+
k (int): Half-window size for tolerance around each true anomaly point. A prediction within k
|
1140
|
+
time steps of a true point counts toward detection.
|
864
1141
|
|
865
1142
|
Returns:
|
866
1143
|
float: The total detected in range.
|
@@ -876,7 +1153,28 @@ def detection_accuracy_in_range(y_true: np.array, y_pred: np.array, k: int):
|
|
876
1153
|
def weighted_detection_difference(y_true: np.array, y_pred: np.array, k: int):
|
877
1154
|
"""
|
878
1155
|
Calculate weighted detection difference for anomaly detection in time series.
|
879
|
-
|
1156
|
+
|
1157
|
+
For each true anomaly segment, each point in the segment is assigned a weight based on a
|
1158
|
+
Gaussian function centered at the segment’s midpoint: points closer to the center receive higher
|
1159
|
+
weights, which decay with distance according to the standard deviation sigma. These weights form
|
1160
|
+
the basis for scoring both correct detections and false alarms.
|
1161
|
+
|
1162
|
+
WS (Weighted Sum) is defined as the sum of Gaussian weights for all predicted anomaly points that
|
1163
|
+
fall within any true anomaly segment (extended by delta time steps at the ends).
|
1164
|
+
WF (False Alarm Weight) is the sum of Gaussian weights for all predicted anomaly points that do
|
1165
|
+
not overlap any true anomaly segment (within the same extension).
|
1166
|
+
|
1167
|
+
The final score is:
|
1168
|
+
WDD = WS - WF*FA
|
1169
|
+
|
1170
|
+
Where:
|
1171
|
+
WS = Σ weights_true_predictions
|
1172
|
+
WF = Σ weights_false_positives
|
1173
|
+
FA (False Anomaly) = number of predicted anomaly segments that do not overlap any true anomaly segment
|
1174
|
+
even within a k-step tolerance window around true points.
|
1175
|
+
|
1176
|
+
For more information, see the original paper:
|
1177
|
+
https://acta.sapientia.ro/content/docs/evaluation-metrics-for-anomaly-detection.pdf
|
880
1178
|
|
881
1179
|
Parameters:
|
882
1180
|
y_true (np.array): The ground truth binary labels for the time series data.
|
@@ -923,7 +1221,17 @@ def weighted_detection_difference(y_true: np.array, y_pred: np.array, k: int):
|
|
923
1221
|
def binary_pate(y_true: np.array, y_pred: np.array, early: int, delay: int):
|
924
1222
|
"""
|
925
1223
|
Calculate PATE score for anomaly detection in time series.
|
926
|
-
|
1224
|
+
|
1225
|
+
PATE evaluates predictions by assigning weighted scores based on temporal proximity
|
1226
|
+
to true anomaly intervals. It uses buffer zones around each true anomaly: an early buffer of length
|
1227
|
+
`early` preceding the interval and a delay buffer of length `delay` following it. Detections within
|
1228
|
+
the true interval receive full weight, while those in the early or delay buffers receive linearly
|
1229
|
+
decaying weights based on distance from the interval edges. Predictions outside these zones are
|
1230
|
+
treated as false positives, and missed intervals as false negatives. The final score balances these
|
1231
|
+
weighted detections into a single measure of performance.
|
1232
|
+
|
1233
|
+
For more information, see the original paper:
|
1234
|
+
https://arxiv.org/abs/2405.12096
|
927
1235
|
|
928
1236
|
Parameters:
|
929
1237
|
y_true (np.array): The ground truth binary labels for the time series data.
|
@@ -940,12 +1248,22 @@ def binary_pate(y_true: np.array, y_pred: np.array, early: int, delay: int):
|
|
940
1248
|
def mean_time_to_detect(y_true: np.array, y_pred: np.array):
|
941
1249
|
"""
|
942
1250
|
Calculate mean time to detect for anomaly detection in time series.
|
943
|
-
|
1251
|
+
|
1252
|
+
This metric quantifies the average detection delay across all true anomaly events.
|
1253
|
+
For each ground-truth anomaly segment, let i be the index where the segment starts,
|
1254
|
+
and let j ≥ i be the first index within that segment where the model predicts an anomaly.
|
1255
|
+
The detection delay for that event is defined as:
|
1256
|
+
Δ = j - i
|
1257
|
+
The MTTD is the mean of all such Δ values, one per true anomaly segment, and expresses
|
1258
|
+
the average number of time steps between the true onset of an anomaly and its first detection.
|
944
1259
|
|
945
1260
|
Parameters:
|
946
1261
|
y_true (np.array): The ground truth binary labels for the time series data.
|
947
1262
|
y_pred (np.array): The predicted binary labels for the time series data.
|
948
1263
|
|
1264
|
+
For more information, see the original paper:
|
1265
|
+
https://arxiv.org/pdf/2211.05244
|
1266
|
+
|
949
1267
|
Returns:
|
950
1268
|
float: The mean time to detect.
|
951
1269
|
"""
|
@@ -953,10 +1271,10 @@ def mean_time_to_detect(y_true: np.array, y_pred: np.array):
|
|
953
1271
|
b = Binary_detection(len(y_true),y_true,y_pred)
|
954
1272
|
a_events = b.get_gt_anomalies_segmentwise()
|
955
1273
|
t_sum = 0
|
956
|
-
for _
|
957
|
-
for i in range(
|
1274
|
+
for a,_ in a_events:
|
1275
|
+
for i in range(a,len(y_pred)):
|
958
1276
|
if y_pred[i] == 1:
|
959
|
-
t_sum+=i-
|
1277
|
+
t_sum+=i-a
|
960
1278
|
break
|
961
1279
|
|
962
1280
|
return t_sum/len(a_events)
|