Repository navigation
fix(outliers): spikes and dips in one segment no longer mask each other - #31
Merged
Merged
Conversation
The cpt outlier test computed the segment mean and sd with the spikes in them: a big spike inflated the sd and hid itself and its neighbours. A point is now also an outlier when it is more than 5 sd from the mean of the other points (leave-one-out, farthest first, O(n) per pass), and outliers are replaced by a linear interpolation of their neighbours instead of the segment mean. [review: diff relu (seuils, segments courts, séries intermittentes, coût O(n)) ; tests ciblés rouge→vert ; suite complète verte sur la branche installée]
uvr sync --frozen failed in the image build: CRAN published globals 0.20.0, so the lock no longer matched the manifest. Regenerated with uvr 0.4.6 (same version as the Dockerfile); only globals changes. [review: diff du lock relu, 1 paquet (globals 0.19.1 -> 0.20.0)]
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
With
preprocessing: {"outliers": true}, several spikes or dips in the same series mask each other. Seen on agent-dev (engine 0.1.5) with 24 months of trend (100 -> 184), spikes at 950 and 900 and a dip at 5: only the 900 was corrected, and it was brought to 212 while the trend is at ~169 there.outliers_detection(method_ls = "cpt")tests|x - mean| > 3 sdinside each changepoint segment, with the mean and sd computed with the spikes in them. Recomputed on that series (cut at 11): segment 1-11 has sd 257, so 950 sits at 2.99 sd and 5 at 0.69 sd; segment 11-24 catches 900 at 3.46 sd and replaces it with the segment mean, 212.4 (the API returned 212).Fix
.segment_outliers()). Leave-one-out scores are computed in O(n) per pass (.deleted_z()), so long segments stay cheap.docs/API.mdandNEWS.mdupdated..merge_short_segments()is unchanged.On the series above: 3 corrections, 950 -> 114, 5 -> 132, 900 -> 166.
Bench
timetk::m4_monthly, defects injected at random positions, 100 draws per case, same script and seed before/after (absolute numbers differ from #26's table, which used another script; the deltas are comparable). "corrected" = the point ends up at less than half of its injected deviation from the true value; "error" = median |corrected - true| / true over corrected points; "other changed" = points changed that were not injected, per series.multi= a x3 spike, a -80 % dip and a x2 spike in the same series.Detection never goes down; false corrections go up by 0.03 per clean 36-month series and 0.25 per full series.
Variants tried and dropped (same bench):
forecast::tsoutliers()approach, basestatsonly): 1.36 false corrections per clean 36-month series;multigain is gone.multi.Tests
tests/testthat/test-outliers-spikes.R: the 24-month series above (3 points changed, replacements close to the neighbours), the API report lists the 3 dates, and.deleted_z()matches a direct leave-one-out computation. Against main (0.1.5 image,pkgload::load_all()): 7 failures/errors; after: all pass.apowerb/th2forecast:0.1.5image, as CI tests the installed package:test_dir(..., stop_on_failure = TRUE)exit 0.Not changed
anomaliesis the step for that).preprocessing_data()also callsoutliers_detection(method_ls = "cpt")and gets the same new behaviour.