Migrating from Prophet - Farseer

## Why Migrate?

Farseer offers significant advantages over Prophet while maintaining API compatibility:

- 5-10x faster - Rust-powered performance with automatic multithreading
- Weighted observations - Native support for data quality and recency weighting
- Polars support - Modern DataFrame library for even better performance
- Simpler deployment - Fewer dependencies, single binary distribution
- Same API - Nearly identical interface, minimal learning curve

## Quick Migration Guide

#### ❌ Before (Prophet)

    from prophet import Prophet
    import pandas as pd

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

    m = Prophet()
    m.fit(df)
    future = m.make_future_dataframe(periods=30)
    forecast = m.predict(future)

#### ✅ After (Farseer)

    from farseer import Farseer
    import pandas as pd

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

    m = Farseer()  # Just change the class name!
    m.fit(df)
    future = m.make_future_dataframe(periods=30)
    forecast = m.predict(future)

That's it! In most cases, you only need to change `Prophet` to `Farseer`.

## API Compatibility

Farseer maintains compatibility with Prophet's core API:

### ✅ Fully Compatible

- `fit(df)` - Train the model
- `predict(df)` - Make predictions
- `make_future_dataframe(periods)` - Generate future dates
- `add_regressor(name, ...)` - Add custom regressors
- `add_seasonality(name, period, fourier_order)` - Add custom seasonality
- `add_country_holidays(country)` - Add holiday effects
- Growth modes: `linear`, `logistic`, `flat`
- Seasonality modes: `additive`, `multiplicative`
- Changepoint detection and configuration

### ⚡ Enhanced Features

- Weighted observations - Add `weight` column to your DataFrame
- Polars DataFrames - Use Polars for 5-10x better performance
- Automatic multithreading - No configuration needed

## Common Migration Scenarios

### Scenario 1: Basic Time Series

#### Prophet

    from prophet import Prophet

    m = Prophet(
        yearly_seasonality=True,
        weekly_seasonality=False,
        daily_seasonality=False
    )
    m.fit(df)
    forecast = m.predict(future)

#### Farseer

    from farseer import Farseer

    m = Farseer(
        yearly_seasonality=True,
        weekly_seasonality=False,
        daily_seasonality=False
    )
    m.fit(df)
    forecast = m.predict(future)

### Scenario 2: With Regressors

#### Prophet

    from prophet import Prophet

    m = Prophet()
    m.add_regressor('temperature')
    m.add_regressor('is_weekend')
    m.fit(train_df)
    forecast = m.predict(test_df)

#### Farseer

    from farseer import Farseer

    m = Farseer()
    m.add_regressor('temperature')
    m.add_regressor('is_weekend')
    m.fit(train_df)
    forecast = m.predict(test_df)

### Scenario 3: With Holidays

#### Prophet

    from prophet import Prophet

    m = Prophet()
    m.add_country_holidays(country_name='US')
    m.fit(df)
    forecast = m.predict(future)

#### Farseer

    from farseer import Farseer

    m = Farseer()
    m.add_country_holidays(country_name='US')
    m.fit(df)
    forecast = m.predict(future)

### Scenario 4: Logistic Growth

#### Prophet

    from prophet import Prophet

    df['cap'] = 200  # Carrying capacity
    m = Prophet(growth='logistic')
    m.fit(df)

    future = m.make_future_dataframe(periods=30)
    future['cap'] = 200
    forecast = m.predict(future)

#### Farseer

    from farseer import Farseer

    df['cap'] = 200  # Carrying capacity
    m = Farseer(growth='logistic')
    m.fit(df)

    future = m.make_future_dataframe(periods=30)
    future['cap'] = 200
    forecast = m.predict(future)

## Performance Boost with Polars

For even better performance, migrate to Polars DataFrames:

#### With Pandas

    import pandas as pd
    from farseer import Farseer

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

    m = Farseer()
    m.fit(df)  # Works but slower

#### With Polars (5-10x faster!)

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

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

    m = Farseer()
    m.fit(df)  # Much faster! ⚡

## New Features in Farseer

### Weighted Observations

This feature is unique to Farseer and not available in Prophet:

    import polars as pl
    from farseer import Farseer

    # Add weights to emphasize recent data
    df = pl.DataFrame({
        'ds': dates,
        'y': values,
        'weight': [2.0 if i < 50 else 1.0 for i in range(100)]
    })

    # Weights are automatically detected!
    m = Farseer()
    m.fit(df)

### Automatic Multithreading

No configuration needed - Farseer automatically uses all available CPU cores:

    # Prophet: single-threaded by default
    from prophet import Prophet
    m = Prophet()
    m.fit(large_df)  # Slower

    # Farseer: automatic multithreading
    from farseer import Farseer
    m = Farseer()
    m.fit(large_df)  # Much faster with no extra code!

## Troubleshooting

### Import Errors

    # If you get import errors, ensure Farseer is installed
    pip install farseer

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

### Minor Differences

While Farseer aims for full Prophet compatibility, there may be minor numerical differences due to:

- Different optimization algorithms (both use L-BFGS but with different implementations)
- Floating point precision differences between Rust and Python
- Random number generation in uncertainty intervals

These differences are typically negligible and don't affect forecast quality.

## Need Help?

If you encounter issues migrating from Prophet to Farseer:

- Report an issue on GitHub
- Join the discussion
- Check out more examples