@sipemu/anofox-forecast 0.4.4 → 0.4.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +179 -4
- package/anofox_forecast_js.d.ts +1769 -55
- package/anofox_forecast_js.js +4276 -392
- package/anofox_forecast_js_bg.wasm +0 -0
- package/anofox_forecast_js_bg.wasm.d.ts +256 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @sipemu/anofox-forecast
|
|
2
2
|
|
|
3
|
-
WebAssembly bindings for [anofox-forecast](https://crates.io/crates/anofox-forecast), a comprehensive time series forecasting library.
|
|
3
|
+
WebAssembly bindings for [anofox-forecast](https://crates.io/crates/anofox-forecast), a comprehensive time series forecasting library with 40+ models, automatic model selection, probabilistic postprocessing, and more.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -109,9 +109,27 @@ const ts = TimeSeries.withTimestamps(
|
|
|
109
109
|
| `MSTLForecasterWrapper` | MSTL decomposition | `seasonal_periods[]` |
|
|
110
110
|
| `GARCHForecaster` | GARCH volatility model | `p`, `q` |
|
|
111
111
|
|
|
112
|
+
### Auto Selection
|
|
113
|
+
|
|
114
|
+
| Forecaster | Description | Parameters |
|
|
115
|
+
|------------|-------------|------------|
|
|
116
|
+
| `AutoForecaster` | Best of ARIMA, ETS, Theta | - |
|
|
117
|
+
| `AutoEnsembleForecaster` | Ensemble of top-K models | - |
|
|
118
|
+
|
|
119
|
+
### Orchestration
|
|
120
|
+
|
|
121
|
+
| Type | Description |
|
|
122
|
+
|------|-------------|
|
|
123
|
+
| `JsDataProfile` | Automated data profiling (stationarity, trend, quality) |
|
|
124
|
+
| `JsPipelineBuilder` | Declarative pipeline construction |
|
|
125
|
+
| `JsPipelineResult` | Pipeline result with forecast and diagnostics |
|
|
126
|
+
| `JsPipelineReport` | Structured multi-section report |
|
|
127
|
+
| `selectModels()` | Model recommendation from data profile |
|
|
128
|
+
| `explainResult()` | Human-readable result explanation |
|
|
129
|
+
|
|
112
130
|
## Prediction Intervals
|
|
113
131
|
|
|
114
|
-
|
|
132
|
+
Most models support prediction intervals:
|
|
115
133
|
|
|
116
134
|
```javascript
|
|
117
135
|
import { NaiveForecaster } from '@sipemu/anofox-forecast';
|
|
@@ -191,6 +209,163 @@ ETSForecaster.isValidSpec("M", "A", "M"); // true
|
|
|
191
209
|
ETSForecaster.isValidSpec("M", "A", "A"); // false (unstable)
|
|
192
210
|
```
|
|
193
211
|
|
|
212
|
+
## Probabilistic Postprocessing
|
|
213
|
+
|
|
214
|
+
Generate calibrated prediction intervals using conformal prediction, historical simulation, or normal approximation:
|
|
215
|
+
|
|
216
|
+
```javascript
|
|
217
|
+
import { JsConformalPredictor, JsPointForecasts, JsPostProcessor } from '@sipemu/anofox-forecast';
|
|
218
|
+
|
|
219
|
+
// Conformal prediction intervals (distribution-free)
|
|
220
|
+
const predictor = new JsConformalPredictor(0.9); // 90% coverage
|
|
221
|
+
predictor.calibrate(forecasts, actuals);
|
|
222
|
+
const intervals = predictor.predictIntervals(newForecasts);
|
|
223
|
+
console.log('Lower:', intervals.lower);
|
|
224
|
+
console.log('Upper:', intervals.upper);
|
|
225
|
+
|
|
226
|
+
// Unified PostProcessor API
|
|
227
|
+
const processor = JsPostProcessor.conformal(0.95);
|
|
228
|
+
const trained = processor.train(forecasts, actuals);
|
|
229
|
+
const pi = processor.predictIntervals(trained, newForecasts);
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### Available Methods
|
|
233
|
+
- `JsConformalPredictor` — distribution-free intervals (split, cross-val, jackknife+)
|
|
234
|
+
- `JsNormalPredictor` — Gaussian error assumption baseline
|
|
235
|
+
- `JsHistoricalSimulator` — non-parametric empirical error distribution
|
|
236
|
+
- `JsPostProcessor` — unified API wrapping all methods
|
|
237
|
+
- `JsBacktestConfig` / `JsBacktestResult` — rolling/expanding window backtesting
|
|
238
|
+
|
|
239
|
+
## Orchestration / Agent Forecasting
|
|
240
|
+
|
|
241
|
+
Build autonomous forecasting pipelines with data profiling, multi-metric model selection, preprocessing, ensemble construction, and structured reporting:
|
|
242
|
+
|
|
243
|
+
### Data Profiling
|
|
244
|
+
|
|
245
|
+
```javascript
|
|
246
|
+
import { JsDataProfile } from '@sipemu/anofox-forecast';
|
|
247
|
+
|
|
248
|
+
// Profile a time series
|
|
249
|
+
const profile = JsDataProfile.fromSeries(ts);
|
|
250
|
+
console.log('Observations:', profile.nObservations);
|
|
251
|
+
console.log('Trend:', profile.trendDirection); // "Rising", "Falling", "Flat"
|
|
252
|
+
console.log('Stationary?', profile.isStationary);
|
|
253
|
+
console.log('Intermittent?', profile.isIntermittent);
|
|
254
|
+
console.log('Quality:', profile.qualityScore); // 0.0 to 1.0
|
|
255
|
+
|
|
256
|
+
// Full profile as JSON
|
|
257
|
+
const json = profile.toJSON();
|
|
258
|
+
|
|
259
|
+
// Profile raw values (no timestamps needed)
|
|
260
|
+
const profile2 = JsDataProfile.fromValues(new Float64Array([1, 2, 3, 4, 5]));
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
### Model Selection
|
|
264
|
+
|
|
265
|
+
```javascript
|
|
266
|
+
import { JsDataProfile, selectModels } from '@sipemu/anofox-forecast';
|
|
267
|
+
|
|
268
|
+
const profile = JsDataProfile.fromSeries(ts);
|
|
269
|
+
|
|
270
|
+
// Get model recommendations based on data characteristics
|
|
271
|
+
const result = selectModels(profile);
|
|
272
|
+
console.log('Recommended:', result.recommended); // ["ARIMA", "ETS", "Naive", "SES"]
|
|
273
|
+
console.log('Reasoning:', result.reasoning); // ["High autocorrelation...", ...]
|
|
274
|
+
|
|
275
|
+
// Filter to available models
|
|
276
|
+
const filtered = selectModels(profile, ["Naive", "SES", "ARIMA"]);
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### Pipeline Builder
|
|
280
|
+
|
|
281
|
+
```javascript
|
|
282
|
+
import { JsPipelineBuilder } from '@sipemu/anofox-forecast';
|
|
283
|
+
|
|
284
|
+
// Build and execute a forecasting pipeline
|
|
285
|
+
const result = new JsPipelineBuilder()
|
|
286
|
+
.profile() // enable data profiling
|
|
287
|
+
.preprocess('auto') // auto Box-Cox + outlier treatment
|
|
288
|
+
.metric('auto') // data-aware metric selection
|
|
289
|
+
.ensemble('auto') // ensemble if MCS includes > 1 model
|
|
290
|
+
.addModel('Naive')
|
|
291
|
+
.addModel('SES')
|
|
292
|
+
.addModel('SMA')
|
|
293
|
+
.withFallback() // Naive → SMA fallback chain
|
|
294
|
+
.nonNegative() // clamp forecasts >= 0
|
|
295
|
+
.execute(ts, 12); // 12-step forecast
|
|
296
|
+
|
|
297
|
+
console.log('Model:', result.modelName);
|
|
298
|
+
console.log('Forecast:', result.forecast.values);
|
|
299
|
+
console.log('Decision log:', result.decisionLog);
|
|
300
|
+
|
|
301
|
+
// Access diagnostics
|
|
302
|
+
const profile = result.profile; // JsDataProfile or undefined
|
|
303
|
+
const mcs = result.modelConfidenceSet; // { included, pValue, singleWinner }
|
|
304
|
+
const scores = result.metricScores; // [{ model, score, components }]
|
|
305
|
+
const weights = result.ensembleWeights; // [{ model, weight }] or undefined
|
|
306
|
+
const preprocess = result.preprocessInfo; // { boxcoxLambda, outliersReplaced, stepsApplied }
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
#### Builder Options
|
|
310
|
+
|
|
311
|
+
| Method | Options | Description |
|
|
312
|
+
|--------|---------|-------------|
|
|
313
|
+
| `profile()` | — | Enable data profiling |
|
|
314
|
+
| `preprocess(mode)` | `"auto"`, `"none"` | Preprocessing (Box-Cox, outlier replacement) |
|
|
315
|
+
| `metric(strategy)` | `"auto"`, `"mae"`, `"mse"`, `"rmse"`, `"smape"`, `"wape"`, `"mda"` | Metric for model ranking |
|
|
316
|
+
| `ensemble(mode)` | `"auto"`, `"none"`, `"mean"`, `"median"`, `"weighted"` | Ensemble construction |
|
|
317
|
+
| `addModel(name)` | `"Naive"`, `"SES"`, `"SMA"`, `"SMA3"`, `"SMA5"`, `"SMA10"`, `"SeasonalNaive"` | Register a model |
|
|
318
|
+
| `addSeasonalModel(name, period)` | — | Register a seasonal model |
|
|
319
|
+
| `selectModels(k)` | — | Select top-K models |
|
|
320
|
+
| `crossValidate(folds, horizon)` | — | Enable cross-validation |
|
|
321
|
+
| `withFallback()` | — | Enable fallback chain |
|
|
322
|
+
| `nonNegative()` | — | Clamp forecasts to non-negative |
|
|
323
|
+
| `seasonalPeriod(p)` | — | Set seasonal period hint |
|
|
324
|
+
|
|
325
|
+
### Pipeline Report
|
|
326
|
+
|
|
327
|
+
```javascript
|
|
328
|
+
// Generate a structured report
|
|
329
|
+
const report = result.report();
|
|
330
|
+
console.log(report.title); // "Pipeline Report: SES"
|
|
331
|
+
console.log(report.sectionCount); // number of sections
|
|
332
|
+
console.log(report.toString()); // full formatted text
|
|
333
|
+
|
|
334
|
+
// Report as JSON with typed sections
|
|
335
|
+
const json = report.toJSON();
|
|
336
|
+
// { title, sections: [{ heading, content: { type, ... } }] }
|
|
337
|
+
// Content types: "text", "keyValue" (with pairs), "table" (with headers + rows)
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
### Explain Result
|
|
341
|
+
|
|
342
|
+
```javascript
|
|
343
|
+
import { explainResult } from '@sipemu/anofox-forecast';
|
|
344
|
+
|
|
345
|
+
// Generate a human-readable explanation
|
|
346
|
+
const brief = explainResult(result, 'brief');
|
|
347
|
+
console.log(brief.summary); // "Selected SES for 12-step forecast."
|
|
348
|
+
|
|
349
|
+
const detailed = explainResult(result, 'detailed');
|
|
350
|
+
console.log(detailed.summary);
|
|
351
|
+
detailed.sections.forEach(s => console.log(s.heading, s.content));
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
## Calendar Annotations
|
|
355
|
+
|
|
356
|
+
Add holidays and named regressors for models that support exogenous variables:
|
|
357
|
+
|
|
358
|
+
```javascript
|
|
359
|
+
import { CalendarAnnotations } from '@sipemu/anofox-forecast';
|
|
360
|
+
|
|
361
|
+
const calendar = new CalendarAnnotations();
|
|
362
|
+
calendar.addHoliday(Date.parse('2024-12-25'));
|
|
363
|
+
calendar.addRegressor('temperature', new Float64Array([20, 22, 25, 23]));
|
|
364
|
+
|
|
365
|
+
ts.setCalendar(calendar);
|
|
366
|
+
model.fit(ts); // ARIMA, MFLES, etc. will automatically use the regressors
|
|
367
|
+
```
|
|
368
|
+
|
|
194
369
|
## Browser Usage
|
|
195
370
|
|
|
196
371
|
```html
|
|
@@ -232,8 +407,8 @@ const forecast = model.predict(10);
|
|
|
232
407
|
## Limitations
|
|
233
408
|
|
|
234
409
|
- The `parallel` feature from the Rust crate is not available in WASM
|
|
235
|
-
-
|
|
236
|
-
-
|
|
410
|
+
- IDR (Isotonic Distributional Regression) and QRA are not yet exposed in WASM
|
|
411
|
+
- Abstract storage (`PipelineStore`) is not exposed — use the report JSON output for persistence
|
|
237
412
|
|
|
238
413
|
## License
|
|
239
414
|
|