UNPKG

moving-average-arima

Version:

ARIMA, SARIMA, SARIMAX and AutoARIMA models for time series analysis and forecasting

111 lines (110 loc) 5.62 kB
"use strict"; var ARIMA = require('.'); var test = require('tape'); function mse(yt, yp) { return yt.reduce(function (a, v, i) { return a + Math.pow(v - yp[i], 2) / yt.length; }, 0); } function rmse(yt, yp) { return Math.sqrt(mse(yt, yp)); } function uniq(arr) { var uniq = []; arr.forEach(function (v) { if (!uniq.includes(v)) { uniq.push(v); } }); return uniq; } test('Old API', function (_) { var ts = [112, 118, 132, 129, 121, 135, 148, 148, 136, 119, 104, 118, 115, 126, 141, 135, 125, 149, 170, 170, 158, 133, 114, 140, 145, 150, 178, 163, 172, 178, 199, 199, 184, 162, 146, 166, 171, 180, 193, 181, 183, 218, 230, 242, 209, 191, 172, 194, 196, 196, 236, 235, 229, 243, 264, 272, 237, 211, 180, 201, 204, 188, 235, 227, 234, 264, 302, 293, 259, 229, 203, 229, 242, 233, 267, 269, 270, 315, 364, 347, 312, 274, 237, 278, 284, 277, 317, 313, 318, 374, 413, 405, 355, 306, 271, 306, 315, 301, 356, 348, 355, 422, 465, 467, 404, 347, 305, 336, 340, 318, 362, 348, 363, 435, 491, 505, 404, 359, 310, 337, 360, 342, 406, 396, 420, 472, 548, 559, 463, 407, 362, 405]; var tstest = [417, 391, 419, 461, 472, 535, 622, 606, 508, 461, 390, 432]; var N = 50; var _a = ARIMA(ts, tstest.length, { p: 0, d: 1, q: 1, P: 0, D: 1, Q: 1, s: 12, verbose: false }), pred = _a[0], errors = _a[1]; var loss = rmse(pred, tstest); _.true(loss < 22); _.end(); }); test('SARIMA', function (_) { var ts = [112, 118, 132, 129, 121, 135, 148, 148, 136, 119, 104, 118, 115, 126, 141, 135, 125, 149, 170, 170, 158, 133, 114, 140, 145, 150, 178, 163, 172, 178, 199, 199, 184, 162, 146, 166, 171, 180, 193, 181, 183, 218, 230, 242, 209, 191, 172, 194, 196, 196, 236, 235, 229, 243, 264, 272, 237, 211, 180, 201, 204, 188, 235, 227, 234, 264, 302, 293, 259, 229, 203, 229, 242, 233, 267, 269, 270, 315, 364, 347, 312, 274, 237, 278, 284, 277, 317, 313, 318, 374, 413, 405, 355, 306, 271, 306, 315, 301, 356, 348, 355, 422, 465, 467, 404, 347, 305, 336, 340, 318, 362, 348, 363, 435, 491, 505, 404, 359, 310, 337, 360, 342, 406, 396, 420, 472, 548, 559, 463, 407, 362, 405]; var tstest = [417, 391, 419, 461, 472, 535, 622, 606, 508, 461, 390, 432]; var N = 50; var losses = []; for (var i = 0; i < N; i++) { var arima = new ARIMA({ p: 0, d: 1, q: 1, P: 0, D: 1, Q: 1, s: 12, verbose: false }); arima.fit(ts); var res = arima.predict(12); losses.push(rmse(res[0], tstest)); } var ul = uniq(losses); _.equal(ul.length, 1); _.true(Math.max.apply(Math, ul) < 22); _.end(); }); test('AutoARIMA', function (_) { var ts = [16.9969, 16.5969, 16.3012, 16.1018, 17.0998, 16.8997, 16.8002, 17.4001, 17.0998, 16.9996, 16.6991, 17.3993, 17.2002, 17.4013, 17.4029, 17.0015, 17.2965, 17.1966, 17.4013, 16.802, 17.1, 17.3995, 17.3995, 17.5008, 17.3998, 17.6, 17.4, 17.3, 17, 17.8, 17.5, 18.1, 17.5, 17.4, 17.4, 17.1, 17.6, 17.7, 17.4, 17.8, 17.6, 17.5, 16.5, 17.8, 17.3, 17.3, 17.1, 17.4, 16.9, 17.3, 17.6, 16.9, 16.7, 16.8, 16.8, 17.2, 16.8, 17.6, 17.2, 16.6, 17.1, 16.9, 16.6, 18, 17.2, 17.3, 17, 16.9, 17.3, 16.8, 17.3, 17.4, 17.7, 16.8, 16.9, 17, 16.9, 17, 16.6, 16.7, 16.8, 16.7, 16.4, 16.5, 16.4, 16.6, 16.5, 16.7, 16.4, 16.4, 16.2, 16.4, 16.3, 16.4, 17, 16.9, 17.1, 17.1, 16.7, 16.9, 16.5, 17.2, 16.4, 17, 17, 16.7, 16.2, 16.6, 16.9, 16.5, 16.6, 16.6, 17, 17.1, 17.1, 16.7, 16.8, 16.3, 16.6, 16.8, 16.9, 17.1, 16.8, 17, 17.2, 17.3, 17.2, 17.3, 17.2, 17.2, 17.5, 16.9, 16.9, 16.9, 17.0001, 16.4999, 16.6996, 16.8001, 16.7013, 16.6985, 16.6005, 16.5, 17, 16.7, 16.7, 16.9, 17.4, 17.1, 17, 16.8, 17.2, 17.2, 17.4, 17.2, 16.9, 16.8, 17, 17.4, 17.2, 17.2, 17.1, 17.1, 17.1, 17.4, 17.2, 16.9, 16.9, 17, 16.7, 16.9, 17.3, 17.8, 17.8, 17.6, 17.5, 17, 16.8999, 17.1, 17.2002, 17.3998, 17.5001, 17.9, 17, 17, 17, 17.2, 17.3, 17.4]; var tstest = [17.4, 17.4, 17.0001, 18.0001, 18.2001, 17.5999, 17.7996, 17.6992, 17.2002, 17.4027]; var N = 10; var losses = []; for (var i = 0; i < N; i++) { var arima = new ARIMA({ auto: true, verbose: false, search: 0, aproximation: 0 }); arima.fit(ts); var res = arima.predict(10); losses.push(rmse(res[0], tstest)); } var ul = uniq(losses); _.equal(ul.length, 1); _.true(Math.max.apply(Math, ul) < 1); _.end(); }); test('SARIMAX with 2 exogenous variables', function (_) { var N = 30; var f = function (a, b) { return a * 2 + b * 5; }; var losses = []; for (var i = 0; i < N; i++) { var exog = Array(30).fill(0).map(function (x) { return [Math.random(), Math.random()]; }); var exognew = Array(10).fill(0).map(function (x) { return [Math.random(), Math.random()]; }); var ts = exog.map(function (x) { return f(x[0], x[1]) + Math.random() / 5; }); for (var j = 0; j < 10; j++) { var arima = new ARIMA({ p: 1, d: 0, q: 1, transpose: true, verbose: false }); arima.fit(ts, exog); var res = arima.predict(10, exognew); var ytrue = exognew.map(function (x) { return f(x[0], x[1]); }); var ypred = res[0]; losses.push(rmse(ytrue, ypred)); } } var ul = uniq(losses); _.equal(ul.length, N); _.true(Math.max.apply(Math, ul) < 2); _.end(); });