Forecasting in Python with Prophet
mode.com
mode.com
Highlights include:
* Pure ML methods are still not competitive with statistical models;
* Ensembles perform better than any single model, an important difference to the last competition;
* Very simple benchmarks can perform very well on this type of competition.
The top 3 included multiple statistical models feeding into an RNN (by an Uber engineer), another ensemble using XGboost for the final layer and a combination of just statistical methods with a clever weighting scheme.
If you're interested in making production-level predictions, it's probably a good idea to ensemble prophet with other methods.
[1] https://en.wikipedia.org/wiki/Makridakis_Competitions
[2] https://www.scribd.com/document/382185710/IJF-Published-M4-P...
I've found that ensembles aren't necessarily more accurate for individual forecasts per se, but in terms of aggregate errors over the long run, they end up being less wrong. (bias-variance tradeoff)
Say you have multiple product lines like iOS-1month, iOS-1year, iOS-1year-premium, Android-1month, web-5years, etc. And you have historical numbers for new users and retention for each product line.
I looked at using Prophet for this, but instead I made a giant spreadsheet and modeled my assumptions around seasonality, retention, and new user growth. I wasn't totally sure, but it seemed like Prophet wasn't intended for my use case, where my assumptions can be stated very explicitly, and I want to twiddle the knobs to look at various scenarios.
However I found Prophet to be computationally a little heavier than auto.arima because it uses "stan" (Bayesian) underneath, which in turn uses an MCMC type approach and has quite a few dependencies. We needed fast model retraining as well, and at the time, it didn't seem like that was something it excelled at. (might have changed, I'm not sure)
I ended up putting together a simple ensemble forecast model class with "statsmodels" which automatically selected/averaged the best models over a collection of model types via heuristics and cross-validation. It works ok, but I'm still waiting for someone to port the R auto.arima over to Python. (I tried rpy, which in theory should have worked, but I struggled with the impedance mismatch)
Thanks for the correction.
I need to look at Prophet again. Maybe it will work for fast model retraining. I had trouble the last time I tried it.
If a transformation f has the property (f^-1 o f)(x) = x then (f^-1 o g o f)(x) should be valid -- though how to rigorously demonstrate this in all cases evades me for now. (there are some conditions that need to be satisfied)
Rob Hyndman, the author of the "forecast" package in R, also thinks it's ok (slide 17 [1])
[1] https://robjhyndman.com/talks/RevolutionR/7-Transformations....
I'm not familiar enough with Prophet to know whether the same logic applies here, though I'd hazard a guess that it does.
Shit, I've forgotten everything, I'm googling model assumptions, boxcox transform, the works
I'm trying to follow your explanation but help me understand better: which model assumptions would it violate?
Typical assumptions for time-series forecasting are stationarity (differencing is used to achieve this if not already the case), residuals are homoskedastic (constant variance) and normally distributed, etc. In fact, the primary use of the Box-Cox is to stabilize the variance and make the data more normal. Box-Cox itself doesn't violate any model assumptions. Forecasting on Box-Cox transformed data shouldn't either -- if anything, Box-Cox attempts to better satisfy the assumptions of time-series forecast models (well, as best it can -- some data just don't want to be normal).
Now the question is whether the inverse Box-Cox (or the entire process) violates any model assumptions. Intuitively, I don't believe it does (and Rob Hyndman, author of book on Forecasting agrees) but I'm not certain how to demonstrate this rigorously.
Here is a paper which addresses the issue in the introduction. https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4024993/
1) Log-transformation: log(Y)
2) Forecast results of transformed data: E[g(log(Y))]
3) Inversion of forecast results: exp(E[g(log(Y))])
4) However, what we really want is the expectation of the transformed-forecasted-inversed results, which is E[exp(g(log(Y)))].
Jensen's inequality states that for a convex function φ,
φ(E[X]) <= E[φ(X)]
And equality is only attained if either X is constant or φ is affine. Since neither is (generally) the case here, therefore
exp(E[g(log(Y))]) < E[exp(g(log(Y)))]
An offset factor ε is needed to correct (3) to (4)
E[exp(g(log(Y)))] = exp(E[g(log(Y))]) * ε
Did I get that right? (Offset changed to multiplicative factor)
It strikes me that if you package the entire thing as a random variable:
Z = exp(G(log(Y)))
and use a different kind of forecast function G : Y -> Y' where Y, Y' ~ Normal, then we don't need the multiplicative factor -- which can be difficult to calculate for an arbitrary transformation. We can just get the expected value of Z, ie. E[Z] = E[exp(G(log(Y)))]. This is not done in the article, but in theory it could be.