@sipemu/anofox-forecast
v0.5.1
Published
Time series forecasting library - WebAssembly bindings for anofox-forecast
Downloads
881
Maintainers
Readme
@sipemu/anofox-forecast
WebAssembly bindings for anofox-forecast, a comprehensive time series forecasting library with 50+ models, automatic model selection, probabilistic postprocessing, and more.
Installation
npm install @sipemu/anofox-forecastUsage
Basic Example
import { TimeSeries, NaiveForecaster, ThetaForecaster } from '@sipemu/anofox-forecast';
// Create a time series from values
const data = [10, 12, 15, 14, 18, 20, 22, 25, 24, 28];
const ts = new TimeSeries(new Float64Array(data));
// Create and fit a forecaster
const model = new NaiveForecaster();
model.fit(ts);
// Generate predictions
const forecast = model.predict(5);
console.log('Predictions:', forecast.values);With Timestamps
import { TimeSeries } from '@sipemu/anofox-forecast';
const values = [10, 12, 15, 14, 18];
const timestamps = [
Date.parse('2024-01-01'),
Date.parse('2024-01-02'),
Date.parse('2024-01-03'),
Date.parse('2024-01-04'),
Date.parse('2024-01-05'),
];
const ts = TimeSeries.withTimestamps(
new Float64Array(values),
new Float64Array(timestamps)
);Available Forecasters
Baseline Models
| Forecaster | Description | Parameters |
|------------|-------------|------------|
| NaiveForecaster | Last observation repeated | - |
| MeanForecaster | Historical mean | - |
| SeasonalNaiveForecaster | Same season from previous cycle | period |
| RandomWalkDriftForecaster | Random walk with trend | - |
| SMAForecaster | Simple Moving Average | window |
| WindowAverageForecaster | Rolling window average | window_size |
| SeasonalWindowAverageForecaster | Seasonal window average | period, window |
Exponential Smoothing Models
| Forecaster | Description | Parameters |
|------------|-------------|------------|
| SESForecaster | Simple Exponential Smoothing | alpha |
| HoltForecaster | Holt Linear Trend (Double ES) | alpha, beta |
| HoltWintersForecaster | Triple Exponential Smoothing | alpha, beta, gamma, period |
| SeasonalESForecaster | Seasonal Exponential Smoothing | period |
| ETSForecaster | ETS state-space model | error, trend, seasonal, period |
| AutoETSForecaster | Automatic ETS selection | - |
Theta Models
| Forecaster | Description | Parameters |
|------------|-------------|------------|
| ThetaForecaster | Standard Theta method | - |
| OptimizedThetaForecaster | Optimized Theta | - |
| DynamicThetaForecaster | Dynamic coefficient updates | alpha |
| AutoThetaForecaster | Automatic Theta selection | - |
ARIMA Models
| Forecaster | Description | Parameters |
|------------|-------------|------------|
| ARIMAForecaster | ARIMA | p, d, q |
| SARIMAForecaster | Seasonal ARIMA | p, d, q, P, D, Q, period |
| AutoARIMAForecaster | Automatic ARIMA selection | - |
Intermittent Demand Models
| Forecaster | Description | Parameters |
|------------|-------------|------------|
| CrostonForecaster | Croston's method | - |
| TSBForecaster | Teunter-Syntetos-Babai | - |
| ADIDAForecaster | Aggregate-Disaggregate approach | - |
| IMAPAForecaster | Multiple Aggregation Prediction | - |
Advanced Models
| Forecaster | Description | Parameters |
|------------|-------------|------------|
| TBATSForecaster | TBATS (complex seasonality) | seasonal_periods[] |
| AutoTBATSForecaster | Automatic TBATS | seasonal_periods[] |
| MFLESForecaster | Multiple Frequency LOESS | seasonal_periods[] |
| MSTLForecasterWrapper | MSTL decomposition | seasonal_periods[] |
| GARCHForecaster | GARCH volatility model | p, q |
Auto Selection
| Forecaster | Description | Parameters |
|------------|-------------|------------|
| AutoForecaster | Best of ARIMA, ETS, Theta | - |
| AutoEnsembleForecaster | Ensemble of top-K models | - |
Prediction Intervals
Most models support prediction intervals:
import { NaiveForecaster } from '@sipemu/anofox-forecast';
const model = new NaiveForecaster();
model.fit(ts);
// Get forecast with 95% prediction intervals
const forecast = model.predictWithIntervals(5, 0.95);
console.log('Point predictions:', forecast.values);
console.log('Lower bound:', forecast.lower);
console.log('Upper bound:', forecast.upper);API Reference
TimeSeries
new TimeSeries(values: Float64Array)- Create from valuesTimeSeries.withTimestamps(values, timestamps)- Create with timestamps (ms since epoch)ts.length- Number of observationsts.values- Get values as arrayts.isEmpty()- Check if emptyts.hasMissingValues()- Check for NaN valuests.slice(start, end)- Get a slice of the series
Forecast
forecast.horizon- Number of predictionsforecast.values- Point predictionsforecast.lower- Lower prediction interval (if available)forecast.upper- Upper prediction interval (if available)forecast.hasLower()- Check if lower interval existsforecast.hasUpper()- Check if upper interval exists
ETS Model Specification
For ETSForecaster, use string codes:
- Error:
"A"(additive) or"M"(multiplicative) - Trend:
"N"(none),"A"(additive), or"Ad"(additive damped) - Seasonal:
"N"(none),"A"(additive), or"M"(multiplicative)
// ETS(A,A,M) - Additive error, Additive trend, Multiplicative seasonal
const ets = new ETSForecaster("A", "A", "M", 12);Standard ETS Notation
You can also use standard ETS notation (following FPP3 taxonomy):
// Create from notation string
const model = ETSForecaster.fromNotation("AAA", 12); // Holt-Winters additive
const model = ETSForecaster.fromNotation("MAM", 12); // Multiplicative Holt-Winters
const model = ETSForecaster.fromNotation("AAdM", 12); // Damped trend, multiplicative seasonalValid notation format: ErrorTrendSeasonal
- First letter: Error (A or M)
- Second letter(s): Trend (N, A, or Ad)
- Third letter: Seasonal (N, A, or M)
Model Validation
Some ETS combinations are unstable and will throw an error:
MAA- Multiplicative error + Additive trend + Additive seasonalMAdA- Multiplicative error + Damped trend + Additive seasonal
You can check validity before creating:
// Check if a specification is valid
ETSForecaster.isValidSpec("A", "A", "A"); // true
ETSForecaster.isValidSpec("M", "A", "M"); // true
ETSForecaster.isValidSpec("M", "A", "A"); // false (unstable)Probabilistic Postprocessing
Generate calibrated prediction intervals using conformal prediction, historical simulation, or normal approximation:
import { JsConformalPredictor, JsPointForecasts, JsPostProcessor } from '@sipemu/anofox-forecast';
// Conformal prediction intervals (distribution-free)
const predictor = new JsConformalPredictor(0.9); // 90% coverage
predictor.calibrate(forecasts, actuals);
const intervals = predictor.predictIntervals(newForecasts);
console.log('Lower:', intervals.lower);
console.log('Upper:', intervals.upper);
// Unified PostProcessor API
const processor = JsPostProcessor.conformal(0.95);
const trained = processor.train(forecasts, actuals);
const pi = processor.predictIntervals(trained, newForecasts);Available Methods
JsConformalPredictor— distribution-free intervals (split, cross-val, jackknife+)JsNormalPredictor— Gaussian error assumption baselineJsHistoricalSimulator— non-parametric empirical error distributionJsPostProcessor— unified API wrapping all methodsJsBacktestConfig/JsBacktestResult— rolling/expanding window backtesting
Calendar Annotations
Add holidays and named regressors for models that support exogenous variables:
import { CalendarAnnotations } from '@sipemu/anofox-forecast';
const calendar = new CalendarAnnotations();
calendar.addHoliday(Date.parse('2024-12-25'));
calendar.addRegressor('temperature', new Float64Array([20, 22, 25, 23]));
ts.setCalendar(calendar);
model.fit(ts); // ARIMA, MFLES, etc. will automatically use the regressorsBrowser Usage
<script type="module">
import init, { TimeSeries, ThetaForecaster } from './anofox_forecast_js.js';
async function main() {
await init();
const data = new Float64Array([10, 12, 15, 14, 18, 20, 22, 25]);
const ts = new TimeSeries(data);
const model = new ThetaForecaster();
model.fit(ts);
const forecast = model.predict(5);
console.log('Forecast:', forecast.values);
}
main();
</script>Node.js Usage
import { TimeSeries, AutoARIMAForecaster } from '@sipemu/anofox-forecast';
// Load your data
const data = [/* your time series data */];
const ts = new TimeSeries(new Float64Array(data));
// Forecast with AutoARIMA
const model = new AutoARIMAForecaster();
model.fit(ts);
const forecast = model.predict(10);Calendar Feature Engineering
import { FeatureGenerator, generateFutureTimestamps } from '@sipemu/anofox-forecast';
// Build a feature generator
const gen = new FeatureGenerator();
gen.fourier(7, 2); // weekly Fourier terms
gen.cyclical('month'); // sin/cos month encoding
gen.cyclical('day_of_week'); // sin/cos day-of-week
gen.binary('weekend'); // 0/1 weekend indicator
gen.binary('month_end'); // 0/1 month-end
gen.advanced('days_in_month'); // 28-31
// Generate features from timestamps (ms since epoch)
const features = gen.generate(timestamps); // { month_sin: [...], weekend: [...], ... }
const names = gen.featureNames();
// Generate future timestamps (calendar-aware)
const future = generateFutureTimestamps(lastTimestampMs, '1mo', 12); // monthly
const weekly = generateFutureTimestamps(lastTimestampMs, '1w', 4); // weekly
// Auto-infer from TimeSeries
const futureTs = ts.futureTimestamps(12);Bootstrap Prediction Intervals
import { JsBootstrapPredictor } from '@sipemu/anofox-forecast';
const bp = new JsBootstrapPredictor(0.95);
bp.nReplicates(1000);
bp.seed(42);
const result = bp.fit(fittedValues, actuals);
const intervals = bp.predictIntervals(result, pointForecast);
console.log(intervals.lower, intervals.upper);
// Multi-quantile forecasts
const quantiles = bp.predictQuantiles(result, pointForecast, [0.10, 0.25, 0.50, 0.75, 0.90]);Per-Step Conformal Prediction
// Per-horizon-step intervals (tighter at h=1, wider at h=12)
const perStep = predictor.fitPerStep(foldForecasts, foldActuals);
console.log(perStep.halfWidths); // different width per step
const intervals = perStep.predictIntervals(pointForecast);
// Multi-quantile conformal forecasts
const quantiles = predictor.predictQuantiles(result, pointForecast, [0.10, 0.50, 0.90]);Limitations
- The
parallelfeature from the Rust crate is not available in WASM - IDR (Isotonic Distributional Regression) and QRA are not yet exposed in WASM
- RegressionForecaster (11 regression backends) is Rust-only (not yet in WASM)
License
MIT
