Forecasting at Scale,
Powered by Rust

High-performance time series forecasting with Prophet-like capabilities.
Built in Rust for maximum speed, with a familiar Python API.

Python 3.11+ Rust-powered

Why Farseer?

🚀

Blazing Fast

Rust-powered performance with automatic multithreading. Get forecasts in seconds, 5-10x faster than Prophet.

🎯

Accurate & Robust

Bayesian approach with uncertainty intervals. Handles missing data, outliers, and trend shifts automatically.

⚖️

Weighted Observations

Native support for observation weights. Emphasize recent data or downweight outliers with ease.

📊

Polars & Pandas

Works with both Polars (recommended, 5-10x faster) and Pandas DataFrames for backward compatibility.

🔧

Fully Tunable

Multiple trend types, custom seasonality, holiday effects, and regressors. Add your domain knowledge.

🔄

Prophet Compatible

Nearly identical API to Prophet. Migrate your existing code with minimal changes.

📅

Conditional Seasonality

Apply seasonal patterns only when conditions are met (e.g., weekday vs weekend patterns).

🎄

Flexible Holidays

Independent holiday priors with customizable scales. Different effects for different events.

📈

Smart Regressors

Auto-detects binary vs continuous regressors. Standardizes appropriately for optimal results.

📏

Floor & Cap

Logistic growth with both upper (cap) and lower (floor) bounds for saturating forecasts.

💾

Model Serialization

Save and load trained models as JSON for deployment and reproducibility.

Parallel Optimization

Automatically uses all CPU cores for faster model fitting. Scales with your hardware.

Farseer vs Prophet

Feature Farseer Prophet
Performance Rust-powered, 5-10x faster Python/Stan
Multithreading Automatic parallel optimization Single-threaded by default
Weighted Data Native support Not directly supported
DataFrames Polars + Pandas Pandas only
Conditional Seasonality Fully supported Fully supported
Floor Parameter Full support (logistic growth) Full support
Regressor Standardization Auto-detects binary/continuous Manual configuration
Holiday Priors Independent per-holiday scales Independent per-holiday scales
Deployment Minimal dependencies Requires Stan, PyStan
API Scikit-learn-like, Prophet-compatible Scikit-learn-like

Quick Start

Installation

# From PyPI
pip install farseer

# Development install from source
git clone https://github.com/ryanbieber/seer
cd seer
export PYO3_USE_ABI3_FORWARD_COMPATIBILITY=1  # For Python 3.13+
maturin develop --release

Basic Usage (Polars - Recommended)

from farseer import Farseer
import polars as pl
from datetime import datetime

# Create data
df = pl.DataFrame({
    'ds': pl.date_range(
        datetime(2020, 1, 1),
        periods=100,
        interval='1d',
        eager=True
    ),
    'y': range(100)
})

# Fit and forecast
m = Farseer()
m.fit(df)
future = m.make_future_dataframe(periods=30)
forecast = m.predict(future)

print(forecast.select(['ds', 'yhat', 'yhat_lower', 'yhat_upper']).tail())

Prophet-Compatible (Pandas)

from farseer import Farseer
import pandas as pd

# Create data
df = pd.DataFrame({
    'ds': pd.date_range('2020-01-01', periods=100),
    'y': range(100)
})

# Fit and forecast - same API!
m = Farseer()
m.fit(df)
future = m.make_future_dataframe(periods=30)
forecast = m.predict(future)

print(forecast[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].tail())

Examples

🎯 Weighted Observations

Give more importance to recent or reliable data

import polars as pl
import numpy as np
from farseer import Farseer

df = pl.DataFrame({
    'ds': pl.date_range(...),
    'y': np.random.randn(100).cumsum() + 50,
    'weight': [2.0 if i < 50 else 1.0 for i in range(100)]
})

# Weights automatically detected!
m = Farseer()
m.fit(df)
Learn more →

� Conditional Seasonality

Different patterns for different conditions

from farseer import Farseer

m = Farseer()

# Add conditional seasonality
m.add_seasonality(
    name='weekly_on_weekday',
    period=7,
    fourier_order=3,
    condition_name='is_weekday'
)

# Add condition column
df['is_weekday'] = (df['ds'].dt.weekday < 5)
m.fit(df)
Learn more →

�📈 Custom Regressors

Add additional variables to improve forecasts

from farseer import Farseer

m = Farseer()

# Auto-detects binary vs continuous
m.add_regressor('temperature', standardize='auto')
m.add_regressor('is_weekend', standardize='auto')
m.add_regressor('promo', prior_scale=5.0)

m.fit(train_df)
forecast = m.predict(test_df)
Learn more →

� Floor & Cap

Saturating growth with upper and lower bounds

from farseer import Farseer

# Logistic growth with floor
m = Farseer(growth='logistic')

df['floor'] = 1.5  # Minimum value
df['cap'] = 10.0   # Maximum value
m.fit(df)

future['floor'] = 1.5
future['cap'] = 10.0
forecast = m.predict(future)
Learn more →

�🔄 Manual Changepoints

Specify known trend changes in your data

from farseer import Farseer

# Specify exact changepoint dates
changepoints = ['2021-01-01', '2022-01-01']

m = Farseer(
    changepoints=changepoints,
    yearly_seasonality=True
)

m.fit(df)
forecast = m.predict(future)
Learn more →

🎄 Holiday Effects

Model special events with independent priors

from farseer import Farseer

m = Farseer()

# Different priors for different holidays
m.add_holidays(
    'christmas',
    dates=['2020-12-25', '2021-12-25'],
    prior_scale=20.0  # Strong effect
)
m.add_holidays(
    'minor_event',
    dates=['2020-03-17'],
    prior_scale=5.0   # Weak effect
)

m.fit(df)
Learn more →

Documentation

Ready to get started?

Start forecasting with the speed and reliability of Rust