tsfm provides an easy interface to use TimeSeries Foundational Models.
Project description
Time Series Forecasting Models (TSFM)
A unified Python framework for time series forecasting that makes it easy to switch between classical statistical models and modern foundation models with just a single line of code.
Why TSFM?
Forecasting time series data shouldn't require rewriting your entire pipeline when you want to try a different model. TSFM provides:
- One Interface, Multiple Models: Switch from autoregressive models to state-of-the-art foundation models (Moirai, Chronos) by changing just the model name
- Works With Any Frequency: Automatically detects whether your data is monthly, quarterly, weekly, or daily - no manual configuration needed
- Batteries Included: Built-in metrics (RMSFE, MAE, ME), visualizations, and prediction intervals out of the box
- Production Ready: Consistent API across all models makes it easy to integrate into your workflow
Quick Start
Installation
Create a dedicated conda environment:
conda create -n tsfm python==3.12 ipykernel
conda activate tsfm
pip install tsfmecb
# Optional: register Jupyter kernel if you work within a notebook environment
python -m ipykernel install --user --name=tsfm --display-name "tsfm"
Your First Forecast
from tsfm import Model, generator
# Generate some sample data (or use your own DataFrame)
df = generator()
# Build a model - try "armodel", "moirai", "moirai2", "chronos", or "chronos2"
mdl = Model.build(name="moirai2")
# Generate forecasts
yhs = mdl.pred(df, y="y", ctx_len=12, horizon=6, oos_start="2005-01-31")
# View results
yhs.summary() # See metrics
yhs.plot_actual_vs_pred(horizon=1) # Visualize forecasts
That's it! The model automatically:
- Detects your data frequency
- Handles the forecasting
- Computes accuracy metrics
- Provides prediction intervals
Try Different Models
The beauty of TSFM is how easy it is to compare models:
# Classical autoregressive model
mdl_ar = Model.build(name="armodel")
yhs_ar = mdl_ar.pred(df, y="y", ctx_len=12, horizon=6, oos_start="2005-01-31")
# Salesforce Moirai foundation model
mdl_moirai = Model.build(name="moirai2")
yhs_moirai = mdl_moirai.pred(df, y="y", ctx_len=12, horizon=6, oos_start="2005-01-31")
# Amazon Chronos foundation model
mdl_chronos = Model.build(name="chronos2")
yhs_chronos = mdl_chronos.pred(df, y="y", ctx_len=12, horizon=6, oos_start="2005-01-31")
# Compare accuracy
print(f"AR RMSFE: {yhs_ar.rmsfe.values.mean():.3f}")
print(f"Moirai RMSFE: {yhs_moirai.rmsfe.values.mean():.3f}")
print(f"Chronos RMSFE: {yhs_chronos.rmsfe.values.mean():.3f}")
Works With Any Frequency
Have quarterly data? No problem:
# Resample to quarterly
df_quarterly = df.resample('Q').mean()
# Same code works - frequency is detected automatically
mdl = Model.build(name="moirai2")
yhs = mdl.pred(df_quarterly, y="y", ctx_len=4, horizon=2, oos_start="2005Q1")
# horizon=1 now means "next quarter" (not next month!)
yhs.plot_actual_vs_pred(horizon=1)
Supports monthly (M), quarterly (Q), weekly (W), daily (D), and any pandas frequency.
Available Models
| Model | Type | Covariates | Speed |
|---|---|---|---|
armodel |
Classical AR | ❌ | ⚡⚡⚡ |
moirai |
Foundation (Salesforce 1.1) | ✅ | ⚡⚡ |
moirai2 |
Foundation (Salesforce 2.0) | ✅ | ⚡⚡ |
chronos |
Foundation (Amazon Bolt) | ❌ | ⚡⚡ |
chronos2 |
Foundation (Amazon 2.0) | ✅ | ⚡⚡ |
What You Get
Every forecast returns a ForecastOutput object with:
- Predictions: Full DataFrame with actuals vs predictions by horizon and quantile
- Metrics: RMSFE, MAE, ME computed automatically
- Visualization: Built-in plotting with prediction intervals
- Uncertainty: Quantile forecasts (10th, 50th, 90th percentiles, etc.)
# Access predictions
yhs.df_preds # MultiIndex DataFrame
# Get metrics by horizon
yhs.rmsfe # Root Mean Squared Forecast Error
yhs.mae # Mean Absolute Error
yhs.me # Mean Error
# Quick summary
yhs.summary()
# Plot with uncertainty bands
yhs.plot_actual_vs_pred(horizon=1)
Learn More
Check out the tutorial notebook for:
- Data format requirements
- Model selection guidance
- Uncertainty quantification
- Troubleshooting tips
- Advanced usage examples
Technical Documentation
Architecture 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
UML Diagram
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
-
Model (Abstract Base Class)
- Registry pattern for dynamic model creation
- All models inherit from this class
- Defines interface:
get_backbone()(abstract),_pred()(abstract), andpred()(concrete) - Registry allows building models by name:
Model.build(name="armodel") - Automatically infers frequency from DataFrame and passes to ForecastOutput
-
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
-
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
-
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
-
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)
-
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
- 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
-
TSFMError
- Base exception for the package
-
InvalidInputError
- Raised when input validation fails (e.g., covariates not supported)
Utility Modules
-
DataModule (data.py)
infer_freq(): Automatically detects frequency from DataFrame's DatetimeIndexgenerator(): Simulates time series with AR, trend, seasonalitysplit_is_oos(): Splits data into train/test
-
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:
ForecastOutputwith 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:
- Inferred from the DataFrame's DatetimeIndex using
pd.infer_freq() - Passed through the prediction pipeline
- Stored in
ForecastOutput.meta['freq'] - Used for horizon calculations, metrics, and plotting
Detailed API Usage
Monthly Data Example
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 Example
# 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)
Model Selection
# 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 and Predictions
# 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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file tsfmecb-1.0.5.tar.gz.
File metadata
- Download URL: tsfmecb-1.0.5.tar.gz
- Upload date:
- Size: 13.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.8.23
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0e8886d3798032f67ce6ec025ffb8cc09ea01ab277cfede8abb5b59a2744bf96
|
|
| MD5 |
03093e6011241e03425a838c64e9e2bb
|
|
| BLAKE2b-256 |
c8cd9c00e66fddf864a515cdffb90a581d1df5db73bbcb5ceccd76758fc9892b
|
File details
Details for the file tsfmecb-1.0.5-py3-none-any.whl.
File metadata
- Download URL: tsfmecb-1.0.5-py3-none-any.whl
- Upload date:
- Size: 19.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.8.23
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
099c70fd42bb2e99427089a51ae12a3cac3b33be3b8393b7e859f89227926462
|
|
| MD5 |
7a26bedb7936605cc16a6cc6f4167b3a
|
|
| BLAKE2b-256 |
6316f8cff1a5de30854eb23dc47c2b69f4a67fa84cd3fe3a44f3732503d416b6
|