Models¶
Baselines¶
- class omnicast.NaiveForecaster[source]¶
Bases:
BaseForecasterRandom-walk forecast using the most recent observation.
Examples
>>> import pandas as pd >>> from omnicast import NaiveForecaster >>> y = pd.Series([10.0, 12.0, 11.0, 13.0, 15.0, 14.0]) >>> model = NaiveForecaster().fit(y) >>> model.predict(horizon=2).mean.round(2).tolist() [14.0, 14.0]
Notes
When to use this model¶ Best for
The floor baseline every other model must beat; no assumptions about the series beyond “tomorrow looks like today”
Avoid when
The series has a visible trend or seasonal cycle – it will systematically lag both
Handles trend
No
Handles seasonality
No
Extra dependencies
None
Min. observations
1
- fit_predict(y, horizon, **kwargs)¶
- class omnicast.SeasonalNaiveForecaster(seasonal_period)[source]¶
Bases:
BaseForecasterRepeat values from the latest seasonal cycle.
Examples
>>> import pandas as pd >>> from omnicast import SeasonalNaiveForecaster >>> y = pd.Series([10.0, 20.0, 15.0, 25.0, 11.0, 21.0, 16.0, 26.0]) >>> model = SeasonalNaiveForecaster(seasonal_period=4).fit(y) >>> model.predict(horizon=4).mean.round(2).tolist() [11.0, 21.0, 16.0, 26.0]
Notes
When to use this model¶ Best for
The baseline to beat whenever a series has real seasonal structure; captures the seasonal swing for free
Avoid when
The series has no repeating cycle, or a trend on top of the cycle that repeating last year’s values would miss
Handles trend
No
Handles seasonality
Yes (repeats the last full cycle)
Extra dependencies
None
Min. observations
seasonal_period + 1- Parameters:
seasonal_period (int)
- fit_predict(y, horizon, **kwargs)¶
- class omnicast.MeanForecaster[source]¶
Bases:
BaseForecasterForecast the historical mean.
Examples
>>> import pandas as pd >>> from omnicast import MeanForecaster >>> y = pd.Series([10.0, 12.0, 11.0, 13.0, 15.0, 14.0]) >>> model = MeanForecaster().fit(y) >>> model.predict(horizon=2).mean.round(2).tolist() [12.5, 12.5]
Notes
When to use this model¶ Best for
A stability sanity check – does the series have a signal worth modeling at all?
Avoid when
The series has any trend or seasonality; it should almost always lose to a trend-aware model on a proper backtest
Handles trend
No
Handles seasonality
No
Extra dependencies
None
Min. observations
1
- fit_predict(y, horizon, **kwargs)¶
- class omnicast.DriftForecaster[source]¶
Bases:
BaseForecasterRandom walk with drift between the first and last observations.
Examples
>>> import pandas as pd >>> from omnicast import DriftForecaster >>> y = pd.Series([10.0, 12.0, 11.0, 13.0, 15.0, 14.0]) >>> model = DriftForecaster().fit(y) >>> model.predict(horizon=2).mean.round(2).tolist() [14.8, 15.6]
Notes
When to use this model¶ Best for
A trending series with no seasonality; a much stronger baseline than
NaiveForecasterin that case, at the same costAvoid when
The series has seasonality a straight line can’t capture, or the trend is not roughly linear end-to-end
Handles trend
Yes (linear, extrapolated from the first and last observation)
Handles seasonality
No
Extra dependencies
None
Min. observations
2
- fit_predict(y, horizon, **kwargs)¶
Theta¶
- class omnicast.ThetaForecaster(seasonal_period=None)[source]¶
Bases:
BaseForecasterClassical Theta method (Assimakopoulos & Nikolopoulos, 2000).
Compatible Python reimplementation of R’s forecast::thetaf (Hyndman, package forecast, GPL-3) – not a call into R, and not yet verified against its numerical output; see CONTRIBUTING.md. It decomposes the series into two “theta lines”: the theta=0 line is the long-term linear trend, and the theta=2 line doubles local curvature around that trend. The theta=2 line is extrapolated with simple exponential smoothing, the theta=0 line is extrapolated linearly, and the two forecasts are averaged with equal weight, following Assimakopoulos & Nikolopoulos (2000), “The theta model: a decomposition approach to forecasting”, International Journal of Forecasting 16(4):521-530.
When seasonal_period is given, the series is deseasonalized first with a multiplicative classical decomposition (statsmodels.seasonal_decompose) and forecasts are reseasonalized afterwards; this requires strictly positive values and at least two full seasonal cycles.
Prediction intervals use the same residual-variance random-walk scaling (sqrt(sigma2 * h)) as NaiveForecaster, an approximation rather than the exact ETS(A,N,N) state-space interval that R’s implementation derives from the SES equivalence proven by Hyndman & Billah (2003), “Unmasking the Theta method”, International Journal of Forecasting 19(2):287-290.
Supported indexes: any index accepted by future_index (PeriodIndex, DatetimeIndex with a regular frequency, RangeIndex, or numeric Index). Minimum sample size: 4 observations, or 2 * seasonal_period when seasonal.
Examples
>>> import pandas as pd >>> from omnicast import ThetaForecaster >>> y = pd.Series([10.0, 12.0, 11.0, 13.0, 15.0, 14.0]) >>> model = ThetaForecaster().fit(y) >>> model.predict(horizon=2).mean.round(2).tolist() [14.05, 14.49]
Pass
seasonal_periodto deseasonalize first (multiplicative decomposition) and reseasonalize the forecast afterward; this requires strictly positive values and at least two full seasonal cycles, e.g.ThetaForecaster(seasonal_period=12)on two years of monthly data.Notes
When to use this model¶ Best for
A strong, fast default before reaching for a full state-space model; a good general-purpose replacement for the baselines
Avoid when
You need exact parity with R’s
forecast::thetafintervals, or a model that supports exogenous regressorsHandles trend
Yes (linear long-term trend line)
Handles seasonality
Yes, via
seasonal_period(multiplicative decomposition)Extra dependencies
None
Min. observations
4, or
2 * seasonal_periodwhen seasonal- Parameters:
seasonal_period (int | None)
- fit_predict(y, horizon, **kwargs)¶
Statistical (statsmodels-backed)¶
- class omnicast.ETSForecaster(trend='add', seasonal=None, seasonal_period=None, damped_trend=False)[source]¶
Bases:
BaseForecasterError-trend-seasonal state-space model with automatic component defaults.
Examples
>>> import pandas as pd >>> from omnicast import ETSForecaster >>> y = pd.Series([10.0, 12.0, 11.0, 13.0, 15.0, 14.0]) >>> model = ETSForecaster(trend="add").fit(y) >>> model.predict(horizon=2).mean.round(2).tolist() [15.6, 16.49]
Pass
seasonal="add"(or"mul") withseasonal_periodset to model a repeating cycle alongside the trend.Notes
When to use this model¶ Best for
Series with a known trend/seasonal shape where you want a full statistical fit (AIC/BIC, parameter confidence intervals) rather than an approximation
Avoid when
You want the trend/seasonal order searched for you (see
AutoARIMAForecaster) or need exogenous regressorsHandles trend
Yes, via
trend("add","mul", orNone)Handles seasonality
Yes, via
seasonal+seasonal_periodExtra dependencies
None (uses
statsmodels)Min. observations
Enough for
statsmodelsto estimate the requested components; at least2 * seasonal_periodwhen seasonal- Parameters:
- fit_predict(y, horizon, **kwargs)¶
- class omnicast.ARIMAForecaster(order=(1, 0, 0), seasonal_order=(0, 0, 0, 0), trend=None)[source]¶
Bases:
BaseForecasterARIMA/SARIMA model with optional exogenous regressors.
Examples
>>> import pandas as pd >>> from omnicast import ARIMAForecaster >>> y = pd.Series([10.0, 12.0, 11.0, 13.0, 15.0, 14.0]) >>> model = ARIMAForecaster(order=(1, 0, 0)).fit(y) >>> model.predict(horizon=2).mean.round(2).tolist() [14.76, 15.55]
Pass
seasonal_order=(P, D, Q, m)for SARIMA, and anXDataFrame (with matching index at bothfitandpredicttime) to include exogenous regressors.Notes
When to use this model¶ Best for
You already know (or want to fix) the ARIMA/SARIMA order, or need exogenous regressors – the only model in this package that supports them
Avoid when
You want the order searched automatically (see
AutoARIMAForecaster)Handles trend
Yes, via differencing (
d) and/ortrendHandles seasonality
Yes, via
seasonal_orderExtra dependencies
None (uses
statsmodels)Min. observations
Enough for
SARIMAXto estimate the requested order; roughlysum(order) + sum(seasonal_order[:3]) + 1at minimum- Parameters:
- fit_predict(y, horizon, **kwargs)¶
- class omnicast.AutoARIMAForecaster(seasonal_period=None, max_p=2, max_d=1, max_q=2, max_P=1, max_D=1, max_Q=1, information_criterion='aicc')[source]¶
Bases:
ARIMAForecasterSelect a non-seasonal or seasonal ARIMA by corrected AIC grid search.
Examples
>>> import pandas as pd >>> from omnicast import AutoARIMAForecaster >>> y = pd.Series([10.0, 12.0, 11.0, 13.0, 15.0, 14.0]) >>> model = AutoARIMAForecaster(max_p=1, max_d=1, max_q=0).fit(y) >>> model.order_ (0, 1, 0) >>> model.predict(horizon=2).mean.round(2).tolist() [14.0, 14.0]
Pass
seasonal_periodto also search(P, D, Q, m).Notes
When to use this model¶ Best for
You want ARIMA/SARIMA without hand-picking an order; the default first candidate
AutoForecastertriesAvoid when
Interactive use with a wide search space – cost scales as the product of every
max_*bound plus one, and it is often the slowest model in the package to fitHandles trend
Yes, searched via
max_dHandles seasonality
Yes, searched via
seasonal_period+max_P/max_D/max_QExtra dependencies
None (uses
statsmodels)Min. observations
Enough for the largest candidate order to be estimated; failed candidates are skipped rather than aborting the search
- Parameters:
- fit_predict(y, horizon, **kwargs)¶
- predict(horizon, X=None, level=(80, 95))¶
Neural (optional, torch)¶
- class omnicast.LSTMForecaster(lookback=12, hidden_size=32, num_layers=1, epochs=200, learning_rate=0.01, dropout=0.0, seed=0)[source]¶
Bases:
BaseForecasterAutoregressive LSTM forecaster wrapping torch.nn.LSTM.
Not an R port – this wraps a major Python deep-learning module the same way ETSForecaster/ARIMAForecaster wrap statsmodels. Requires the optional torch extra (pip install omnicast[torch]); raises a clear ImportError naming the missing package if torch is absent, and the module still imports cleanly without it.
The series is standardized (zero mean, unit variance, computed from training data only) and reframed as a sliding-window supervised regression: lookback consecutive points predict the next one. A single-layer (by default) LSTM is trained with Adam/MSE, full-batch, for epochs iterations – appropriate for the short series typical of this package, not for large-scale training. Multi-step forecasts are produced autoregressively: each predicted point is fed back in as the most recent observation of the next window.
Prediction intervals use the same residual-variance random-walk scaling (sqrt(sigma2 * h)) as NaiveForecaster and ThetaForecaster – an approximation, since the network has no closed-form predictive variance.
Not included in AutoForecaster’s default candidate list: it is optional-dependency and materially slower to backtest than the built-in statistical models. Pass it explicitly via AutoForecaster(models=[…]) to include it.
Minimum sample size: lookback + 2 observations. Training is not deterministic across torch versions/hardware even with a fixed seed; do not rely on exact reproducibility across environments.
Examples
>>> import pandas as pd >>> from omnicast import LSTMForecaster >>> y = pd.Series([10.0, 12.0, 11.0, 13.0, 15.0, 14.0, 16.0, 15.0]) >>> model = LSTMForecaster(lookback=2, hidden_size=4, epochs=30, seed=0).fit(y) >>> forecast = model.predict(horizon=2) # values vary slightly by platform
Notes
When to use this model¶ Best for
Exploring a nonlinear, learned alternative once the built-in statistical models have been tried; short series only
Avoid when
You need a fast default, exact reproducibility across machines, or don’t want the optional
torchdependency – never included inAutoForecaster’s default candidates for these reasonsHandles trend
Implicitly, via the sliding-window autoregression
Handles seasonality
Only if
lookbackspans a full cycle; no explicit seasonal componentExtra dependencies
torch(pip install omnicast[torch])Min. observations
lookback + 2- Parameters:
- fit_predict(y, horizon, **kwargs)¶