Skip to content

Commit f5bea33

Browse files
Add z-score fallback metric tracking for anomaly detection tests
- Add is_zscore_fallback field to anomaly scores query (when training_stddev = 0) - Propagate is_zscore_fallback through get_read_anomaly_scores_query - Track zscore_fallback_passed_count and zscore_fallback_failed_count in test results - Add new fields to elementary_test_results schema This enables tracking the number of tests that use z-score fallback (when all training values are identical), with distinction between passed and failed tests. Co-Authored-By: Yosef Arbiv <[email protected]>
1 parent 7b5fec6 commit f5bea33

File tree

4 files changed

+20
-2
lines changed

4 files changed

+20
-2
lines changed

macros/edr/data_monitoring/anomaly_detection/get_anomaly_scores_query.sql

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,10 @@
231231
when training_stddev = 0 then 0 -- Stationary data case - valid, all values are identical
232232
else (metric_value - training_avg) / (training_stddev)
233233
end as anomaly_score,
234+
case
235+
when training_stddev is not null and training_set_size > 1 and training_stddev = 0 then TRUE
236+
else FALSE
237+
end as is_zscore_fallback,
234238
{{ test_configuration.anomaly_sensitivity }} as anomaly_score_threshold,
235239
source_value as anomalous_value,
236240
{{ elementary.edr_cast_as_timestamp('bucket_start') }} as bucket_start,

macros/edr/data_monitoring/anomaly_detection/store_anomaly_test_results.sql

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,21 @@
4848
{% endif %}
4949
{% endset %}
5050
{% set failures = namespace(data=0) %}
51+
{% set zscore_fallback_passed = namespace(data=0) %}
52+
{% set zscore_fallback_failed = namespace(data=0) %}
5153
{% set filtered_anomaly_scores_rows = [] %}
5254
{% for row in anomaly_scores_rows %}
5355
{% if row.anomaly_score is not none %}
5456
{% do filtered_anomaly_scores_rows.append(row) %}
5557
{% if row.is_anomalous %}
5658
{% set failures.data = failures.data + 1 %}
59+
{% if elementary.insensitive_get_dict_value(row, 'is_zscore_fallback') %}
60+
{% set zscore_fallback_failed.data = zscore_fallback_failed.data + 1 %}
61+
{% endif %}
62+
{% else %}
63+
{% if elementary.insensitive_get_dict_value(row, 'is_zscore_fallback') %}
64+
{% set zscore_fallback_passed.data = zscore_fallback_passed.data + 1 %}
65+
{% endif %}
5766
{% endif %}
5867
{% endif %}
5968
{% endfor %}
@@ -69,7 +78,9 @@
6978
'test_results_query': test_results_query,
7079
'test_params': test_params,
7180
'result_rows': filtered_anomaly_scores_rows,
72-
'failures': failures.data
81+
'failures': failures.data,
82+
'zscore_fallback_passed_count': zscore_fallback_passed.data,
83+
'zscore_fallback_failed_count': zscore_fallback_failed.data
7384
} %}
7485
{% set elementary_test_row = elementary.get_dbt_test_result_row(flattened_test) %}
7586
{% do elementary_test_row.update(test_result_dict) %}

macros/edr/system/system_utils/empty_table.sql

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@
2727
('test_short_name', 'string'),
2828
('test_alias', 'string'),
2929
('result_rows', 'long_string'),
30-
('failed_row_count', 'bigint')
30+
('failed_row_count', 'bigint'),
31+
('zscore_fallback_passed_count', 'bigint'),
32+
('zscore_fallback_failed_count', 'bigint')
3133
]) }}
3234
{% endmacro %}
3335

macros/edr/tests/test_utils/get_anomaly_query.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
column_name,
4444
metric_name,
4545
anomaly_score,
46+
is_zscore_fallback,
4647
anomaly_score_threshold,
4748
anomalous_value,
4849
bucket_start,

0 commit comments

Comments
 (0)