Describe the bug
I am following dynamic forecast example but using ExponentialSmoothing instead of NaiveForecaster.
I noticed that the forecaster is not retrained in every step, thus instead of generating 36 1-step forecast it is creating 36-step forecast.
I.e.
y_pred = forecaster.update_predict(y_test, cv)
behaves like
y_pred = forecaster.predict(fh=[i for i in range(36)])
To Reproduce
forecaster = ExponentialSmoothing(trend="add", seasonal="multiplicative", sp=12)
forecaster.fit(y_train)
cv = SlidingWindowSplitter(fh=1)
y_pred = forecaster.update_predict(y_test, cv)
Expected behavior
forecaster is refitted every time step
Additional context
Versions
v0.4.2
System:
python: 3.7.3 (default, Mar 27 2019, 16:54:48) [Clang 4.0.1 (tags/RELEASE_401/final)]
executable: /Users/aria/anaconda3/bin/python
machine: Darwin-19.4.0-x86_64-i386-64bit
Python dependencies:
pip: 19.3.1
setuptools: 41.6.0.post20191030
sklearn: 0.23.2
numpy: 1.19.0
scipy: 1.5.2
Cython: 0.29.21
pandas: 1.1.2
matplotlib: 3.3.0
joblib: 0.16.0
numba: None
pmdarima: None
tsfresh: None
Hi @pradithya, thanks for raising the issue!
fit(). update_predict() with update_params=True. But note that will raise a NotImplementedError because it isn't implemented yet. Updating parameters is usually model specific. I'm not sure if there is a common way to update exponential smoothing models. For state-space models, Kalman filtering could be used, but I'm not sure if the underlying algorithms from statsmodels allows us to do this easily.self._fitted_forecaster in update() as update() is defined in the parent class here. I think we should raise a not implemented error here for now or fix it if possible.update_params to true, as this is what people may expect?NaiveForecaster may also be a somewhat confusing case, because it does update predictions without updating any parameters. Let me know if you want to look into this, help would be very welcome!
Hi @mloning thanks for promptly replying the issue.
If you want to incrementally update the fitted parameters as new data comes in, you have use update_predict() with update_params=True as below. But note that will raise a NotImplementedError because it isn't implemented yet. Updating parameters is usually model specific. I'm not sure if there is a common way to update exponential smoothing models. For state-space models, Kalman filtering could be used, but I'm not sure if the underlying algorithms from statsmodels allows us to do this easily.
Yeah, ExponentialSmoothing doesn't support incremental retraining with partial data. In such case is it good idea if update_predict should fallback to refit/retrain a completely new model in each step? Same goes for other model which doesn't support incremental retrain. So the promise of update_predict() is to return updated forecast as new data come and incremental retrain can be seen as a form of internal implementation / optimization of each model.
In addition, perhaps we should set the default of update_params to true, as this is what people may expect?
Yes, my expectation is the update_params in update_predict() is True by default, since the prediction without changing the model's param is already covered by predict() to some degree.
I can take a stab if you agree with above approach.
update_params should be set to True. update when no other method is implemented/available because this is what people expect fit is for (similar to what you argue about predict and update_predict which I agree with). Adding another kwargs like refit=False may be an option. @pradithya I'm happy if you go ahead and start changing the default of the update_params argument, let's see if that breaks any examples or unit tests!
@fkiraly I'm interested in hearing your thoughts here.
Yes, I already wanted to reply to this.
Regarding interface, @mloning :
I actually think that update should fall back to either "ignore the data", or "refit on all the data" (if available) - simply since it is a standard interface point that should be implemented by a templated class - composites may expect it, e.g., the hedge algorithm or other ensembles.
Similarly how you wouldn't return a NotImplementedError in sklearn fit_predict as long as you have a fit and predict.
Perhaps it can return a warning "update is not implemented, falling back to ..." though.
Regarding update for Holt-Winters specifically:
Isn麓t Holt-Winters following as simple linear recurrence relation?
So, shouldn麓t updating in-principle be somewhat straightforward if tedious to work out, at least not requiring to remember all the training data?
That's for the math/theory side - when it comes to off-shelf update functionality implemented, these do not seem to exist (in R or python). Which may hint at it not being that easy? Thoughts?
Maybe @big-o has some helpful insight on updating Holt-Winters.