Skip to main content

tsfm provides an easy interface to use TimeSeries Foundational Models.

Project description

UML Diagram - TSFM Codebase

Overview

TSFM is a unified time series forecasting framework that supports multiple frequencies (monthly, quarterly, etc.) with automatic frequency inference. It provides a consistent interface across classical statistical models and modern foundation models.

Key Features

  • Automatic Frequency Inference: No need to specify data frequency - it's detected from the DataFrame's DatetimeIndex
  • Multiple Model Support: Classical AR models and state-of-the-art foundation models (Moirai, Chronos)
  • Unified API: Consistent interface across all models with pred() method
  • Frequency-Aware Metrics: Horizons adapt to your data frequency (horizon=1 means next period, regardless of frequency)
  • Rich Outputs: Built-in metrics (RMSFE, MAE, ME) and visualization with prediction intervals
classDiagram
    %% Exceptions
    class TSFMError {
        <<Exception>>
    }
    
    class InvalidInputError {
        <<Exception>>
        +__init__(message: str)
    }
    
    Exception <|-- TSFMError
    TSFMError <|-- InvalidInputError
    
    %% Output Classes
    class ForecastOutput {
        -df_preds: DataFrame
        -meta: dict[str, Any]
        +rmsfe: DataFrame
        +mae: DataFrame
        +me: DataFrame
        +metric(name: Literal) DataFrame
        +summary(digits: int) None
        +plot_actual_vs_pred(horizon: int, ax: Axes, start: Timestamp, end: Timestamp, return_ax: bool) Axes
        -_agg_mean(s: Series, name: str, post: Callable) DataFrame
        -_summary(digits: int) str
    }
    
    %% Base Model (Abstract)
    class Model {
        <<Abstract>>
        +registry: ClassVar[dict]
        +name: property
        +__init_subclass__(cls, name: str, **kwargs)
        +build(name: str, **kwargs) Model
        +get_backbone() Any*
        +_pred(df: DataFrame, y: str, X: list, ctx_len: int, horizon: int, oos_start: str)* DataFrame
        +pred(df: DataFrame, y: str, X: list, ctx_len: int, horizon: int, oos_start: str) ForecastOutput
    }
    
    ABC <|-- Model
    
    %% ARModel
    class ARModel {
        +get_backbone() None
        +_pred(df: DataFrame, y: str, X: list, ctx_len: int, horizon: int, oos_start: str) DataFrame
    }
    
    Model <|-- ARModel : name="armodel"
    ARModel ..> InvalidInputError : raises
    ARModel ..> ForecastOutput : creates
    
    %% Moirai Model
    class Moirai {
        +get_backbone() MoiraiModule
        +get_model(ctx_len: int, horizon: int, n_covariates: int) MoiraiForecast
        +_pred(df: DataFrame, y: str, X: list, ctx_len: int, horizon: int, oos_start: str) DataFrame
    }
    
    Model <|-- Moirai : name="moirai"
    Moirai ..> ForecastOutput : creates
    
    %% Moirai2 Model
    class Moirai2 {
        +get_backbone() Moirai2Module
        +get_model(ctx_len: int, horizon: int, n_covariates: int) Moirai2Forecast
        +_pred(df: DataFrame, y: str, X: list, ctx_len: int, horizon: int, oos_start: str) DataFrame
    }
    
    Model <|-- Moirai2 : name="moirai2"
    Moirai2 ..> ForecastOutput : creates
    
    %% Chronos Model
    class Chronos {
        +get_backbone() BaseChronosPipeline
        +_pred(df: DataFrame, y: str, X: list, ctx_len: int, horizon: int, oos_start: str) DataFrame
    }
    
    Model <|-- Chronos : name="chronos"
    Chronos ..> ForecastOutput : creates
    
    %% Chronos2 Model
    class Chronos2 {
        +get_backbone() Chronos2Pipeline
        +_pred(df: DataFrame, y: str, X: list, ctx_len: int, horizon: int, oos_start: str) DataFrame
    }
    
    Model <|-- Chronos2 : name="chronos2"
    Chronos2 ..> ForecastOutput : creates
    
    %% Data Module Functions
    class DataModule {
        <<module: data.py>>
        +infer_freq(df: DataFrame) str
        +generator(n: int, phi: float, beta0: float, beta1: float, sigma: float, trend: float, season_period: int, season_ampl: float, seed: int) DataFrame
        +split_is_oos(df: DataFrame, test_frac: float) tuple[DataFrame, DataFrame]
    }
    
    %% ARModel Helper Functions
    class ARModelHelpers {
        <<module: armodel.py>>
        +create_lags(var: Series, lags: int) DataFrame
        +get_design_matrix(ys: Series, y_lags: int, horizon: int) tuple[Series, DataFrame]
        +fit(ys: Series, y_lags: int, horizon: int) RegressionResultsWrapper
        +pred(ys: Series, y_lags: int, horizon: int, oos_start: str) Series
        +build_oos_panel(ys: Series, y_lags: int, horizon: int, oos_start: str, freq: str) DataFrame
        -_to_period_end(idx: Index, freq: str) DatetimeIndex
    }
    
    ARModel ..> ARModelHelpers : uses
    
    %% Moirai Helper Functions
    class MoiraiHelpers {
        <<module: moirai.py>>
        +make_fc_df(forecasts: list, y_true_series: Series, freq: str) DataFrame
        +prepare_data(df: DataFrame, y: str, X: list, horizon: int, oos_start: str, freq: str) TestData
        +MODEL_ID: str
    }
    
    Moirai ..> MoiraiHelpers : uses
    
    %% Moirai2 Helper Functions
    class Moirai2Helpers {
        <<module: moirai2.py>>
        +make_fc_df(forecasts: list, y_true_series: Series, freq: str) DataFrame
        +prepare_data(df: DataFrame, y: str, X: list, horizon: int, oos_start: str, freq: str) TestData
        +MODEL_ID: str
    }
    
    Moirai2 ..> Moirai2Helpers : uses
    
    %% Chronos Helper Functions
    class ChronosHelpers {
        <<module: chronos.py>>
        +prepare_data(df: DataFrame, y: str, X: list, ctx_len: int, oos_start: str, freq: str) DataFrame
        +make_fc_df(forecasts: DataFrame, y_true: DataFrame, horizon: int, freq: str) DataFrame
        +BOLT_MODEL_ID: str
    }
    
    Chronos ..> ChronosHelpers : uses
    
    %% Chronos2 Helper Functions
    class Chronos2Helpers {
        <<module: chronos2.py>>
        +prepare_data(df: DataFrame, y: str, X: list, ctx_len: int, oos_start: str, freq: str) DataFrame
        +make_fc_df(forecasts: DataFrame, y_true: DataFrame, horizon: int, freq: str) DataFrame
        +MODEL_ID: str
    }
    
    Chronos2 ..> Chronos2Helpers : uses
    
    %% Output Helper Functions
    class OutputHelpers {
        <<module: outputs.py>>
        +get_horizon_groupby(df: DataFrame, freq: str) Index
    }
    
    ForecastOutput ..> OutputHelpers : uses
    
    %% Relationships with external libraries
    Model ..> ForecastOutput : returns
    Model ..> DataModule : uses infer_freq
    
    %% Package level
    class TSFMPackage {
        <<module: __init__.py>>
        +ARModel
        +Model
        +Moirai
        +Moirai2
        +Chronos
        +Chronos2
        +generator
    }
    
    TSFMPackage ..> ARModel : exports
    TSFMPackage ..> Model : exports
    TSFMPackage ..> Moirai : exports
    TSFMPackage ..> Moirai2 : exports
    TSFMPackage ..> Chronos : exports
    TSFMPackage ..> Chronos2 : exports
    TSFMPackage ..> DataModule : exports generator

    %% Notes
    note for Model "Registry pattern:\nSubclasses auto-register\nby name parameter\nAuto-infers frequency from data"
    
    note for ForecastOutput "Contains forecast results\nwith MultiIndex[cutoff, oos_date]\nFrequency-aware metrics\nand visualization"
    
    note for ARModel "Autoregressive model\nusing statsmodels OLS\nwith HAC standard errors\nNo covariate support"
    
    note for Moirai "Pretrained foundation model\nfrom Salesforce\nmodel: moirai-1.1-R-small\nSupports covariates"
    
    note for Moirai2 "Pretrained foundation model\nfrom Salesforce\nmodel: moirai-2.0-R-small\nuses uni2ts library\nSupports covariates"
    
    note for Chronos "Amazon Chronos-Bolt model\nchronos-bolt-small\nNo covariate support\nFrequency-aware"
    
    note for Chronos2 "Amazon Chronos 2.0 model\namazon/chronos-2\nSupports covariates\nFrequency-aware"
    
    note for DataModule "infer_freq:\nAuto-detects frequency\nfrom DatetimeIndex\nSupports M, Q, W, D, etc."

Class Descriptions

Core Classes

  1. Model (Abstract Base Class)

    • Registry pattern for dynamic model creation
    • All models inherit from this class
    • Defines interface: get_backbone() (abstract), _pred() (abstract), and pred() (concrete)
    • Registry allows building models by name: Model.build(name="armodel")
    • Automatically infers frequency from DataFrame and passes to ForecastOutput
  2. ARModel

    • Autoregressive time series model using classical statistical methods
    • Uses statsmodels for OLS regression with HAC standard errors
    • Does not support covariates (raises InvalidInputError)
    • Implements expanding window forecasting
    • Frequency-aware: automatically adapts to monthly, quarterly, or other frequencies
  3. Moirai

    • Wrapper for Salesforce's Moirai 1.1 foundation model (moirai-1.1-R-small)
    • Supports covariates via past_feat_dynamic_real
    • Uses GluonTS for data preparation
    • Generates 1,000 samples for probabilistic forecasting with quantile outputs
    • Frequency-aware with automatic normalization of timestamps
  4. Moirai2

    • Wrapper for Salesforce's Moirai 2.0 foundation model (moirai-2.0-R-small)
    • Supports covariates
    • Uses uni2ts library for inference
    • Quantile-based forecasting (median as point forecast)
    • Frequency-aware with automatic normalization of timestamps
  5. Chronos

    • Amazon Chronos-Bolt model (chronos-bolt-small)
    • Fast inference with quantile predictions
    • Does not support covariates
    • Frequency-aware with dynamic offset calculations
    • Returns quantile predictions (0.1 through 0.9)
  6. Chronos2

    • Amazon Chronos 2.0 model (amazon/chronos-2)
    • Supports covariates via DataFrame columns
    • Uses predict_df() interface for batch predictions
    • Frequency-aware with dynamic offset calculations
    • Returns quantile predictions and point forecasts

Data Structures

  1. ForecastOutput
    • Dataclass containing forecast results
    • MultiIndex DataFrame: (cutoff, oos_date)
    • Cached properties for metrics: RMSFE, MAE, ME
    • Frequency-aware metrics (stored in meta['freq'])
    • Methods for summary statistics and plotting
    • plot_actual_vs_pred(): Visualize forecasts with prediction intervals
    • Horizon parameter adapts to data frequency (horizon=1 = next period)

Exceptions

  1. TSFMError

    • Base exception for the package
  2. InvalidInputError

    • Raised when input validation fails (e.g., covariates not supported)

Utility Modules

  1. DataModule (data.py)

    • infer_freq(): Automatically detects frequency from DataFrame's DatetimeIndex
    • generator(): Simulates time series with AR, trend, seasonality
    • split_is_oos(): Splits data into train/test
  2. Helper Functions

    • ARModel helpers: lag creation, design matrix, OLS fitting, frequency-aware period alignment
    • Moirai helpers: forecast formatting with frequency parameter, GluonTS data preparation
    • Moirai2 helpers: forecast formatting with frequency parameter, uni2ts data preparation
    • Chronos helpers: rolling window data preparation, frequency-aware offset handling
    • Chronos2 helpers: DataFrame-based data preparation, frequency-aware offset handling
    • Output helpers: horizon grouping with frequency awareness

Architecture Patterns

  • Registry Pattern: Models self-register via __init_subclass__ enabling dynamic instantiation
  • Template Method: Base Model.pred() calls abstract _pred() and handles common logic
  • Dataclass: ForecastOutput with cached properties for lazy metric computation
  • Facade: Simple interface (pred()) over complex forecasting logic
  • Frequency Inference: Automatic detection and propagation of time series frequency throughout the pipeline

Frequency Support

All models automatically detect and adapt to your data's frequency:

  • Monthly (M): Standard month-end dates
  • Quarterly (Q): Quarter-end dates
  • Weekly (W): Week-end dates
  • Daily (D): Daily dates
  • Custom: Any pandas frequency string

The frequency is:

  1. Inferred from the DataFrame's DatetimeIndex using pd.infer_freq()
  2. Passed through the prediction pipeline
  3. Stored in ForecastOutput.meta['freq']
  4. Used for horizon calculations, metrics, and plotting

Usage Examples

Basic Usage - Monthly Data

from tsfm import Model, generator

# Generate monthly data (frequency auto-detected)
df = generator()

# Build and use any model
mdl = Model.build(name="moirai2")
yhs = mdl.pred(df, y="y", ctx_len=12, horizon=6, oos_start="2005-01-31")

# View metrics
yhs.summary()

# Plot forecasts (horizon=1 means next month)
yhs.plot_actual_vs_pred(horizon=1)

Quarterly Data

# Resample to quarterly (frequency auto-detected as 'Q')
df_quarterly = df.resample('Q').mean()

# Use the same interface - frequency is handled automatically
mdl = Model.build(name="chronos2")
yhs = mdl.pred(df_quarterly, y="y", ctx_len=4, horizon=2, oos_start="2005Q1")

# horizon=1 now means next quarter (not next 3 months!)
yhs.plot_actual_vs_pred(horizon=1)

Available Models

# Classical statistical model
mdl = Model.build(name="armodel")

# Foundation models from Salesforce
mdl = Model.build(name="moirai")   # Moirai 1.1
mdl = Model.build(name="moirai2")  # Moirai 2.0

# Foundation models from Amazon
mdl = Model.build(name="chronos")   # Chronos-Bolt
mdl = Model.build(name="chronos2")  # Chronos 2.0

Accessing Metrics

# Individual metrics
rmsfe = yhs.rmsfe  # Root Mean Squared Forecast Error by horizon
mae = yhs.mae      # Mean Absolute Error by horizon
me = yhs.me        # Mean Error by horizon

# Or use the metric method
yhs.metric("mae")

# Access raw predictions
yhs.df_preds  # MultiIndex DataFrame with y_true, y_pred, quantiles

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

tsfmecb-0.1.4.tar.gz (12.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

tsfmecb-0.1.4-py3-none-any.whl (18.3 kB view details)

Uploaded Python 3

File details

Details for the file tsfmecb-0.1.4.tar.gz.

File metadata

  • Download URL: tsfmecb-0.1.4.tar.gz
  • Upload date:
  • Size: 12.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.8.23

File hashes

Hashes for tsfmecb-0.1.4.tar.gz
Algorithm Hash digest
SHA256 ed3b360f8be414e1e388f385b80defe52bb104c8dde4aa8c29ac6547413fa95e
MD5 8ab198ec9145ab6716e552e778a5c400
BLAKE2b-256 530c8aed403366cda121b0c92a55f92b3265460da16e2973541b7beafde37cab

See more details on using hashes here.

File details

Details for the file tsfmecb-0.1.4-py3-none-any.whl.

File metadata

  • Download URL: tsfmecb-0.1.4-py3-none-any.whl
  • Upload date:
  • Size: 18.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.8.23

File hashes

Hashes for tsfmecb-0.1.4-py3-none-any.whl
Algorithm Hash digest
SHA256 341a705cdf0a8f4f7648f4ac82d3dffbcc442bc21dabd2e270336bce8afdb628
MD5 35ab1bf290c8a22ad32755be473da195
BLAKE2b-256 8729fbbde34b1ab2d40ed438b9faa921b005c03929e0b7fd98188f72ba81ef99

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page