1 Installation
Install Farseer using pip or build from source:
From PyPI (Recommended)
pip install farseer
From Source
# Clone the repository
git clone https://github.com/ryanbieber/seer
cd seer
# For Python 3.13+, set compatibility flag
export PYO3_USE_ABI3_FORWARD_COMPATIBILITY=1
# Build and install with maturin
pip install maturin
maturin develop --release
Prerequisites
- Python 3.11 or higher
- CmdStan (automatically installed with cmdstanpy)
- Rust toolchain (only for building from source)
2 Your First Forecast
Create a simple forecast in just a few lines of code:
import polars as pl
from datetime import datetime
from farseer import Farseer
# Create sample data
df = pl.DataFrame({
'ds': pl.date_range(
datetime(2020, 1, 1),
periods=100,
interval='1d',
eager=True
),
'y': range(100) # Simple linear trend
})
# Create and fit model
m = Farseer()
m.fit(df)
# Make future predictions
future = m.make_future_dataframe(periods=30)
forecast = m.predict(future)
# View results
print(forecast.select(['ds', 'yhat', 'yhat_lower', 'yhat_upper']).tail())
Output:
shape: (5, 4)
┌─────────────────────┬────────────┬─────────────┬─────────────┐
│ ds ┆ yhat ┆ yhat_lower ┆ yhat_upper │
│ --- ┆ --- ┆ --- ┆ --- │
│ datetime[μs] ┆ f64 ┆ f64 ┆ f64 │
╞═════════════════════╪════════════╪═════════════╪═════════════╡
│ 2020-04-06 00:00:00 ┆ 126.234 ┆ 123.891 ┆ 128.577 │
│ 2020-04-07 00:00:00 ┆ 127.234 ┆ 124.891 ┆ 129.577 │
│ 2020-04-08 00:00:00 ┆ 128.234 ┆ 125.891 ┆ 130.577 │
│ 2020-04-09 00:00:00 ┆ 129.234 ┆ 126.891 ┆ 131.577 │
│ 2020-04-10 00:00:00 ┆ 130.234 ┆ 127.891 ┆ 132.577 │
└─────────────────────┴────────────┴─────────────┴─────────────┘
3 Understanding the Model
Farseer's forecast includes several components:
- yhat: The predicted value
- yhat_lower, yhat_upper: Uncertainty intervals (default 80%)
- trend: The overall trend component
- yearly: Yearly seasonal component (if enabled)
- weekly: Weekly seasonal component (if enabled)
- daily: Daily seasonal component (if enabled)
# View all components
print(forecast.select([
'ds', 'yhat', 'trend', 'yearly', 'weekly'
]).tail())
4 Customizing Your Model
Farseer provides many options to customize your forecast:
Seasonality Settings
m = Farseer(
yearly_seasonality=True, # Enable yearly patterns
weekly_seasonality=True, # Enable weekly patterns
daily_seasonality=False, # Disable daily patterns
seasonality_mode='additive' # or 'multiplicative'
)
Growth Settings
# Linear growth (default)
m = Farseer(growth='linear')
# Logistic growth with capacity
df['cap'] = 200 # Maximum capacity
m = Farseer(growth='logistic')
m.fit(df)
# Flat (no trend)
m = Farseer(growth='flat')
Changepoint Detection
m = Farseer(
n_changepoints=25, # Number of potential changepoints
changepoint_range=0.8, # Use first 80% of data
changepoint_prior_scale=0.05 # Flexibility (higher = more flexible)
)
Uncertainty Intervals
m = Farseer(interval_width=0.95) # 95% confidence intervals
m.fit(df)
forecast = m.predict(future)
5 Working with Real Data
Here's a complete example with realistic data including trend and seasonality:
import polars as pl
import numpy as np
from datetime import datetime
from farseer import Farseer
# Generate realistic data
np.random.seed(42)
n = 365 * 2 # 2 years of daily data
dates = pl.date_range(datetime(2020, 1, 1), periods=n, interval='1d', eager=True)
# Create components
t = np.arange(n)
trend = t * 0.5 + 100 # Linear growth
yearly = 10 * np.sin(2 * np.pi * t / 365.25) # Yearly seasonality
weekly = 5 * np.sin(2 * np.pi * t / 7) # Weekly seasonality
noise = np.random.normal(0, 2, n)
y = trend + yearly + weekly + noise
df = pl.DataFrame({'ds': dates, 'y': y})
# Split into train/test
train_size = int(n * 0.8)
train = df[:train_size]
test = df[train_size:]
# Fit model
m = Farseer(
yearly_seasonality=True,
weekly_seasonality=True,
daily_seasonality=False
)
m.fit(train)
# Forecast on test set
forecast = m.predict(test)
# Evaluate performance
from sklearn.metrics import mean_absolute_error, mean_squared_error
mae = mean_absolute_error(test['y'], forecast['yhat'][:len(test)])
rmse = np.sqrt(mean_squared_error(test['y'], forecast['yhat'][:len(test)]))
print(f"Test MAE: {mae:.2f}")
print(f"Test RMSE: {rmse:.2f}")
6 Next Steps
Now that you've got the basics, explore more advanced features:
- Weighted observations - Give more importance to recent data
- Custom regressors - Add additional variables
- Manual changepoints - Specify known trend changes
- Holiday effects - Model special events
- Performance optimization - Maximize speed
💡 Pro Tip
Use Polars DataFrames instead of Pandas for 5-10x better performance. Farseer is optimized for Polars but still supports Pandas for backward compatibility.