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.
@@ -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
- Calculate point-adjusted recall for anomaly detection in time series.
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): The maximum number of time steps within which an anomaly must be predicted to be considered detected.
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): The maximum number of time steps within which an anomaly must be predicted to be considered detected.
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): The maximum number of time steps within which an anomaly must be predicted to be considered detected.
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
- y_true (np.array): The ground truth binary labels for the time series data.
407
- y_pred (np.array): The predicted binary labels for the time series data.
408
- beta (float): The beta value, which determines the weight of precision in the combined score.
409
- Default is 1, which gives equal weight to precision and recall.
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
- float: The composite F-score, which is the harmonic mean of precision and recall, adjusted by the beta value.
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()#point_wise_precision(y_true,y_pred)
520
+ precision = m.precision()
418
521
 
419
522
  #Segment wise recall
420
- recall = m.recall()#segment_wise_recall(y_true,y_pred)
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): A parameter that controls the length of the range considered for true positives.
496
- bias (str): The type of bias to apply for weighting (flat, front-end, back-end, middle).
497
- cardinality (str, optional): ["one", "reciprocal", "udf_gamma"]. Defaults to "one".
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): A parameter that controls the length of the range considered for true positives.
517
- bias (str): The type of bias to apply for weighting (flat, front-end, back-end, middle).
518
- cardinality (str, optional): ["one", "reciprocal", "udf_gamma"]. Defaults to "one".
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): A parameter that controls the length of the range considered for true positives.
541
- p_bias: string, default="flat"
542
- Positional bias for precision. This should be "flat", "front", "middle", or "back"
543
- r_bias: string, default="flat"
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): A parameter that controls the length of the range considered for true positives.
568
- past_range: Determines if the range is considered in the past or future as specified in https://www.mdpi.com/2079-9292/11/8/1213
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): A parameter that controls the length of the range considered for true positives.
587
- past_range: Determines if the range is considered in the past or future as specified in https://www.mdpi.com/2079-9292/11/8/1213
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): A parameter that controls the length of the range considered for true positives.
607
- beta (float): The beta value, which determines the weight of precision in the combined score.
608
- Default is 1, which gives equal weight to precision and recall.
609
- past_range: Determines if the range is considered in the past or future as specified in https://www.mdpi.com/2079-9292/11/8/1213
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
- alpha (float): A parameter that controls the length of the range considered for true positives.
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
- alpha (float): A parameter that controls the length of the range considered for true positives.
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, beta: float, theta_p: float, theta_r: float):
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
- beta (float): The beta value, which determines the weight of precision in the combined score.
676
- Default is 1, which gives equal weight to precision and recall.
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 time series aware F-score, which is the harmonic mean of precision and recall, adjusted by the beta value.
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
- beta (float): The beta value, which determines the weight of precision in the combined score.
716
- Default is 1, which gives equal weight to precision and recall.
933
+
717
934
 
718
935
  Returns:
719
- float: The time series aware F-score, which is the harmonic mean of precision and recall, adjusted by the beta value.
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
- Default is 1, which gives equal weight to precision and recall.
959
+
737
960
 
738
961
  Returns:
739
- float: The time series aware F-score, which is the harmonic mean of precision and recall, adjusted by the beta value.
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, which is the harmonic mean of precision and recall, adjusted by the beta value.
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, which is the harmonic mean of precision and recall, adjusted by the beta value.
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): The maximum number of time steps within which an anomaly must be predicted to be considered detected.
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): The maximum number of time steps within which an anomaly must be predicted to be considered detected.
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
- The weighted detection difference is the difference between the number of true positives and the number of false positives, weighted by the number of true positives.
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
- The PATE score is the ratio of the number of true positives to the sum of true positives, false positives, and false negatives, within a given early and delay range.
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
- The mean time to detect is the average number of time steps between the ground truth anomaly and the predicted anomaly.
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 _,b in a_events:
957
- for i in range(b,len(y_pred)):
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-b
1277
+ t_sum+=i-a
960
1278
  break
961
1279
 
962
1280
  return t_sum/len(a_events)