Prophet › Implementation in Prophet
Machine Learning from ScratchAll chapters Prophet › Implementation in ProphetOne section · Sections in this chapter5 / 8 ↓
Reading tools Definitions & inline links
Choose your expertise level to adjust how many terms are explained. Beginners see more tooltips, experts see fewer to maintain reading flow. Hover over underlined terms for instant definitions.
Article links
Make inline references clickable
Prophet provides a straightforward Python API that makes time series forecasting accessible. Let's implement a complete forecasting workflow using the Prophet library.
Framework Selection:
We use the Prophet library because it's specifically designed for time series forecasting with an intuitive API, automatic parameter tuning, and built-in visualization capabilities. Prophet abstracts away the statistical complexity while providing the flexibility to customize the model when needed.
import warnings
from datetime import datetime
import numpy as np
import pandas as pd
warnings.filterwarnings("ignore")
# Load or create time series data
# For this example, we'll create realistic e-commerce sales data
np.random.seed(42)
# Create daily sales data for 2 years
start_date = datetime(2022, 1, 1)
end_date = datetime(2023, 12, 31)
dates = pd.date_range(start=start_date, end=end_date, freq="D")
# Generate realistic sales data with multiple components
sales_data = []
for i, date in enumerate(dates):
# Base trend: gradual growth
trend = 1000 + 2 * i
# Weekly seasonality: higher on weekends
day_of_week = date.weekday()
weekly_seasonal = 200 * np.sin(2 * np.pi * day_of_week / 7)
# Yearly seasonality: peak in December, dip in January
day_of_year = date.timetuple().tm_yday
yearly_seasonal = 300 * np.sin(2 * np.pi * day_of_year / 365.25)
# Holiday effects
holiday_effect = 0
if date.month == 12 and date.day == 25: # Christmas
holiday_effect = 500
elif date.month == 11 and date.day == 24: # Black Friday
holiday_effect = 400
# Random noise
noise = np.random.normal(0, 50)
# Total sales
total_sales = (
trend + weekly_seasonal + yearly_seasonal + holiday_effect + noise
)
sales_data.append(max(0, total_sales)) # Ensure non-negative sales
# Create DataFrame in Prophet format
df = pd.DataFrame({"ds": dates, "y": sales_data})
print("Sample of our e-commerce sales data:")
print(df.head(10))
print("\nData summary:")
print(f"Date range: {df['ds'].min()} to {df['ds'].max()}")
print(f"Mean daily sales: ${df['y'].mean():.2f}")
print(f"Sales standard deviation: ${df['y'].std():.2f}")Sample of our e-commerce sales data:
ds y
0 2022-01-01 835.010598
1 2022-01-02 849.039907
2 2022-01-03 1051.859737
3 2022-01-04 1259.144412
4 2022-01-05 1217.049745
5 2022-01-06 1115.979314
6 2022-01-07 1040.221743
7 2022-01-08 898.541775
8 2022-01-09 882.421198
9 2022-01-10 1096.481120
Data summary:
Date range: 2022-01-01 00:00:00 to 2023-12-31 00:00:00
Mean daily sales: $1730.28
Sales standard deviation: $419.37Our dataset contains 730 days of daily sales data spanning two years. The mean daily sales of approximately $1,730 with a standard deviation of about $350 indicates moderate variability around the trend. This level of variation is typical for e-commerce data where daily fluctuations are expected, but the overall trend and seasonal patterns should be learnable by Prophet.
Now let's implement the Prophet model with proper configuration:
# Initialize Prophet model with custom parameters
model = Prophet(
# Seasonality settings
yearly_seasonality=True, # Enable yearly patterns
weekly_seasonality=True, # Enable weekly patterns
daily_seasonality=False, # Disable daily (we have daily data but want weekly patterns)
# Trend flexibility
changepoint_prior_scale=0.05, # Lower = less flexible trend changes
changepoint_range=0.8, # Proportion of data to consider for changepoints
# Seasonality strength
seasonality_prior_scale=10.0, # Higher = more flexible seasonality
seasonality_mode="additive", # Additive seasonality (default)
# Uncertainty intervals
interval_width=0.95, # 95% confidence intervals
mcmc_samples=0, # Use MAP estimation (faster than MCMC)
)
# Add custom holidays
holidays = pd.DataFrame(
{
"holiday": [
"christmas",
"new_year",
"black_friday",
"christmas",
"new_year",
],
"ds": pd.to_datetime(
[
"2022-12-25",
"2023-01-01",
"2023-11-24",
"2023-12-25",
"2024-01-01",
]
),
"lower_window": [-1, -1, -1, -1, -1], # Effect starts 1 day before
"upper_window": [1, 1, 1, 1, 1], # Effect ends 1 day after
}
)
model.add_country_holidays(country_name="US") # Add US holidays
model.add_seasonality(
name="monthly", period=30.5, fourier_order=5
) # Custom monthly seasonality
# Fit the model
print("Fitting Prophet model...")
model.fit(df)
print("Model fitting completed!")Fitting Prophet model... Model fitting completed!
The model has successfully fitted to our data. Prophet has learned the trend, weekly seasonality, yearly seasonality, monthly patterns, and holiday effects from the historical sales data. The fitting process uses Bayesian inference to estimate all parameters, which typically completes in a few seconds for datasets of this size.
Now let's make forecasts and analyze the results:
# Create future dataframe for forecasting
future = model.make_future_dataframe(
periods=90, freq="D"
) # Forecast 90 days ahead
# Make predictions
forecast = model.predict(future)
# Display forecast summary
print("Forecast Summary:")
print(f"Forecast period: {future['ds'].min()} to {future['ds'].max()}")
print(f"Number of future periods: {len(future) - len(df)}")
print(f"Mean predicted sales: ${forecast['yhat'].mean():.2f}")
print(f"Forecast uncertainty (std): ${forecast['yhat'].std():.2f}")
# Show last few predictions
print("\nLast 10 forecasted values:")
print(forecast[["ds", "yhat", "yhat_lower", "yhat_upper"]].tail(10))Forecast Summary:
Forecast period: 2022-01-01 00:00:00 to 2024-03-30 00:00:00
Number of future periods: 90
Mean predicted sales: $1840.44
Forecast uncertainty (std): $507.00
Last 10 forecasted values:
ds yhat yhat_lower yhat_upper
810 2024-03-21 2972.696881 2871.126845 3067.132860
811 2024-03-22 2796.113255 2701.196403 2898.423580
812 2024-03-23 2697.933289 2598.498186 2795.003799
813 2024-03-24 2753.401189 2644.693233 2855.981746
814 2024-03-25 2913.525864 2813.181167 3003.714214
815 2024-03-26 3078.671859 2979.326781 3183.335892
816 2024-03-27 3107.937859 3009.645537 3207.124403
817 2024-03-28 3005.476061 2903.946376 3104.973919
818 2024-03-29 2826.216029 2723.305132 2930.047737
819 2024-03-30 2720.958837 2625.261519 2810.988038The forecast extends 90 days into the future. The mean predicted sales value combines the projected trend with recurring seasonal patterns and holiday effects. The forecast uncertainty, measured by the standard deviation of predictions, indicates how confident the model is in its forecasts. Higher uncertainty typically occurs during periods with less historical data or greater variability.
The last 10 forecasted values show both point predictions (yhat) and uncertainty intervals (yhat_lower and yhat_upper). These intervals represent the 95% confidence range, meaning we expect the actual values to fall within this range 95% of the time. Wider intervals indicate higher uncertainty, which is normal when forecasting further into the future.
Let's visualize our Prophet model:


Alternative Implementation: Manual Parameter Tuning
For advanced users who want more control over the model, here's how to manually tune Prophet parameters:
# Advanced Prophet configuration with manual tuning
advanced_model = Prophet(
# Trend parameters
growth="linear", # Use linear growth (vs 'logistic')
changepoint_prior_scale=0.01, # Very conservative changepoints
changepoint_range=0.9, # Use 90% of data for changepoint detection
# Seasonality parameters
yearly_seasonality=True,
weekly_seasonality=True,
daily_seasonality=False,
seasonality_prior_scale=20.0, # More flexible seasonality
seasonality_mode="additive", # Additive (vs 'multiplicative')
# Holiday parameters
holidays_prior_scale=10.0, # Holiday effect strength
# Uncertainty
interval_width=0.8, # 80% confidence intervals
mcmc_samples=100, # Use MCMC for uncertainty (slower but more accurate)
)
# Add custom seasonalities
advanced_model.add_seasonality(
name="quarterly",
period=91.25, # ~3 months
fourier_order=8, # More complex quarterly patterns
prior_scale=15.0,
)
# Add custom regressors (external variables)
# Note: This would require additional data columns
# advanced_model.add_regressor('marketing_spend', prior_scale=0.5)
# Fit the advanced model
print("Fitting advanced Prophet model with manual tuning...")
advanced_model.fit(df)
print("Advanced model fitting completed!")
# Make forecast with advanced model
advanced_future = advanced_model.make_future_dataframe(periods=90, freq="D")
advanced_forecast = advanced_model.predict(advanced_future)
print(f"Advanced model forecast mean: ${advanced_forecast['yhat'].mean():.2f}")
print(f"Standard model forecast mean: ${forecast['yhat'].mean():.2f}")Fitting advanced Prophet model with manual tuning... Advanced model fitting completed! Advanced model forecast mean: $1840.86 Standard model forecast mean: $1840.44
The advanced model uses more conservative changepoint settings and MCMC sampling for uncertainty estimation, which provides more accurate uncertainty intervals at the cost of longer computation time. Comparing the forecast means between the standard and advanced models helps assess sensitivity to parameter choices. Similar means indicate that these parameter variations have little effect on the forecasts.
Key Parameters
Below are some of the main parameters that affect how Prophet works and performs.
-
yearly_seasonality: Enable or disable yearly seasonal patterns (default: 'auto'). Set toTruefor yearly data,Falseto disable, or 'auto' to let Prophet decide based on data frequency. -
weekly_seasonality: Enable or disable weekly seasonal patterns (default: 'auto'). Useful for daily data with day-of-week effects. Set toFalsefor monthly or yearly data. -
daily_seasonality: Enable or disable daily seasonal patterns (default: 'auto'). Typically only needed for sub-daily data (hourly, etc.). -
changepoint_prior_scale: Controls flexibility of trend changes (default: 0.05). Lower values (0.01-0.05) create stable trends, higher values (0.1-0.5) allow more adaptation. Start with 0.05 and adjust based on how much your trend changes. -
changepoint_range: Proportion of data to consider for changepoints (default: 0.8). Values of 0.8-0.9 work well for most cases, excluding the most recent data from changepoint detection. -
seasonality_prior_scale: Controls strength of seasonal patterns (default: 10.0). Increase (15-20) for strong, consistent seasonality. Decrease (5-8) for weak or noisy seasonal patterns. -
seasonality_mode: Type of seasonality (default: 'additive'). Use 'additive' when seasonal effects are constant regardless of trend level. Use 'multiplicative' when seasonal effects scale with the trend. -
holidays_prior_scale: Controls strength of holiday effects (default: 10.0). Increase for holidays with large impacts, decrease if holiday effects are subtle. -
interval_width: Width of uncertainty intervals (default: 0.80 for 80% intervals). Set to 0.95 for 95% intervals, which are wider but more conservative. -
mcmc_samples: Number of MCMC samples for uncertainty (default: 0, uses MAP). Set to 100-1000 for more accurate uncertainty intervals, but expect 10-100x slower fitting.
Key Methods
The following are the most commonly used methods for interacting with Prophet models.
-
fit(df): Trains the Prophet model on historical data. The DataFramedfshould have columns 'ds' (dates) and 'y' (values). Returns the fitted model object. -
predict(df): Generates forecasts for the dates indf. The DataFrame should have a 'ds' column with future dates. Returns a DataFrame with predictions (yhat) and uncertainty intervals (yhat_lower,yhat_upper). -
make_future_dataframe(periods, freq): Creates a DataFrame with historical dates plus future periods for forecasting.periodsis the number of future periods,freqis the frequency ('D' for daily, 'M' for monthly, etc.). -
plot(forecast): Creates a visualization of the forecast showing historical data, fitted values, and future predictions with uncertainty intervals. -
plot_components(forecast): Creates a decomposition plot that separates the trend from seasonal and holiday effects. -
add_country_holidays(country_name): Adds built-in holidays for a specific country (e.g., 'US', 'UK', 'CN'). Prophet includes holiday calendars for many countries. -
add_seasonality(name, period, fourier_order, prior_scale): Adds a custom seasonal pattern. Useful for quarterly patterns, bi-weekly patterns, or other non-standard seasonalities. -
add_regressor(name, prior_scale): Adds an external regressor (additional predictor variable). Requires the regressor values to be included in both training and future DataFrames.