MFLES
chronax.models.MFLES · inherits BaseForecaster
JAX MFLES implementation with StatsForecast-compatible default behavior. MFLES (Multi-Feature Locally Exponential Smoothing) combines multiple additive components — piecewise linear trend, Fourier seasonal patterns, and residual smoothing — fitted iteratively to successive residuals in a JIT-compiled loop. The goal is algorithmic parity with MFLES in StatsForecast while keeping the implementation JAX-friendly for speed at larger scales.
Attributes:
* uses_exog: True
* alias: str Model name identifier.
* conformal_params: ConformalIntervals | None Conformal prediction configuration.
* model_: dict Populated after fit(); contains fitted values and all components.
* multiplicative: bool Whether the last fit used multiplicative (log-space) mode.
* penalty: float | None R²-based trend dampening scalar (set during fit).
* trend_penalty: bool Whether trend damping is applied during predict().
* seasonality: jnp.ndarray | None Last seasonal period tail used for forecasting.
* trend: jnp.ndarray Two-element array [prev_end, curr_end] for slope extrapolation.
__init__(self, verbose: int = 1, robust: bool | None = None, alias: str = 'MFLES', conformal_params: ConformalIntervals | None = None) -> None
Initializes the MFLES model instance.
| Parameter | Type | Default | Description |
|---|---|---|---|
verbose |
int |
1 |
Verbosity level (currently reserved, unused). |
robust |
bool \| None |
None |
If True, uses Siegel repeated medians for trend fitting. If False, uses OLS. If None, auto-detects based on residual variability. |
alias |
str |
"MFLES" |
Model name identifier. |
conformal_params |
ConformalIntervals \| None |
None |
Conformal prediction configuration for generating prediction intervals. |
fit(self, y: jnp.ndarray, seasonal_period: int | list[int] | None = None, X: jnp.ndarray | None = None, fourier_order: int | None = None, ma: int | list[int] | None = None, alpha: float = 1.0, decay: float = -1, n_changepoints: float | int = 0.25, seasonal_lr: float = 0.9, rs_lr: float = 1.0, exogenous_lr: float = 1.0, exogenous_estimator=None, exogenous_params: dict = {}, linear_lr: float = 0.9, cov_threshold: float = 0.7, moving_medians: bool = False, max_rounds: int = 50, min_alpha: float = 0.05, max_alpha: float = 1.0, round_penalty: float = 0.0001, trend_penalty: bool = True, multiplicative: bool | None = None, changepoints: bool = True, smoother: bool = False, ses_mode: str = 'lite', seasonality_weights: bool = False, gradient_strategy: bool = False) -> Self
Fit the MFLES model to a time series.
Runs the JIT-compiled iterative fitting loop that alternately updates seasonal, trend, residual-smoothing, and exogenous components until convergence or max_rounds is reached.
| Parameter | Type | Default | Description |
|---|---|---|---|
y |
jnp.ndarray |
- | Input time series of shape (n,). |
seasonal_period |
int \| list[int] \| None |
None |
Seasonal period(s) for Fourier features. Pass a list for multiple seasonalities. None disables seasonality. |
X |
jnp.ndarray \| None |
None |
Exogenous design matrix of shape (n, p). |
fourier_order |
int \| None |
None |
Fixed Fourier order for all periods. None uses the auto-heuristic (5 / 10 / 15 based on period length). |
ma |
int \| list[int] \| None |
None |
Moving-average window(s) for residual smoothing cadence. None defaults to [1]. |
alpha |
float |
1.0 |
LASSO regularization strength for changepoint trend. |
decay |
float |
-1 |
Unused legacy parameter (kept for API compatibility). |
n_changepoints |
float \| int |
0.25 |
Number of changepoint knots. A float < 1 is treated as a fraction of series length (e.g. 0.25 = 25% of n). An int specifies knots directly. None or 0 disables changepoints. |
seasonal_lr |
float |
0.9 |
Learning rate multiplier applied to seasonal updates. |
rs_lr |
float |
1.0 |
Learning rate multiplier for residual-smoothing updates. |
exogenous_lr |
float |
1.0 |
Learning rate multiplier for exogenous updates. |
exogenous_estimator |
- | None |
Unused legacy parameter. |
exogenous_params |
dict |
{} |
Unused legacy parameter. |
linear_lr |
float |
0.9 |
Learning rate multiplier for trend updates. |
cov_threshold |
float |
0.7 |
CoV proxy threshold for auto robust-mode detection. Set to -1 to effectively disable. |
moving_medians |
bool |
False |
If True, initialises fitted values with period-wise medians instead of zeros. |
max_rounds |
int |
50 |
Maximum number of fitting iterations. |
min_alpha |
float |
0.05 |
Minimum SES alpha in the ensemble grid. |
max_alpha |
float |
1.0 |
Maximum SES alpha in the ensemble grid. |
round_penalty |
float |
0.0001 |
Improvement threshold fraction required before accepting a residual-smoothing update. |
trend_penalty |
bool |
True |
If True, dampens trend slope by the R-squared penalty computed on the first trend iteration. |
multiplicative |
bool \| None |
None |
If True, fits in log-space (multiplicative seasonality). If None, auto-detected: True when seasonal_period is set and all values are positive. |
changepoints |
bool |
True |
If True, enables piecewise linear trend via LASSO. |
smoother |
bool |
False |
Used only when ses_mode="adaptive": True selects SES ensemble, False selects rolling mean. |
ses_mode |
str |
"lite" |
Residual smoothing strategy. One of "off" (no residual smoothing), "lite" (rolling mean, StatsForecast default), "full" (SES ensemble), or "adaptive" (controlled by the smoother flag). |
seasonality_weights |
bool |
False |
If True, applies recency-weighted OLS for Fourier seasonal fitting. Auto-enabled for multiplicative single-period series. |
gradient_strategy |
bool |
False |
Legacy flag (currently unused). |
Returns: Self (the fitted forecaster; sets self.model_).
predict(self, h: int, X: jnp.ndarray | None = None, level: list[int | float] | None = None) -> dict
Generate h-step ahead forecasts from the fitted model.
Extrapolates the stored trend tail by the fitted slope (optionally damped by the R² penalty), tiles the seasonal tail, and adds any exogenous contribution. Optionally computes conformal prediction intervals.
| Parameter | Type | Default | Description |
|---|---|---|---|
h |
int |
- | Forecast horizon (number of steps ahead). |
X |
jnp.ndarray \| None |
None |
Future exogenous matrix of shape (h, p). Required only if the model was fitted with exogenous variables. |
level |
list[int \| float] \| None |
None |
Confidence levels (0-100) for conformal prediction intervals, e.g. [80, 95]. Requires conformal_params to be set. |
Returns: dict
Dictionary containing:
* mean: Point forecasts of shape (h,).
* lo-L: Lower bound of the prediction interval for level L (if level is provided).
* hi-L: Upper bound of the prediction interval for level L (if level is provided).
forecast(self, y: jnp.ndarray, h: int, X: jnp.ndarray | None = None, X_future: jnp.ndarray | None = None, level: list[int | float] | None = None, seasonal_period: int | list[int] | None = None, **fit_kwargs) -> dict
Stateless fit+predict in one call (convenience wrapper).
Creates a fresh model copy, fits it on y, and immediately generates forecasts. Does not store any state on self.
| Parameter | Type | Default | Description |
|---|---|---|---|
y |
jnp.ndarray |
- | Input time series of shape (n,). |
h |
int |
- | Forecast horizon. |
X |
jnp.ndarray \| None |
None |
In-sample exogenous matrix of shape (n, p). |
X_future |
jnp.ndarray \| None |
None |
Future exogenous matrix of shape (h, p). |
level |
list[int \| float] \| None |
None |
Confidence levels for conformal intervals. |
seasonal_period |
int \| list[int] \| None |
None |
Seasonal period(s) passed to fit. |
**fit_kwargs |
- | - | Any additional keyword arguments forwarded to fit(). |
Returns: dict (Same output as predict() -- "mean" and optional interval keys.)
optimize(self, y: jnp.ndarray, seasonal_period: int | list[int] | None, n_steps: int, test_size: int, step_size: int = 1, metric: str = 'smape', X: jnp.ndarray | None = None, params: list[dict] | None = None) -> dict
Auto-tune MFLES hyperparameters via rolling cross-validation.
Evaluates a grid of candidate configurations on rolling validation windows and returns the configuration with the lowest average error metric.
| Parameter | Type | Default | Description |
|---|---|---|---|
y |
jnp.ndarray |
- | Full time series used for cross-validation. |
seasonal_period |
int \| list[int] \| None |
- | Seasonal period(s) passed to fit() in each fold. Also drives the default candidate grid when params is None. |
n_steps |
int |
- | Number of rolling validation windows to evaluate. |
test_size |
int |
- | Number of observations held out as the test horizon in each window. |
step_size |
int |
1 |
Step (in observations) between successive validation windows. |
metric |
str |
"smape" |
Error metric to minimise. One of "mse", "mae", "mape", "smape". |
X |
jnp.ndarray \| None |
None |
Exogenous matrix of shape (n, p) aligned with y. Sliced appropriately for each fold. |
params |
list[dict] \| None |
None |
Explicit list of fit() kwarg dicts to evaluate. If None, a default grid is constructed based on seasonal_period. |
Returns: dict
The best-performing hyperparameter dictionary (suitable as **kwargs to fit()).