How to Use Facebook Prophet in Python

• Prophet requires your time series data in a specific two-column format with 'ds' for dates and 'y' for values—any other structure will fail, so data preparation is your first critical step.

Key Insights

• Prophet requires your time series data in a specific two-column format with ‘ds’ for dates and ‘y’ for values—any other structure will fail, so data preparation is your first critical step.

• The library automatically detects yearly, weekly, and daily seasonality patterns without manual configuration, but you’ll get better results by customizing changepoint sensitivity and adding domain-specific holidays.

• Cross-validation in Prophet uses a time series-aware approach that respects temporal ordering, unlike standard ML cross-validation—use the built-in cross_validation() function rather than scikit-learn’s tools.

Introduction to Prophet

Facebook Prophet is an open-source forecasting library designed specifically for business time series data. Unlike traditional statistical methods like ARIMA that require extensive parameter tuning and statistical expertise, Prophet takes an additive model approach that’s both powerful and accessible.

Prophet excels at handling real-world messiness: missing data points, outliers, and dramatic shifts in trends. It automatically detects multiple seasonality patterns (daily, weekly, yearly) and lets you incorporate known events like holidays or product launches. This makes it ideal for forecasting metrics like daily active users, revenue, server load, or inventory demand—scenarios where business context matters as much as statistical rigor.

The library is particularly valuable when you have at least several months of historical data with strong seasonal patterns and want interpretable results. If you’re forecasting sales that spike during holidays or website traffic that drops on weekends, Prophet handles these patterns out of the box.

Installation and Setup

Prophet has dependencies on Stan, a probabilistic programming language, which can make installation slightly tricky. The easiest approach uses conda, but pip works if you have a C++ compiler configured.

# Using conda (recommended)
conda install -c conda-forge prophet

# Using pip
pip install prophet

# If pip fails, you may need pystan first
pip install pystan
pip install prophet

Once installed, import the necessary libraries:

import pandas as pd
from prophet import Prophet
import matplotlib.pyplot as plt
from datetime import datetime, timedelta

# Suppress warnings for cleaner output
import logging
logging.getLogger('prophet').setLevel(logging.WARNING)

Preparing Your Time Series Data

Prophet is rigid about data format. You need a pandas DataFrame with exactly two columns: ds (datestamp) and y (the value you’re forecasting). The ds column must be datetime format, and y should be numeric.

Let’s create a sample dataset representing daily website visitors:

# Generate sample data
date_range = pd.date_range(start='2022-01-01', end='2023-12-31', freq='D')
np.random.seed(42)

# Create synthetic data with trend and seasonality
base_value = 1000
trend = np.linspace(0, 500, len(date_range))
weekly_seasonality = 200 * np.sin(2 * np.pi * np.arange(len(date_range)) / 7)
yearly_seasonality = 150 * np.sin(2 * np.pi * np.arange(len(date_range)) / 365)
noise = np.random.normal(0, 50, len(date_range))

visitors = base_value + trend + weekly_seasonality + yearly_seasonality + noise

# Create DataFrame in Prophet format
df = pd.DataFrame({
    'ds': date_range,
    'y': visitors
})

print(df.head())
print(f"\nData shape: {df.shape}")
print(f"Date range: {df['ds'].min()} to {df['ds'].max()}")

If you’re working with real data, you’ll typically need to rename columns:

# Example: Converting a typical dataset
raw_data = pd.read_csv('sales_data.csv')
prophet_data = raw_data.rename(columns={
    'date': 'ds',
    'daily_sales': 'y'
})

# Ensure ds is datetime
prophet_data['ds'] = pd.to_datetime(prophet_data['ds'])

# Remove any missing values
prophet_data = prophet_data.dropna()

Building Your First Forecast Model

Creating a basic Prophet model takes just a few lines. The model instantiation accepts various parameters, but defaults work well for initial exploration.

# Initialize and fit the model
model = Prophet()
model.fit(df)

# Create a dataframe for future predictions
# This extends 180 days beyond your training data
future = model.make_future_dataframe(periods=180)
print(f"Future dataframe shape: {future.shape}")

# Generate predictions
forecast = model.predict(future)

# Examine the forecast output
print(forecast[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].tail())

The forecast DataFrame contains several columns:

  • yhat: The predicted value
  • yhat_lower and yhat_upper: Uncertainty intervals (default 80%)
  • trend, weekly, yearly: Component breakdowns
  • Additional columns for any custom seasonality or holidays you’ve added

Visualizing Forecast Results

Prophet includes built-in plotting functions that create publication-ready visualizations:

# Plot the forecast
fig1 = model.plot(forecast)
plt.title('Website Visitors Forecast')
plt.xlabel('Date')
plt.ylabel('Number of Visitors')
plt.tight_layout()
plt.show()

# Plot forecast components
fig2 = model.plot_components(forecast)
plt.tight_layout()
plt.show()

The component plot is particularly valuable. It decomposes your forecast into:

  • Trend: The overall direction (increasing, decreasing, or flat)
  • Weekly seasonality: Patterns that repeat each week
  • Yearly seasonality: Annual patterns (if you have enough data)

This decomposition helps you understand what’s driving your forecast and communicate results to stakeholders.

Customizing Prophet Models

The default Prophet configuration is conservative. For better results, customize based on your domain knowledge.

Adding Holidays and Special Events

# Define holidays
holidays = pd.DataFrame({
    'holiday': 'black_friday',
    'ds': pd.to_datetime(['2022-11-25', '2023-11-24']),
    'lower_window': 0,
    'upper_window': 3,  # Effect lasts 3 days
})

# Create model with holidays
model = Prophet(holidays=holidays)
model.fit(df)

Adjusting Seasonality

# Disable automatic seasonality detection and add custom patterns
model = Prophet(
    yearly_seasonality=False,
    weekly_seasonality=True,
    daily_seasonality=False
)

# Add custom seasonality (e.g., monthly patterns)
model.add_seasonality(
    name='monthly',
    period=30.5,
    fourier_order=5
)

model.fit(df)

Tuning Changepoint Sensitivity

Prophet automatically detects trend changes. The changepoint_prior_scale parameter controls sensitivity:

# More flexible (detects more changepoints) - use for volatile data
model_flexible = Prophet(changepoint_prior_scale=0.5)

# More conservative (fewer changepoints) - use for stable data
model_conservative = Prophet(changepoint_prior_scale=0.001)

# Default is 0.05
model_default = Prophet()

Higher values make the model more flexible but risk overfitting. Lower values create smoother trends but may miss important changes.

Model Evaluation and Cross-Validation

Never deploy a forecast model without evaluating its accuracy. Prophet includes time series-aware cross-validation:

from prophet.diagnostics import cross_validation, performance_metrics

# Perform cross-validation
# initial: minimum training data
# period: spacing between cutoff dates
# horizon: forecast horizon to evaluate
df_cv = cross_validation(
    model,
    initial='365 days',
    period='90 days',
    horizon='180 days'
)

# Calculate performance metrics
df_metrics = performance_metrics(df_cv)
print(df_metrics[['horizon', 'mape', 'rmse', 'mae']].head())

# Get average metrics
print(f"\nAverage MAPE: {df_metrics['mape'].mean():.2%}")
print(f"Average RMSE: {df_metrics['rmse'].mean():.2f}")

Key metrics to monitor:

  • MAPE (Mean Absolute Percentage Error): Good for comparing across different scales
  • RMSE (Root Mean Squared Error): Penalizes large errors more heavily
  • MAE (Mean Absolute Error): More robust to outliers

For business applications, MAPE is often most interpretable. A MAPE under 10% is excellent, 10-20% is good, and above 20% suggests the model needs improvement.

Best Practices and Common Pitfalls

Use enough historical data: Prophet needs at least several months of data, preferably a full year to capture yearly seasonality. More data generally means better forecasts.

Handle outliers appropriately: Extreme outliers can distort your forecast. Either remove them or use Prophet’s built-in outlier handling by setting outlier_threshold parameters.

Don’t forecast too far ahead: Forecast accuracy degrades rapidly beyond your historical data’s time span. If you have one year of data, don’t forecast two years ahead.

Retrain regularly: As new data arrives, retrain your model. Time series patterns shift, and yesterday’s model may not capture today’s reality.

Prophet isn’t appropriate for every forecasting problem. It struggles with short time series (less than a few months), data without clear patterns, or scenarios requiring minute-by-minute predictions. For those cases, consider LSTM neural networks or classical statistical methods.

The library’s real strength lies in making sophisticated forecasting accessible. You can build a production-ready forecast in under 20 lines of code, then iteratively improve it by incorporating business knowledge through holidays, custom seasonality, and tuned parameters.

Liked this? There's more.

Every week: one practical technique, explained simply, with code you can use immediately.