Example 3: Forecasting

Consider the Wolfer Sunspot Data (Anderson 1971, p. 660) consisting of the number of sunspots observed each year from 1749 through 1924. The data set for this example consists of the number of sunspots observed from 1770 through 1869. An ARMA(2,1) model is fitted to these data using the Method of Moments. With backward_origin = 3, the forecast method is used to obtain forecasts starting from 1866, 1867, 1868, and 1869, respectively. Note that the values in the first row of the matrix returned by this method are the one-step ahead forecasts for 1867, 1868, ..., 1870. The values in the second row are the two-step ahead forecasts for 1868, 1869, ..., 1871, etc.

Method getForecast is used to compute the one-step ahead forecasts setting backward_origin = 10. This obtains the one-step ahead forecasts for the last 10 observations in the series, i.e. years 1860-1869, plus the next 5 years. The upper 90% confidence limits are computed for these forecasts using the getDeviations method.

import java.text.*;
import com.imsl.stat.*;
import com.imsl.math.PrintMatrix;
import com.imsl.math.PrintMatrixFormat;

public class ARMAEx3 {
    public static void main(String args[]) throws Exception {
        /* sunspots from 1770 to 1869 */
        double[] z = {100.8, 81.6, 66.5, 34.8, 30.6, 7, 19.8, 92.5,
        154.4, 125.9, 84.8, 68.1, 38.5, 22.8, 10.2, 24.1, 82.9,
        132, 130.9, 118.1, 89.9, 66.6, 60, 46.9, 41, 21.3, 16,
        6.4, 4.1, 6.8, 14.5, 34, 45, 43.1, 47.5, 42.2, 28.1, 10.1,
        8.1, 2.5, 0, 1.4, 5, 12.2, 13.9, 35.4, 45.8, 41.1, 30.4,
        23.9, 15.7, 6.6, 4, 1.8, 8.5, 16.6, 36.3, 49.7, 62.5, 67,
        71, 47.8, 27.5, 8.5, 13.2, 56.9, 121.5, 138.3, 103.2,
        85.8, 63.2, 36.8, 24.2, 10.7, 15, 40.1, 61.5, 98.5, 124.3,
        95.9, 66.5, 64.5, 54.2, 39, 20.6, 6.7, 4.3, 22.8, 54.8,
        93.8, 95.7, 77.2, 59.1, 44, 47, 30.5, 16.3, 7.3, 37.3,
        73.9};
        int backwardOrigin = 3;
        double[][] printTable     = new double[15][4];
        double[][] printEstimates = new double[1][4];
        double[] forecasts;
        double[] deviations;
        PrintMatrixFormat pmf = new PrintMatrixFormat();
        PrintMatrix pm        = new PrintMatrix();
        NumberFormat nf = NumberFormat.getNumberInstance();
        pm.setColumnSpacing(3);
        
        ARMA arma = new ARMA(2, 1, z);
        arma.setRelativeError(0.0);
        arma.setMaxIterations(0);
        arma.compute();
        
        System.out.println("ARMA ESTIMATES");
        double[] ar = arma.getAR();
        double[] ma = arma.getMA();
        printEstimates[0][0] = arma.getConstant();
        printEstimates[0][1] = ar[0];
        printEstimates[0][2] = ar[1];
        printEstimates[0][3] = ma[0];
        String[] estimateLabels = {"Constant", "AR(1)", "AR(2)", "MA(1)"};
        pmf.setColumnLabels(estimateLabels);
        nf.setMinimumFractionDigits(5);
        nf.setMaximumFractionDigits(5);
        pmf.setNumberFormat(nf);
        pm.setTitle("ARMA ESTIMATES");
        pm.print(pmf, printEstimates);
        arma.setBackwardOrigin(backwardOrigin);
        
        String[] labels = { "From 1866", "From 1867",
        "From 1868", "From 1869"};
        pmf.setColumnLabels(labels);
        pmf.setFirstRowNumber(1);
        nf.setMinimumFractionDigits(1);
        nf.setMaximumFractionDigits(1);
        pmf.setNumberFormat(nf);
        pm.setTitle("FORECASTS");
        pm.print(pmf, arma.forecast(5));
        
        /* FORECASTING - An example of forecasting using the ARMA estimates
         * In this case, forecasts are returned for the last 10 values in the 
         * series followed by the forecasts for the next 5 values.
         */
        String[] forecastLabels={"Observed", "Forecast", "Residual", "UCL(90%)"};
        pmf.setColumnLabels(forecastLabels);
        backwardOrigin = 10;
        arma.setBackwardOrigin(backwardOrigin);
        int n_forecast = 5;
        arma.setConfidence(0.9);
        forecasts  = arma.getForecast(n_forecast);
        deviations = arma.getDeviations();
        for(int i=0; i<backwardOrigin; i++){
            printTable[i][0] = z[z.length-backwardOrigin+i];
            printTable[i][1] = forecasts[i];
            printTable[i][2] = z[z.length-backwardOrigin+i]-forecasts[i];
            printTable[i][3] = forecasts[i] + deviations[0];
        }
        for(int i=backwardOrigin; i<n_forecast+backwardOrigin; i++){
            printTable[i][0] = Double.NaN;
            printTable[i][1] = forecasts[i];
            printTable[i][2] = Double.NaN;
            printTable[i][3] = forecasts[i] + deviations[i-backwardOrigin];
        }
        pmf.setFirstRowNumber(1869-backwardOrigin+1);
        pm.setTitle("ARMA ONE-STEP AHEAD FORECASTS");
        pm.print(pmf, printTable);
        
        //new PrintMatrix("getForecast").print(arma.getForecast(15));
        //new PrintMatrix("getDeviations").print(arma.getDeviations());
        
        
    }
}

Output

ARMA ESTIMATES
                ARMA ESTIMATES
    Constant    AR(1)      AR(2)      MA(1)    
0   15.54398   1.24426   -0.57515   -0.12409   

                     FORECASTS
    From 1866   From 1867   From 1868   From 1869   
1     18.3        16.6        55.2        83.7      
2     28.9        32.0        62.8        77.2      
3     41.0        45.8        61.9        63.5      
4     49.9        54.1        56.5        50.1      
5     54.1        56.6        50.2        41.4      

           ARMA ONE-STEP AHEAD FORECASTS
       Observed   Forecast   Residual   UCL(90%)   
1860     95.7      100.7       -5.0      128.6     
1861     77.2       81.3       -4.1      109.2     
1862     59.1       57.1        2.0       84.9     
1863     44.0       44.4       -0.4       72.3     
1864     47.0       36.4       10.6       64.2     
1865     30.5       47.4      -16.9       75.3     
1866     16.3       28.6      -12.3       56.4     
1867      7.3       19.8      -12.5       47.7     
1868     37.3       16.8       20.5       44.7     
1869     73.9       55.2       18.7       83.1     
1870      ?         83.7        ?        111.6     
1871      ?         77.2        ?        124.5     
1872      ?         63.5        ?        120.2     
1873      ?         50.1        ?        109.4     
1874      ?         41.4        ?        100.8     

Link to Java source.