Is there a way to store a model and retrain it every day with new daily data?
I can pickle a model and load it, but I don't know how to retrain it with new data.
I think this is it #46
I will try to implement something else.
Thanks anyways for working on this model
Do you see any problems if I save initial trained model params and then pass them to fit function on every subsequent run?
Now self.params are always initialized with stan_init(). If I replace this with existing params, will everything else work out of the box? The goal is to speed up convergence.
I have two years of data with 30MIN time interval and backtesting on a daily basis takes forever. Partial fit (feed new data to the model) should be a core feature for time series model. Great job overall.
@kr1stjans that approach is good, the only thing you will have to worry about is that the changepoints line up well enough across the two time series.
By default, 25 changepoints are placed uniformly through the first 80% of the time series. Suppose your time series has grown by 1% since the last fit. Then, each of the two time series (old and new) will have the same number of changepoints (25), but they will be in slightly different places - the location in time will differ by ~1%. This is not very far, and so it probably wouldn't be an issue to initialize with the values from old and I would expect that it could speed up convergence dramatically.
Things can be a bit more complicated if the difference between the time series is larger. For the sake of simplicity, let's say we have changepoints at t=1,2,3, and 4. The model will fit trend changes at those points. Now suppose I have doubled the length of the time series. The model will now place the same number of changepoints, but again uniformly throughout the first part of the time series. So it will have changepoints at, for instance, t=2, 4, 6, and 8. Taking the fitted changepoints for 1, 2, 3, and 4 and using them as an initialization for changepoints at 2, 4, 6, 8 isn't quite what we want and could actually make things slower.
What you'd want to do is manually specify changepoints for the first time series (say, at 2 and 4) (this can be done with the changepoints input). Then when you double your data, manually specify changepoints as (2, 4, 6, 8). Initialize 2 and 4 to their fitted values from before, and initialize 6 and 8 to zero (as is currently done by default).
Anyway, those are all of the considerations. If you're interested in contributing this as a new feature, let's discuss in #46 what the interface would look like. But otherwise for your personal use, then as long as the time series isn't growing too much between refits I'd expect this to work just fine. If you try it, let me know how it goes!
@bletham I found your suggestions here very useful. However, I'm having trouble with the practical implementation of the following:
Initialize 2 and 4 to their fitted values from before, and initialize 6 and 8 to zero (as is currently done by default).
It seems like all this is done deep in the guts of the fit function and in order to do this I would have to re-implement that function. Does this sound correct? It's not a big deal if that's the case, just wondering if there's an already implemented mechanism that can be re-purposed for this, so I don't duplicate effort.
@vlsd that's right, it's here:
https://github.com/facebook/prophet/blob/d9bea6196981bfcedae40525e702d424d26e7cd0/python/fbprophet/forecaster.py#L1123-L1129
So instead of initializing things to zeros, you'd want to initialize to the previous values (except for the adjustment on delta to account for the possibly changed number of changepoints). This will require changing the fit function, but I think it could be a small change (for instance, add a kwarg for optionally passing in stan_init directly).
Thanks @bletham! I've actually passed the params to the init kwarg of the fit function, which seems to flow directly to the stan backend's fit function as an initial guess and so far this seems to work!
@vlsd how are you able to pass the init kwargs via python prophet? I had issues with this (says kwargs not recognized for pystan.Stanmodel) and am interested in your solution here.
@vlsd how are you able to pass the init kwargs via python prophet? I had issues with this (says kwargs not recognized for pystan.Stanmodel) and am interested in your solution here.
@GinoWoz1 I don't have direct access to the code right now, but I vaguely remember reading the pystan code to see what arguments it expects and renaming the prophet variables as needed before passing them as kwargs (the naming wasn't one to one). If I manage to find the code I'll post a snippet.
There's an example on how to do this now in the documentation: https://facebook.github.io/prophet/docs/additional_topics.html#updating-fitted-models
Per https://discourse.mc-stan.org/t/different-outputs-in-rstan-vs-pystan/211/27 I have to use extra_compile_args and when I input it in the fit the command is not recognized. Rstan and Pystan have different outputs and need to update this; linking the similar #316 issue. I see **kwargs passes the arguments to sampling and optimizing but I don't see where I can input :extra_compile_args=['-O3', "-march=native", "-mtune=native"]. Any idea ?
There's an example on how to do this now in the documentation: https://facebook.github.io/prophet/docs/additional_topics.html#updating-fitted-models
Model compilation happens during install. If you need to change that, then you'd want to download the source from here and install it that way. These are the default makevars in R: https://github.com/facebook/prophet/blob/master/R/src/Makevars and in Py the building happens here: https://github.com/facebook/prophet/blob/20f590b7263b540eb5e7a116e03360066c58de4d/python/fbprophet/models.py#L218-L227
Most helpful comment
@kr1stjans that approach is good, the only thing you will have to worry about is that the changepoints line up well enough across the two time series.
By default, 25 changepoints are placed uniformly through the first 80% of the time series. Suppose your time series has grown by 1% since the last fit. Then, each of the two time series (old and new) will have the same number of changepoints (25), but they will be in slightly different places - the location in time will differ by ~1%. This is not very far, and so it probably wouldn't be an issue to initialize with the values from old and I would expect that it could speed up convergence dramatically.
Things can be a bit more complicated if the difference between the time series is larger. For the sake of simplicity, let's say we have changepoints at t=1,2,3, and 4. The model will fit trend changes at those points. Now suppose I have doubled the length of the time series. The model will now place the same number of changepoints, but again uniformly throughout the first part of the time series. So it will have changepoints at, for instance, t=2, 4, 6, and 8. Taking the fitted changepoints for 1, 2, 3, and 4 and using them as an initialization for changepoints at 2, 4, 6, 8 isn't quite what we want and could actually make things slower.
What you'd want to do is manually specify changepoints for the first time series (say, at 2 and 4) (this can be done with the
changepointsinput). Then when you double your data, manually specify changepoints as (2, 4, 6, 8). Initialize 2 and 4 to their fitted values from before, and initialize 6 and 8 to zero (as is currently done by default).Anyway, those are all of the considerations. If you're interested in contributing this as a new feature, let's discuss in #46 what the interface would look like. But otherwise for your personal use, then as long as the time series isn't growing too much between refits I'd expect this to work just fine. If you try it, let me know how it goes!