Closed stefanproell closed 7 years ago
Thanks for the really awesome description and analysis of the issue. As you said, the LBFGS is hanging and doing so without raising an error that can be caught. Interestingly this does not happen in the R with these same data, the issue seems to be specific to pystan.
I don't know what exactly is causing the optimization to hang with these data, but I think there are things that we can do in prophet to make the optimization problem nicer for small datasets like this. Prophet by default inserts 25 potential changepoints in the time series, which in this case is more than the number of datapoints in the history. This means there are a bunch of unidentifiable parameters in the model, which isn't necessarily a problem for the optimization but I think could be.
In this case of this dataset, using
m = Prophet(n_changepoints=2)
makes it work. I'm not sure though if this is actually fixing the issue generally or if it just fixing it for this one dataset. If you have a whole bunch of datasets like this, could you try all of them with this setting?
Generally we need to adapt the default number of changepoints based on the number of data points.
Is there a hard rule or a rule-of-thumb on the # of change points needed for x data points?
Thank you very much for the quick reply and help. I can confirm that the example works when the number of change points is reduced. For my current application, I set the number of change points equal to the number of data points for data sets with 25 records or less. For data sets having more than 25 historical records, I use the default of 25. This works for my project where I forecast smaller data sets.
n_data_points = len(df.index)
potential_change_points = 25
if(n_data_points < potential_change_points ):
potential_change_points = n_data_points
m = Prophet(weekly_seasonality='auto', yearly_seasonality='auto',n_changepoints=potential_change_points )
The documentation states that the potential change points are selected by the first 80 percent of the historical data.
n_changepoints: Number of potential changepoints to include. Not used
if input `changepoints` is supplied. If `changepoints` is not supplied,
then n.changepoints potential changepoints are selected uniformly from
the first 80 percent of the history.
I suppose I could also select n=0.8* len(df.index) and thereby all potential change points , but this would probably not scale for larger data sets. Is there a generic way of finding a proper value for this setting?
Thanks again, Cheers Stefan
If you look at the dashed lines in the first figure on this page https://facebookincubator.github.io/prophet/docs/trend_changepoints.html you can see what you get with 25 changepoints. You would want to increase past that when the time series experiences trend changes that you need to capture that are happening at a faster rate than that. However, if the trend really is changing every few observations (or, very frequently relative to the forecast horizon), the hope for a useful forecast may be a bit slim.
I think around 25 is a good default choice for longer time series (>a few hundred observations) and I think in most cases there won't be too much value from increasing past there. It would give a quite small change to the quality of the trend fit, and an even smaller change in the quality of the seasonality estimation (the most important part of having a good trend fit). Of course this might not apply if the time series is experiencing very frequent, large trend shifts.
For short time series - having more changepoints than observations introduces variables in the model that are never used and so is entirely unecessary. Having a changepoint for each observation gives the model the potential to change the trend at every data point - which also seems unlikely to be a good strategy. I don't think see much reason to have more than 1 changepoint per 3 or so observations. A changepoint per 3 observations would mean that the location of a trend change would be off by at most 1 observation. This seems pretty reasonable.
In these low-data settings I would also strongly recommend using MCMC sampling (e.g. argument mcmc_samples = 500
) which would then incorporate the trend changepoint parameter uncertainty into the forecast, and will still be relatively fast.
https://github.com/facebookincubator/prophet/commit/0b4ec4a9b3c6d91e2ae70dbc02dd37d25b9758e7 makes it so we don't use more changepoints than we have datapoints, which should prevent this in the future.
I ran into this same problem but with a different series - specifically one that is 490 in length, so longer than the number of changepoints.
Notebook that reproduces issue
This example differs from OP in that it is a significantly longer series (~490 in length) which should mean that it is not that case that there will be more changepoints than datapoints. (It also includes some NaNs.) The STAN output also differs from above in that I've never seen it get to reporting on a single Iter
- I have so far always seen it hang with the same output as in the notebook.
So far, making changes of + or - 1 to any of the values solves the issue (similarly to OP). Also changes in the ds
series solves it.
This is my first exposure to Prophet and STAN, and I think I've reached the soft-limit of my debugging capabilities on this, of course happy to answer any clarifications/questions on the contents of the notebook.
Thanks for the notebook - that's unfortunate to have this issue in a longer time series, I was really hoping it was a matter just of the very short time series.
Things seem to be working on the current v0.2 branch - the notebook runs successfully in both Py 2 and 3. There have been a lot of changes, but I'm suspecting that it will now work for this time series but not for some other. We'll push v0.2 out in a few days and then if the problem persists or there is a time series that produces it I'll debug further. In the meantime, you can try changing up the optimizer by passing along algorithm='Newton'
to fit()
. That might tell if it's something specific to the L-BFGS.
Thanks for the speedy reply. Looking forward to v0.2 as it also solves #258 & #251 which I've been running into.
Do you think it's worth trying v0.2 right now (i.e. cloning branch and installing with setup.py
)?
That'd be great! Right now everything is done for Py, just have a couple R features to wrap up and then documentation update.
This fix has been pushed to CRAN and pypi in v0.2.
Hello @bletham I have run into same issue for a series of 252 data points. It hits to fit method and hangs there like an infinite loop. I am not able to catch with python timeout since it occurs in the stan backend.
Hi @bletham ,
I have run into the same issue. In my case, I use growth='flat'. It hangs forever without any error. But when I change growth='linear', it works fine.
Hey @bletham, I also have been stuck with a similar problem. Most time series in my dataset are of length 400. When the default change_points i.e. 25 are kept and growth is set to 'linear', it works fine. But when the growth is set to 'logistic', it hangs infinitely.
Also note that I have been iterating over each individual time series not with a python for loop but using the applyInPandas utility for executing it on a spark cluster. Reducing the n_changepoints solves the issue but not sure why since default value works well with growth 'linear'.
I am iterating over several hundreds of quite small time series data sets and try to forecast a value for each one of the data sets. I am aware that Facebook Prophet is built for large data sets, but I am experiencing good results also for smaller data sets, except for single outliers, where no useful forecast can be made. One of these outliers causes my script to run forever, without throwing an error or aborting.
Minimal example to reproduce the problem
The following example causes the model optimization for the data set to run for ever and therefore freezes the script which is executing the forecasts.
This is the output, the script freezes at the fit method:
Expected result
The problem is related to the data set. When I change a single error, e.g. the first one, then the little program runs through:
So that works as expected, just by changing one of the values.
Investigation
When debugging the script with IntelliJ IDEA Ultimate, I noticed that the problem is caused by the line 538 in forecaster.py
params = model.optimizing(dat, init=stan_init, iter=1e4, **kwargs)
In cases where my data cannot be processed by Prophet, I would like to have an error thrown on which I can react upon. I found the following issue, which is but not identical to mine here, as I do not receive any error. In the issue, there is a link to the commit with a suggested fix [here] (https://github.com/facebookincubator/prophet/commit/f7becb0942cd0a005d72ae307aefee431fa962d7) I tried to replace the code snippet in a similar way, but catching generic Exceptions instead of only RuntimeErrors. This is my example code:The following does not work, as the optimizing method does not throw any error, but hangs. Trying to investigate on the problem, I noticed that the assignment of the StanFit4Model to the fit_class attribute fails in model.py line 324. In line 472 of model.py, I can see the following error with the debugger:
Unable to get repr for <class 'stanfit4anon_model_7a788197ac3493030b72020b9ffdbe7d_5923200972637382724.StanFit4Model'>
Most properties of the fit object are then undefined (None) and cause the subsequent execution to fail. What would be a quick fix to catch errors and proceed with the tool execution? The following versions are used:Used Python Packages
I use Python 3.6.0 :: Anaconda 4.3.1 (64-bit) on an Ubuntu 14.04 LTS machine. I also tested the same in a Debian Docker container and receive the same problem.
Quick fix?
What would be a quick fix to catch errors and proceed with the tool execution? Thank you!