Skip to content

Commit

Permalink
[detectors] add inclusive flag to threshold boundaries (#1783)
Browse files Browse the repository at this point in the history
  • Loading branch information
cyrilou242 authored Jan 30, 2025
1 parent b4a5150 commit bf74bba
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,22 @@ private BooleanSeries valueTooHigh(DoubleSeries values) {
if (Double.isNaN(spec.getMax())) {
return BooleanSeries.fillValues(values.size(), false);
}
return values.gt(spec.getMax());
if (spec.isMaxInclusive()) {
return values.gt(spec.getMax());
} else {
return values.gte(spec.getMax());
}
}

private BooleanSeries valueTooLow(DoubleSeries values) {
if (Double.isNaN(spec.getMin())) {
return BooleanSeries.fillValues(values.size(), false);
}
return values.lt(spec.getMin());
if (spec.isMinInclusive()) {
return values.lt(spec.getMin());
} else {
return values.lte(spec.getMin());
}
}

private AnomalyDetectorResult runDetectionOnSingleDataTable(final DataFrame inputDf,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ public class ThresholdRuleDetectorSpec extends AbstractSpec {

private double min = Double.NaN;
private double max = Double.NaN;

private boolean maxInclusive = true;

private boolean minInclusive = true;

public double getMin() {
return min;
Expand All @@ -39,4 +43,22 @@ public ThresholdRuleDetectorSpec setMax(final double max) {
this.max = max;
return this;
}

public boolean isMaxInclusive() {
return maxInclusive;
}

public ThresholdRuleDetectorSpec setMaxInclusive(final boolean maxInclusive) {
this.maxInclusive = maxInclusive;
return this;
}

public boolean isMinInclusive() {
return minInclusive;
}

public ThresholdRuleDetectorSpec setMinInclusive(final boolean minInclusive) {
this.minInclusive = minInclusive;
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public class ThresholdRuleDetectorTest {
private static final long JANUARY_3_2021 = 1609632000000L;
private static final long JANUARY_4_2021 = 1609718400000L;
private static final long JANUARY_5_2021 = 1609804800000L;
private static final long JANUARY_6_2021 = 1609891200000L;

@Test
public void testNoAnomalies() {
Expand Down Expand Up @@ -129,22 +130,24 @@ public void testDetectionRunsOnIntervalOnly() {
public void testAnomaliesUpAndDown() {
Interval interval = new Interval(JANUARY_1_2021, JANUARY_5_2021, DateTimeZone.UTC);
Map<String, DataTable> timeSeriesMap = new HashMap<>();
double minValue = 150;
double maxValue = 350.;
DataFrame currentDf = new DataFrame()
.addSeries(Constants.COL_TIME,
JANUARY_1_2021,
JANUARY_2_2021,
JANUARY_3_2021,
JANUARY_4_2021,
JANUARY_5_2021)
.addSeries(Constants.COL_VALUE, 100., 200., 300., 400., 500.);
JANUARY_5_2021,
JANUARY_6_2021)
.addSeries(Constants.COL_VALUE, 100., minValue, 200., 300., maxValue, 500.);
timeSeriesMap.put(AnomalyDetector.KEY_CURRENT, SimpleDataTable.fromDataFrame(currentDf));

ThresholdRuleDetectorSpec spec = new ThresholdRuleDetectorSpec();
spec.setMonitoringGranularity("P1D");
double minValue = 150;
double maxValue = 350.;
spec.setMin(minValue);
spec.setMax(maxValue);
spec.setMaxInclusive(false);
ThresholdRuleDetector detector = new ThresholdRuleDetector();
detector.init(spec);

Expand All @@ -153,6 +156,7 @@ public void testAnomaliesUpAndDown() {

DoubleSeries outputValueSeries = outputDf.getDoubles(Constants.COL_VALUE);
DoubleSeries expectedValueSeries = DoubleSeries.buildFrom(
minValue,
minValue,
200,
300,
Expand All @@ -163,9 +167,10 @@ public void testAnomaliesUpAndDown() {
BooleanSeries outputAnomalySeries = outputDf.getBooleans(Constants.COL_ANOMALY);
BooleanSeries expectedAnomalySeries = BooleanSeries.buildFrom(
BooleanSeries.TRUE,
BooleanSeries.FALSE, // not an anomaly because equal to minValue and default is to be inclusive of the min
BooleanSeries.FALSE,
BooleanSeries.FALSE,
BooleanSeries.TRUE,
BooleanSeries.TRUE, // anomaly because equal to maxValue and maxInclusive is set to false
BooleanSeries.TRUE);
assertThat(outputAnomalySeries).isEqualTo(expectedAnomalySeries);
}
Expand Down

0 comments on commit bf74bba

Please sign in to comment.