Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add NaiveMovingAverage baseline model #1557

Merged
merged 24 commits into from
Mar 7, 2023

Conversation

JanFidor
Copy link
Contributor

@JanFidor JanFidor commented Feb 10, 2023

Fixes #951

Summary

I did a bit of research, and couldn't find anything that would support auto-regressive rolling window, so I implemented it from the ground up. I've decided to use numpy as the backbone of my implementation, main reasons being:

  1. Easy incorporation of multivariate series support with vector operations
  2. Readable
  3. It's very popular when it comes to data science and ml in python, so anyone deciding to contribute to / browse darts' code will most likely be familiar with it

There are a few shortcomings with it, mainly iterating by index and using it to mutate the ndarray, which is a concatenation of the forecasts and the starting sliding window. Personally it feels a little iffy when it comes to clean code, but this approach saves us from an if-else block, which would be even less readable.

My first idea was to use a double linked list -> collections.deque for its popLeft() / append() methods and dynamically keeping a sliding window of forecasts. In the end I decided it wasn't a good idea to introduce this kind of algorithmic heavy approach out of the blue, so I shelved it and went with numpy

Copy link
Collaborator

@madtoinou madtoinou left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for contributing to darts! The PR looks great, just a few small things to address in my opinion.

The rolling-window implementation looks nice, however the np.convolve method could probably have been used in order to obtain a one-liner and avoid the for loop (but at the cost of readability). I don't know which one of the two options is closer to darts' mentality, I'll let @dennisbader decide :)

darts/models/forecasting/baselines.py Outdated Show resolved Hide resolved
darts/models/forecasting/baselines.py Show resolved Hide resolved
@codecov-commenter
Copy link

codecov-commenter commented Feb 15, 2023

Codecov Report

Patch coverage: 98.21% and project coverage change: -0.02 ⚠️

Comparison is base (e56faca) 94.08% compared to head (d14671b) 94.06%.

📣 This organization is not using Codecov’s GitHub App Integration. We recommend you install it so Codecov can continue to function properly for your repositories. Learn more

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1557      +/-   ##
==========================================
- Coverage   94.08%   94.06%   -0.02%     
==========================================
  Files         125      125              
  Lines       11188    11277      +89     
==========================================
+ Hits        10526    10608      +82     
- Misses        662      669       +7     
Impacted Files Coverage Δ
darts/dataprocessing/transformers/boxcox.py 95.91% <90.90%> (-4.09%) ⬇️
...taprocessing/transformers/base_data_transformer.py 96.55% <96.20%> (-0.23%) ⬇️
...sing/transformers/static_covariates_transformer.py 99.30% <98.95%> (+0.85%) ⬆️
darts/dataprocessing/transformers/diff.py 100.00% <100.00%> (ø)
...ocessing/transformers/fittable_data_transformer.py 98.36% <100.00%> (+1.69%) ⬆️
...essing/transformers/invertible_data_transformer.py 97.14% <100.00%> (+0.98%) ⬆️
darts/dataprocessing/transformers/mappers.py 100.00% <100.00%> (ø)
...taprocessing/transformers/missing_values_filler.py 100.00% <100.00%> (ø)
...arts/dataprocessing/transformers/reconciliation.py 99.04% <100.00%> (-0.04%) ⬇️
darts/dataprocessing/transformers/scaler.py 97.29% <100.00%> (-0.27%) ⬇️
... and 12 more

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

☔ View full report at Codecov.
📢 Do you have feedback about the report comment? Let us know in this issue.

Copy link
Contributor

@hrzn hrzn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @JanFidor , looks good! I just have a few pretty small comments.

darts/models/forecasting/baselines.py Outdated Show resolved Hide resolved
darts/models/forecasting/baselines.py Outdated Show resolved Hide resolved
return self.input_chunk_length

def __str__(self):
return f"Naive moving average model, with input_chunk_length={self.input_chunk_length}"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be convenient to use something more concise here, such as

Suggested change
return f"Naive moving average model, with input_chunk_length={self.input_chunk_length}"
return f"NaiveMovingAverage({self.input_chunk_length})"

as it can appear for instance in plots' legends or other such places.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, making it code-like looks much sharper and to the point. I looked around the repo and it seems like most models share this style, but there are some outliers including other NaiveModels. What do you think about opening a new issue for bringing other models in line with it?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good idea 👍

darts/models/forecasting/baselines.py Show resolved Hide resolved
JanFidor and others added 3 commits February 22, 2023 11:04
Co-authored-by: madtoinou <32447896+madtoinou@users.noreply.github.com>
Copy link
Contributor

@hrzn hrzn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks @JanFidor !

@JanFidor
Copy link
Contributor Author

JanFidor commented Mar 7, 2023

Just wanted to say that I had an absolute blast contributing this PR, in big part thanks to your reviews, explanations and patience with the occasional workflow fail on black ; P . Thanks @madtoinou @hrzn !

@madtoinou madtoinou merged commit 92b74db into unit8co:master Mar 7, 2023
@hrzn
Copy link
Contributor

hrzn commented Mar 7, 2023

Just wanted to say that I had an absolute blast contributing this PR, in big part thanks to your reviews, explanations and patience with the occasional workflow fail on black ; P . Thanks @madtoinou @hrzn !

That's great to hear! And your contribution is greatly appreciated 👍 thanks!

alexcolpitts96 pushed a commit to alexcolpitts96/darts that referenced this pull request May 31, 2023
* implement NaiveMovingAverage model

* rename Moving Average Filter

* black

* add NaiveMovingAverage to test local

* delete debug print

* black

* isort

* fix __init__.py file import

* rename window param and delete unnecessary check

* fix MA test param

* add docs changes and deterministic assertion

* use more readable assert syntax

* add loger to raise_if_not

Co-authored-by: madtoinou <32447896+madtoinou@users.noreply.github.com>

* black (again)

---------

Co-authored-by: Julien Herzen <julien@unit8.co>
Co-authored-by: madtoinou <32447896+madtoinou@users.noreply.github.com>
Co-authored-by: Dennis Bader <dennis.bader@gmx.ch>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[New Model] Forecasting with Moving Average
5 participants