Trying to Understand FB Prophet Cross Validation
ML System Design practice on Codemia
Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.
Introduction
Cross-validation in Prophet is not ordinary random-fold validation. It is a time-aware backtesting procedure that repeatedly fits the model on historical data up to a cutoff date, forecasts forward for a chosen horizon, and compares those forecasts with the actual values that came after the cutoff.
What Prophet Cross-Validation Is Actually Doing
If you shuffle time-series rows, you leak future information into the training set. Prophet avoids that by using simulated historical forecasts.
For each cutoff:
- fit the model using only data up to that cutoff
- forecast the future for the specified horizon
- compare predictions with real observed values in that future window
This is often called rolling-origin evaluation or forward-chaining validation.
The important Prophet parameters are:
- '
horizon: how far into the future each fold predicts' - '
initial: how much history is used before the first cutoff' - '
period: spacing between cutoffs'
According to the Prophet diagnostics documentation, the default initial window is three times the horizon and the default period is half the horizon.
A Runnable Python Example
The following example creates a simple synthetic daily series and evaluates a Prophet model with cross-validation.
This produces a dataframe where each row corresponds to an out-of-sample forecasted point. The cutoff column tells you which training window produced that prediction.
How to Read the Output
The df_cv dataframe usually contains:
- '
ds: the predicted timestamp' - '
cutoff: the last timestamp included in training' - '
y: the actual observed value' - '
yhat: the forecast' - '
yhat_lowerandyhat_upper: the prediction interval'
This means a single observed date can appear multiple times if it was forecast from multiple earlier cutoffs. That is normal. Cross-validation here is measuring how the model behaves from different historical starting points.
The performance_metrics helper summarizes those rows into measures such as:
- RMSE
- MAE
- MAPE
- coverage
Coverage is especially useful in Prophet because it tells you how often actual values fall inside the forecast interval.
Choosing initial, period, and horizon
These parameters should match the business question, not just arbitrary defaults.
If you care about forecasts 30 days ahead, set the horizon around 30 days. If you need quarterly planning, use a longer horizon.
The initial window must be long enough to capture the patterns your model needs. Prophet's documentation explicitly notes that the initial period should be long enough to include relevant seasonal structure, such as at least a full yearly cycle if yearly seasonality matters.
The period controls how many cutoff dates you evaluate. A smaller period gives more folds and more compute cost. A larger period gives fewer folds and coarser diagnostics.
In practice:
- small horizon for short-term operational forecasts
- large horizon for planning-style forecasts
- larger initial window when the series has yearly seasonality or extra regressors
What This Is Good For
Prophet cross-validation is useful for:
- comparing parameter choices
- checking how forecast error grows with prediction distance
- validating whether intervals are too narrow or too wide
- testing whether seasonal terms and regressors are helping
It is often better than looking at one final train-test split, because one split may be unusually easy or unusually hard.
Prophet also supports parallelized cross-validation in Python, which is useful once the number of cutoffs becomes large.
Common Pitfalls
The most common mistake is treating Prophet cross-validation like random k-fold validation. Time series must respect temporal order.
Another issue is choosing an initial window that is too short. If the model has yearly seasonality but the first training fold does not contain a full year, the diagnostic result can be misleading.
Developers also misread the output by assuming each row is an independent fold summary. It is not. df_cv contains per-prediction rows, and metrics are computed afterward.
Finally, cross-validation can be expensive. Every cutoff refits the model, so reduce the number of cutoffs if diagnostics are taking too long.
Summary
- Prophet cross-validation is rolling historical backtesting, not random-fold validation.
- '
horizonis forecast distance,initialis the first training window, andperiodcontrols cutoff spacing.' - The output rows show out-of-sample predictions tied to specific cutoff dates.
- Use
performance_metricsto summarize forecast accuracy and interval quality. - Choose validation windows that reflect the real forecasting horizon and seasonality in your problem.
Related reading
- Trying to use LinearRegressor
- Tuning XGBoost Hyperparameters with RandomizedSearchCV
- Turn Pandas Multi-Index into column
- Type hinting / annotation PEP 484 for numpy.ndarray
- TypeError concat got multiple values for argument 'axis
- TypeError only integer scalar arrays can be converted to a scalar index
- TypeError only integer scalar arrays can be converted to a scalar index with 1D numpy indices array
- U-matrix and self organizing maps
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
ML System Design practice on Codemia
Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.