TripleExponentialSmoothing extends AbstractExponentialSmoothing { public static TripleExOptimizer optimizer(int periods) { return optimizer(periods, new ImmutableMetricContext(null, null, 1L)); } private  TripleExponentialSmoothing(int periods, double levelSmoothing, double trendSmoothing,
                                      double seasonalSmoothing, MetricContext metricContext); static TripleExponentialSmoothing createDefault(int periods); static TripleExponentialSmoothing createWithMetric(int periods, MetricContext metricContext); static TripleExponentialSmoothing createWithSmoothingParams(int periods, double levelSmoothing,
                                                                       double trendSmoothing,
                                                                       double seasonalSmoothing); static TripleExponentialSmoothing createCustom(int periods, double levelSmoothing,
                                                          double trendSmoothing,
                                                          double seasonalSmoothing,
                                                          MetricContext metricContext); static TripleExponentialSmoothing createWithState(TripleExState state, double levelSmoothing, double trendSmoothing,
                                                             double seasonalSmoothing, MetricContext metricContext); @Override String name(); @Override int numberOfParams(); @Override int minimumInitSize(); static TripleExState initState(List<DataPoint> dataPoints, int periods, MetricContext metricContext); @Override String toString(); static TripleExOptimizer optimizer(int periods); static TripleExOptimizer optimizer(MetricContext metricContext); static TripleExOptimizer optimizer(int periods, MetricContext metricContext); static final double DEFAULT_LEVEL_SMOOTHING; static final double DEFAULT_TREND_SMOOTHING; static final double DEFAULT_SEASONAL_SMOOTHING; static final double MIN_LEVEL_SMOOTHING; static final double MIN_TREND_SMOOTHING; static final double MIN_SEASONAL_SMOOTHING; static final double MAX_LEVEL_SMOOTHING; static final double MAX_TREND_SMOOTHING; static final double MAX_SEASONAL_SMOOTHING; }
@Test public void testEmpty() { try { TimeSeriesModel model = TripleExponentialSmoothing.optimizer(12).minimizedMSE(Collections.EMPTY_LIST); Assert.fail(); } catch (Throwable ex) { } }
@Test public void testMinimalPoints() throws IOException { int minimalPoints = 40; ModelData rModel = ModelReader.read("sineLowVarLong"); TripleExponentialSmoothing.TripleExOptimizer optimizer = TripleExponentialSmoothing.optimizer(rModel.getPeriods()); try { TimeSeriesModel model = optimizer.minimizedMSE(rModel.getData().subList(0, minimalPoints)); Assert.assertNotNull(model); } catch (IllegalArgumentException ex) { Assert.fail(); } try { TimeSeriesModel model = optimizer.minimizedMSE(rModel.getData().subList(0, minimalPoints - 1)); Assert.fail(); } catch (IllegalArgumentException ex) { } }
@Test public void testSineLowVarMedium() throws IOException { ModelData rModel = ModelReader.read("sineLowVarMedium"); TimeSeriesModel seasonalModel = TripleExponentialSmoothing.optimizer(rModel.getPeriods()) .minimizedMSE(rModel.getData()); AccuracyStatistics seasonalStat = seasonalModel.initStatistics(); System.out.println(seasonalStat); TimeSeriesModel doubleExpSmoot = DoubleExponentialSmoothing.optimizer().minimizedMSE(rModel.getData()); AccuracyStatistics doubleExpSmootStat = doubleExpSmoot.initStatistics(); Assert.assertTrue(seasonalStat.getMse() < doubleExpSmootStat.getMse()); assertThat(seasonalStat.getMse()).withFailMessage("rModel: %s\nMy: %s\n%s", rModel, seasonalModel, seasonalStat) .isBetween(rModel.getMse()*ACCURACY_LOW,rModel.getMse()*ACCURACY_HIGH); }
@Test public void testSineLowVarLong() throws IOException { double ACCURACY_HIGH = 1.3; ModelData rModel = ModelReader.read("sineLowVarLong"); TimeSeriesModel seasonalModel = TripleExponentialSmoothing.optimizer(rModel.getPeriods()) .minimizedMSE(rModel.getData()); AccuracyStatistics seasonalStat = seasonalModel.initStatistics(); System.out.println(seasonalStat); assertThat(seasonalStat.getMse()).withFailMessage("rModel: %s\nMy: %s\n%s", rModel, seasonalModel, seasonalStat) .isBetween(rModel.getMse()*ACCURACY_LOW,rModel.getMse()*ACCURACY_HIGH); }
@Test public void testSineLowVarTrend() throws IOException { ModelData rModel = ModelReader.read("sineTrendLowVar"); TimeSeriesModel seasonalModel = TripleExponentialSmoothing.optimizer(rModel.getPeriods()) .minimizedMSE(rModel.getData()); AccuracyStatistics initStatistics = seasonalModel.initStatistics(); System.out.println(initStatistics); assertThat(initStatistics.getMse()).withFailMessage("rModel: %s\nMy: %s\n%s", rModel, seasonalModel, initStatistics) .isBetween(rModel.getMse()*ACCURACY_LOW,rModel.getMse()*ACCURACY_HIGH); }
@Test public void testAustourists() throws IOException { ModelData rModel = ModelReader.read("austourists"); TimeSeriesModel seasonalModel = TripleExponentialSmoothing.optimizer(rModel.getPeriods()) .minimizedMSE(rModel.getData()); AccuracyStatistics seasonalStat = seasonalModel.initStatistics(); System.out.println(seasonalStat); assertThat(seasonalStat.getMse()).withFailMessage("rModel: %s\nMy: %s\niniStat: %s", rModel, seasonalModel, seasonalStat) .isBetween(rModel.getMse()*ACCURACY_LOW, rModel.getMse()*ACCURACY_HIGH); }
@Test public void testPrediction() throws IOException { ModelData rModel = ModelReader.read("austourists"); TimeSeriesModel seasonalModel = TripleExponentialSmoothing.optimizer(rModel.getPeriods()) .minimizedMSE(rModel.getData()); AccuracyStatistics seasonalStat = seasonalModel.initStatistics(); System.out.println(seasonalStat); int nAhead = 15; List<DataPoint> forecast = seasonalModel.forecast(nAhead); DataPoint oneStepForecast = seasonalModel.forecast(); Assert.assertTrue(forecast.size() == nAhead); Assert.assertTrue(oneStepForecast.getValue().equals(forecast.get(0).getValue())); double ACCURACY_LOW = 0.95; double ACCURACY_HIGH = 1.05; double[] expectedFromR = {60.02375, 37.51312, 46.33168, 49.98424, 62.01252, 39.50189, 48.32045, 51.97301, 64.00129, 41.49066, 50.30923, 53.96178, 65.99007, 43.47944, 52.29800}; for (int i = 0; i < nAhead; i++) { assertThat(forecast.get(i).getValue()) .isBetween(expectedFromR[i]*ACCURACY_LOW, expectedFromR[i]*ACCURACY_HIGH); } }
@Test public void testCollectionInterval() throws IOException { ModelData rModel = ModelReader.read("austourists"); MetricContext metricContext = new ImmutableMetricContext(null, null, 30L); TimeSeriesModel modelCollectionInterval1 = TripleExponentialSmoothing.optimizer(rModel.getPeriods()) .minimizedMSE(rModel.getData()); rModel.setData(setCollectionInterval(rModel.getData(), 30L)); TimeSeriesModel model = TripleExponentialSmoothing.optimizer(rModel.getPeriods(), metricContext) .minimizedMSE(rModel.getData()); Assert.assertEquals(modelCollectionInterval1.initStatistics(), model.initStatistics()); }