diff --git a/docs/changelog/119637.yaml b/docs/changelog/119637.yaml new file mode 100644 index 0000000000000..c2fd6dc51f068 --- /dev/null +++ b/docs/changelog/119637.yaml @@ -0,0 +1,5 @@ +pr: 119637 +summary: Fix spike detection for short spikes at the tail of the data +area: Machine Learning +type: bug +issues: [] diff --git a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/aggs/changepoint/SpikeAndDipDetector.java b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/aggs/changepoint/SpikeAndDipDetector.java index 365ebe8562d6a..fa632f643ffdf 100644 --- a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/aggs/changepoint/SpikeAndDipDetector.java +++ b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/aggs/changepoint/SpikeAndDipDetector.java @@ -58,7 +58,7 @@ private SpikeOrDip findSpikeOrDip(double[] values, int extent, boolean negate) { int maxEnd = Math.min(maxStart + extent, values.length); double maxSum = sum(values, maxStart, maxEnd, negate); for (int start = maxStart + 1; start <= argmax; start++) { - if (start + extent >= values.length) { + if (start + extent > values.length) { break; } double average = sum(values, start, start + extent, negate); diff --git a/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/aggs/changepoint/SpikeAndDipDetectorTests.java b/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/aggs/changepoint/SpikeAndDipDetectorTests.java index b21a7c4625e83..c80cfffbd7328 100644 --- a/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/aggs/changepoint/SpikeAndDipDetectorTests.java +++ b/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/aggs/changepoint/SpikeAndDipDetectorTests.java @@ -184,4 +184,14 @@ public void testMissingBuckets() { assertThat(change, instanceOf(ChangeType.Spike.class)); assertThat(change.changePoint(), equalTo(10)); } + + public void testSpikeAtTail() { + MlAggsHelper.DoubleBucketValues bucketValues = new MlAggsHelper.DoubleBucketValues( + null, + new double[] { 2, 2, 2, 2, 3, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 9, 8 } + ); + ChangeType change = new SpikeAndDipDetector(bucketValues).detect(0.01); + assertThat(change, instanceOf(ChangeType.Spike.class)); + assertThat(change.changePoint(), equalTo(27)); + } }