From 2afef7e852670554321f427f6e5f60da6f3eeb02 Mon Sep 17 00:00:00 2001 From: Agata Benvegna Date: Fri, 28 Nov 2025 15:18:18 +0100 Subject: [PATCH 1/3] Add test on double use of function "evaluate()" --- ats/tests/test_evaluators.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/ats/tests/test_evaluators.py b/ats/tests/test_evaluators.py index cba8342..6701061 100644 --- a/ats/tests/test_evaluators.py +++ b/ats/tests/test_evaluators.py @@ -507,3 +507,23 @@ def test_series_granularity_evaluation(self): evaluation_result2 = _series_granularity_evaluation(flagged_series2,anomaly_labels2) except Exception as e: self.assertIsInstance(e,ValueError) + + def test_double_evaluator(self): + anomalies = ['step_uv'] + effects = [] + series_generator = HumiTempTimeseriesGenerator() + # series1 will be a true anomaly for the minmax + series1 = series_generator.generate(anomalies=anomalies,effects=effects) + # series2 will be a false positive for minmax (it sees always 2 anomalous data points for each variable) + series2 = series_generator.generate(anomalies=[],effects=effects) + dataset = [series1,series2] + evaluator = Evaluator(test_data=dataset) + minmax1 = MinMaxAnomalyDetector() + minmax2 = MinMaxAnomalyDetector() + minmax3 = MinMaxAnomalyDetector() + models={'detector_1': minmax1, + 'detector_2': minmax2, + 'detector_3': minmax3 + } + evaluation_results = evaluator.evaluate(models=models,granularity='series') + evaluation_results = evaluator.evaluate(models=models,granularity='series') From d002747d065a60f5c04aa683aee7f4ce1733dfaa Mon Sep 17 00:00:00 2001 From: Agata Benvegna Date: Fri, 28 Nov 2025 15:45:47 +0100 Subject: [PATCH 2/3] Change the function "_format_for_anomaly_detector()" Now the column "anomaly_label" is deleted not inplace. This solves the problem with the double call of the "evaluate()" fuction --- ats/evaluators.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ats/evaluators.py b/ats/evaluators.py index 56187b9..7de5f7a 100644 --- a/ats/evaluators.py +++ b/ats/evaluators.py @@ -9,8 +9,8 @@ def _format_for_anomaly_detector(input_df,synthetic=False): raise ValueError('The input DataFrame has to contain an "anomaly_label" column for evaluation') anomaly_labels = input_df.loc[:,'anomaly_label'] - input_df.drop(columns=['anomaly_label'],inplace=True) - return input_df,anomaly_labels + output_df = input_df.drop(columns=['anomaly_label'],inplace=False) + return output_df,anomaly_labels def evaluate_anomaly_detector(evaluated_timeseries_df, anomaly_labels, details=False): From 4f02268db4aad0aa54db99c631a67972266765b2 Mon Sep 17 00:00:00 2001 From: Agata Benvegna Date: Fri, 28 Nov 2025 16:03:35 +0100 Subject: [PATCH 3/3] Change function "_format_for_anomaly_detector()" "input_df" renamed to "df" Now the column "effect_label" is deleted with not inplace operation --- ats/evaluators.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ats/evaluators.py b/ats/evaluators.py index 7de5f7a..c85c98a 100644 --- a/ats/evaluators.py +++ b/ats/evaluators.py @@ -2,15 +2,15 @@ import pandas as pd from copy import deepcopy -def _format_for_anomaly_detector(input_df,synthetic=False): +def _format_for_anomaly_detector(df,synthetic=False): if synthetic: - input_df.drop(columns=['effect_label'],inplace=True) - if 'anomaly_label' not in input_df.columns: + df = df.drop(columns=['effect_label'],inplace=False) + if 'anomaly_label' not in df.columns: raise ValueError('The input DataFrame has to contain an "anomaly_label" column for evaluation') - anomaly_labels = input_df.loc[:,'anomaly_label'] - output_df = input_df.drop(columns=['anomaly_label'],inplace=False) - return output_df,anomaly_labels + anomaly_labels = df.loc[:,'anomaly_label'] + df = df.drop(columns=['anomaly_label'],inplace=False) + return df,anomaly_labels def evaluate_anomaly_detector(evaluated_timeseries_df, anomaly_labels, details=False):