Advanced Statistics with R code 90% doen just check it and make a summary
CSC425 – Time series analysis and forecasting
Homework 4 - Solutions
Problem 1 [just for fun!] – NO CREDIT
I noticed some students had questions regarding the SARIMA notation. Write the model expression for
the following SARIMA models for the {Xt} time series.
Example: SARIMA(2,0,0)(1,0,0)[12]
The notation indicates a regular AR(2) model and a seasonal AR(1)[12] model
(1-φ1B-φ2B 2 )(1-Φ1 B
12 )Xt = at
a) SARIMA(2,1,0)(1,1,0)[4] b) SARIMA(1,0,1)(0,0,1)[12] c) SARIMA(0,1,3)(0,1,1)[4]
In general SARIMA(p,d,q)(P,D,Q)[s] where the first set (p,d,q) describes the regular
ARIMA(p,d,q) model, and the second set (P,D,Q)[s] describes the order of the seasonal
component.
a) The first set (2,1,0) identifies a first difference + AR(2) model. The second set (1,1,0) indicates the seasonal component with a seasonal differencing and a AR(4) seasonal
model. Thus
SARIMA(2,1,0)(1,1,0)[4]
(1-ϕ1B-ϕ2B 2 )(1-φ1B
4 ) (1-B)(1-B
4 )Xt = at
b) The first set (1,0,1) indicates an ARMA(1,1) model. The second set (0,0,1) is for the seasonal component, indicating MA(12) seasonal model. Thus
SARIMA(1,0,1)(0,0,1)[12]
(1-ϕ1B)Xt =(1-θ1B 12
) (1-ϑ1B)at
c) The first set (0,1,3) indicates an ARIMA(0,1,3) model, i.e. first difference + MA(3) model. The second set (0,1,1,) indicates a seasonal differencing and a MA(4) model.
Thus
SARIMA(0,1,3)(0,1,1)[4]
(1-B)(1-B 4 )Xt = (1-θ1B
4 ) (1-ϑ1B- ϑ2B
2 - ϑ3B
3 )at
Problem 2 [15pts]
Consider the quarterly earnings per share (EPS) of Costco from the last quarter of 2001 to the third
quarter of 2013 fiscal year. The data were obtained from the Nasdaq website and are saved in the
costco.csv file.
a) Analyze the distribution of the quarterly earnings. Are the data normally distributed? Provide appropriate statistics, tests and graphs to support your conclusions.
The average quarterly earnings are $0.66 per share with a standard deviation of $0.27. The
distribution of eps has a slight positive skew – as shown by the histogram and normal quantile plot
(points under the right tails diverge from the diagonal). Normality test rejects hypothesis of
normality for earnings data at 5% level. (See SAS / R output)
The UNIVARIATE Procedure
Variable: eps
Moments
N 48 Sum Weights 48
Mean 0.66270833 Sum Observations 31.81
Std Deviation 0.26970228 Variance 0.07273932
Skewness 0.95652585 Kurtosis 0.80234438
Uncorrected SS 24.4995 Corrected SS 3.41874792
Coeff Variation 40.6969796 Std Error Mean 0.03892817
Results of Jacque and Bera test on normality
Jarque & P-value for
skewness, kurtosis, Bera Jarque &
Obs eps eps statistic Bera test
1 0.95653 0.80234 8.60705 0.013521
b) Apply the log function to stabilize variable and analyze the variable yt=log(eps) at time t. The distribution of log(eps) is closer to normal distribution, with symmetry and kurtosis statistics
close to 0 as also shown by histogram and normal quantile plot. The Jarque-Bera test is not
significant (p-value > 0.05) indicating that hypothesis of normal distribution for log(eps) cannot
be rejected. Moments
N 48 Sum Weights 48
Mean -0.4891602 Sum Observations -23.479688
Std Deviation 0.39954911 Variance 0.15963949
Skewness 0.0058175 Kurtosis -0.398239
Uncorrected SS 18.9883843 Corrected SS 7.50305604
Coeff Variation -81.68063 Std Error Mean 0.05766995
Results of Jacque and Bera test on normality
Jarque & P-value for
skewness, kurtosis, Bera Jarque &
Obs xlog xlog statistic Bera test
1 .005817502 -0.39824 0.31746 0.85323
c) Is there any evidence of a seasonal effect in the log(eps) data? Explain your answer. The time plot for Costco quarterly earnings and for log(earnings) show quarterly seasonality, with
higher earnings in the first and third quarters and lower earnings in the second and fourth
quarters. We can observe a slight dip in earnings in 2009 but the recent economic crisis didn’t
seem to affect Costco earnings much, as earnings increased shortly after the dip. The log(eps) time
plot shows that variability is more constant over time.
eps
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
1
1.1
1.2
1.3
1.4
date
01/01/2000 01/01/2002 01/01/2004 01/01/2006 01/01/2008 01/01/2010 01/01/2012 01/01/2014
Costco earnings
d) Compute the Dickey-Fuller test for the quarterly earnings for p=1, 3, and 5. Write down the test hypotheses, and the test statistics and analyze the results of the test
Dickey Fuller Test is expressed as H0: φ1=1 vs Ha: φ1<>1 where the null hypothesis
indicates unit-root non-stationarity.
The Dickey-Fuller test shows that the earnings time series is unit-root non-stationary. The test p-
values for lags 1, 3 and 5 are all larger than 5, therefore the null hypothesis of non stationarity
cannot be rejected (large p-values> 0.1).
The ARIMA Procedure
Augmented Dickey-Fuller Unit Root Tests
Type Lags Rho Pr < Rho Tau Pr < Tau F Pr > F
Zero Mean 1 1.1538 0.9282 1.37 0.9554
3 1.2386 0.9381 4.43 0.9999
5 1.1075 0.9213 1.91 0.9852
Single Mean 1 -0.7726 0.9018 -0.28 0.9193 1.22 0.7642
3 1.8677 0.9962 2.06 0.9998 10.02 0.0010
5 0.4869 0.9736 0.24 0.9722 1.86 0.6076
Trend 1 -20.9931 0.0306 -2.77 0.2161 4.22 0.3620
3 0.1628 0.9958 0.06 0.9958 2.31 0.7221
5 93.4268 0.9999 -2.07 0.5472 2.53 0.6813
e) Take the first difference of log(eps) series, and analyze its autocorrelation function. Does the differenced time series show strong seasonal patterns? Explain.
The ACF of the first difference of yt=log(eps), say yt-yt-1 shows larger values at lags multiple of
four, which is consistent with the seasonal behavior seen in the time plot. The TS is not stationary
since it shows seasonality.
xlog
-1.3
-1.2
-1.1
-1.0
-0.9
-0.8
-0.7
-0.6
-0.5
-0.4
-0.3
-0.2
-0.1
0.0
0.1
0.2
0.3
0.4
date
01/01/2000 01/01/2002 01/01/2004 01/01/2006 01/01/2008 01/01/2010 01/01/2012 01/01/2014
Time plot of Costco log(EPS)
f) If you de-trend and de-seasonalize the Costco log(eps) data, do you obtain a stationary time series? Use appropriate statistical techniques and graphs to analyze stationarity.
The de-trended and de-seasonalized time series is stationary – as indicated by the Dickey-Fuller
test (p-values are small, and therefore hypothesis of non stationarity can be rejected), and small
ACF values. After differencing the time series, we can assume a zero mean model for the data.
Note that deseasonalized TS have zero mean (use”nc” type in R)
The ARIMA Procedure
Augmented Dickey-Fuller Unit Root Tests
Type Lags Rho Pr < Rho Tau Pr < Tau F Pr > F
Zero Mean 1 -39.9069 <.0001 -4.17 0.0001
3 85.9684 0.9999 -5.29 <.0001
5 28.6760 0.9999 -4.61 <.0001
Single Mean 1 -39.7843 0.0003 -4.10 0.0024 8.49 0.0010
3 85.8868 0.9999 -5.19 0.0002 13.58 0.0010
5 28.7344 0.9999 -4.51 0.0009 10.30 0.0010
Trend 1 -39.6292 <.0001 -4.04 0.0149 8.22 0.0184
3 86.3878 0.9999 -5.10 0.0009 13.11 0.0010
5 28.3836 0.9999 -4.48 0.0053 10.04 0.0010
g) Apply an airline model SARIMA(0,1,1)(0,1,1)4 to estimate the log(eps).
a. Write down the estimated expression of the fitted model (1-B)(1-B
4 )Xt = (1-0.339B)(1-0.669B
4 )at (sas output)
The ARIMA Procedure
Maximum Likelihood Estimation
Standard Approx
Parameter Estimate Error t Value Pr > |t| Lag
MA1,1 0.33862 0.14912 2.27 0.0232 1
MA2,1 0.66864 0.13492 4.96 <.0001 4
Variance Estimate 0.012082
Std Error Estimate 0.109917
AIC -63.4007
SBC -59.8783
Number of Residuals 43
b. Are all model coefficients significant? All coefficients of the SARIMA model are significant (p-value < 0.05). .
c. Analyze the residuals to check the model validity The autocorrelation analysis of the residuals show that the ACF at lag 5 is significant larger
than zero. This is also shown by the Ljung Box test that has p-value > 0.05 for lags up to 6.
These results indicate that there is some source of serial correlation that is still unexplained
by the model. Since it is only one large ACF value, this is not indicative of a seasonal trend.
The solution is to add a lag 5 parameter in the MA component of the SARIMA model.
Autocorrelation Check of Residuals
To Chi- Pr >
Lag Square DF ChiSq --------------------Autocorrelations--------------------
6 9.44 4 0.0509 -0.013 0.104 -0.198 -0.129 -0.346 -0.049
12 12.75 10 0.2380 0.002 0.184 0.019 0.153 -0.000 0.023
18 20.68 16 0.1911 -0.185 0.066 -0.179 -0.065 -0.044 0.189
24 21.88 22 0.4673 -0.014 -0.055 -0.066 0.054 -0.053 -0.009
h) The multiplicative airline model has some limitations, how can you modify it to be a better fit for the data? (If you are not sure how to do this, post a message on the discussion forum, and start a
discussion with other students!)
a. Write down the estimated expression of the fitted model (1-B)(1-B
4 )Xt =(1-0.7235B
4 )(1-0.4103B-0.3726B
5 )at (sas output)
The ARIMA Procedure
Maximum Likelihood Estimation
Standard Approx
Parameter Estimate Error t Value Pr > |t| Lag
MA1,1 0.41029 0.16632 2.47 0.0136 1
MA1,2 0.37262 0.16359 2.28 0.0227 5
MA2,1 0.72350 0.13731 5.27 <.0001 4
Variance Estimate 0.010536
Std Error Estimate 0.102645
AIC -66.3638
SBC -61.0802
Number of Residuals 43
b. Are all model coefficients significant? All coefficients are significantly different from zero
c. Analyze the residuals to check the model validity The residuals are white noise. Ljung Box test for lags up to 24 is significant, indicating that
the model is able to capture the time dependencies in the data.
To Chi- Pr >
Lag Square DF ChiSq --------------------Autocorrelations--------------------
6 3.77 3 0.2870 -0.059 0.091 -0.202 -0.134 -0.078 0.028
12 5.94 9 0.7457 0.026 0.140 -0.069 0.078 -0.055 0.062
18 13.34 15 0.5759 -0.109 0.071 -0.205 -0.086 -0.066 0.182
24 14.27 21 0.8577 0.005 -0.042 -0.079 0.018 -0.033 -0.032
i) Which model is a better fit for the data? Explain what evidence you use to select the best model.
The SARIMA(0,1,0)(0,1,5)4 provides a better description of the dynamic behavior of the Costco
log earnings time series. The coefficients are significantly different from zero, residuals are white
noise and normally distributed. Also the second model has the lowest SBC/BIC values.
j) Compute forecasts for Costco quarterly EPS for the next 4 quarters using the selected model in h). The table below reports forecasts in terms of EPS values. The forecasts of log(eps) computed by
SARIMA model were transformed to EPS original scale using the exp() function.
Obs date OBSERVED FORECAST STD L95 U95 RESIDUAL x
49 10/01/2013 . 0.97486 0.10264 0.79302 1.18584 . .
50 01/01/2014 . 1.15743 0.11916 0.90987 1.45159 . .
51 04/01/2014 . 1.00514 0.13366 0.76662 1.29454 . .
52 07/01/2014 . 1.51769 0.14672 1.12620 2.00170 . .
R code: # Analysis of quarterly house starts (single family homes) in the US
from 1974
# to 2012. Seasonality is expected due to lower number of new
constructions
# in the winter months.
#1. LOAD LIBRARIES
library(tseries)
library(fBasics)
library(forecast)
#2. IMPORT DATA
# Load data with no variable names into the data frame "da"
myd=read.table("costco.csv",header=T, sep=',')
# creates time series object
x=myd$eps
xts=ts(myd$eps,start=c(2001,4), frequency=4,)
# create time plot
plot(xts,type='l')
# TRANSFORMATIONS
# natural log
y=log(x)
yts=log(xts)
plot(yts,type='l')
#add circles on data points in the time plot
points(yts)
# ACF ANALYSIS
# two plots per page
par(mfcol=c(1,1))
# ACF plot for log starts
# as.vector() transforms time series to regular numerical vector
acf(as.vector(y),lag.max=24, main="ACF of log starts")
# APPLYING DIFFERENCING TO DATA
# compute regular differences
dy=diff(y)
# create acf plot
acf(as.vector(dy),lag.max=16, main="ACF of DX log starts")
# compute seasonal difference for quarterly data (s=4)
sdy=diff(dy,4)
# create acf plot
acf(as.vector(sdy),lag.max=16, main="ACF of DSDX log starts")
pacf(sdy)
#FIT SARIMA MODEL
library(forecast)
# try automated order selection
# since TS is stationary, stationary = FALSE;
auto.arima(y, trace=T,stationary = FALSE)
# fit multiplicative seasonal model ARIMA(1,0,0)×(1,1,0)[4]
m1=arima(y, order=c(1,0,0),seasonal=list(order=c(1,1,0),period=4),
method="ML")
source("arimaPrint.R")
# use arimaPrint() function in arimaPrint.R file
# save arimaPrint.R file in work directory
arimaPrint(m1)
acf(m1$residuals)
qqnorm(m1$residuals)
qqline(m1$residuals)
hist(m1$residuals)
# Since seasonal AR_1 coefficient is not significant; remove it from
model;
# fit airline seasonal model ARIMA(0,1,1)×(0,1,1)4
m1=arima(y, order=c(0,1,1),seasonal=list(order=c(0,1,1),period=4),
method="ML")
m1
# fit airline seasonal model ARIMA(0,1,5)×(0,1,1)4 with only lags 1
and 5
m1=arima(y, order=c(0,1,5),seasonal=list(order=c(0,1,1),period=4),
method="ML", fixed=c(NA, 0,0,0,NA,NA))
m1
# use arimaPrint() function in arimaPrint.R file
arimaPrint(m1,c(1,5,6) )
# One plot per page
par(mfcol=c(1,1))
acf(m1$residuals)
# "approximated" ljung box test on residuals
Box.test(m1$residuals, 6, "Ljung-Box",fitdf=3 )
Box.test(m1$residuals, 12, "Ljung-Box", fitdf=3)
# compute predictions for log data for up to 8-step aheads
f1=forecast(m1,h=8)
names(f1)
plot(f1)
#predictions in original scale;
exp(f1$mean)
# creates forecast plot for original variable
# join data with forecasts
s1=c(x,exp(f1$mean))
#s1=ts(s1, frequency=4,start=c(1974,1))
# computes lower limit for 95% interval
lcl=c(x,exp(f1$lower[,2]))
# computes upper limit for 95% interval
ucl=c(x,exp(f1$upper[,2]))
# Forecast plot
plot(s1,type='l',col='red')
# points(s2011)
lines(1:length(s1),ucl,lty=2)
lines(1:length(s1),lcl,lty=2)
SAS code title1 'Costco earnings';
proc import datafile="costco.csv" out=myd replace;
getnames=yes;
delimiter=',';
run;
proc print;
run;
data myd;
set myd;
xlog=log(eps);
run;
*analyze distribution of log(eps);
proc univariate data=myd;
var xlog;
histogram/normal;
qqplot / normal(mu=est sigma=est);
output out=stats kurtosis=kurtosis skewness=skewness N=ntot;
run;
/* steps to compute Jarque-Bera tests*/
/* and print out tests results to the OUTPUT window */
data computation;
set stats;
label pv_kur = "P-value for kurtosis test";
*skewness statistic;
skew_test = skewness/sqrt(6/Ntot);
*kurtosis statistic;
kurt_test = kurtosis/sqrt(24/Ntot);
* jarque-bera statistic;
jb = skew_test*skew_test+kurt_test*kurt_test;
* JB test p-values;
pv_jb = 1-cdf('CHISQUARE', jb,2);
label pv_jb = "P-value for Jarque & Bera test"
jb = "Jarque & Bera statistic";
/* Print out results of tests*/
Title " Results of Jacque and Bera test on normality";
proc print data= computation label;
var skewness kurtosis jb pv_jb;
run;
*plot timeplots for all transformed variables;
symbol1 i=join v=dot;
proc gplot data=myd;
title1 "Time plot of Costco EPS";
plot eps * date = 1 ;
title1 "Time plot of Costco log(EPS)";
plot xlog * date = 1 ;
run;
proc arima data=myd;
identify var=eps nlag=24 stationarity=(adf=(1 3 5));
identify var=xlog(1) nlag=24;
identify var=xlog(1,4) nlag=20 stationarity=(adf=(1 3 5))
minic;
identify var=xlog(1,4) nlag=20 esacf;
run;
*airline model SARIMA(0,1,1)(0,1,1)[4];
estimate q=(1)(4) noconstant method=ml;
* modified airline model SARIMA(0,1,1)(0,1,5)[4];
estimate q=(1 5)(4) noconstant method=ml;
outlier maxnum=3 alpha=0.01;
run;
forecast out=b lead=12 id=date interval=quarter;
quit;
/*
The following statements retransform the forecast values to get
forecasts in the original scales.
*/
data c;
set b;
x = exp( xlog );
forecast = exp( forecast + std*std/2 );
l95 = exp( l95 );
u95 = exp( u95 );
run;
proc print data=c;
run;
Problem 3 [12 points] (review Week 5 notes)
Global temperatures are rising. Analyze the time series of Land-Ocean Temperature Index in degrees
Celsius published at the NASA-GISS (Goddard Institute for Space Studies) and saved in dataset
globtemp.csv. The temperature index measures temperature anomalies that are computed relative
to the base period 1951-1980. The reason to work with anomalies, rather than absolute
temperature is that absolute temperature varies markedly in short distances, while monthly or
annual temperature anomalies are representative of a much larger region (from GISS website). a) Plot the temperature index time series and its ACFs (20 lags). Analyze trends and patterns
shown by the data.
Time plot shows that global temperatures has steadily increased since 1950.The ACF
plot shows that Global Temperature Index TS is non stationary (ACF function decays
very slowly to zero, which is not surprising given the upward time trend shown by the
time plot)
b) Analyze if the series is stationary using both the ACF function and the Dickey Fuller test The DF tests computed for AR(3) and AR(5) models show that the null hypothesis of unit-root
stationarity cannot be rejected (p-values are > 0.1). (NOTE: for this dataset, it would be
acceptable to use the DF test for either model with intercept (constant) but no time trend, or
for a model with intercept (constant) and a time trend. Results are equivalent)
> # Dickey Fuller test for time series with time trend
> library(fUnitRoots)
> adfTest(index, lags=3, type=c("ct"))
Title:
Augmented Dickey-Fuller Test
Test Results:
PARAMETER:
Lag Order: 3
STATISTIC:
Dickey-Fuller: -2.4227
P VALUE:
0.4007
> adfTest(index, lags=5, type=c("ct"))
Title:
Augmented Dickey-Fuller Test
Test Results:
PARAMETER:
Lag Order: 5
STATISTIC:
Dickey-Fuller: -1.9472
P VALUE:
0.5984
In SAS
Augmented Dickey-Fuller Unit Root Tests
Type Lags Rho Pr < Rho Tau Pr < Tau F Pr > F
Zero Mean 1 -3.1286 0.2229 -0.97 0.2967
3 0.3095 0.7561 0.16 0.7308
5 0.6287 0.8363 0.36 0.7864
Single Mean 1 -2.9490 0.6593 -0.91 0.7827 0.74 0.8811
3 0.5894 0.9790 0.31 0.9780 1.13 0.7831
5 1.0265 0.9887 0.63 0.9900 1.84 0.6012
Trend 1 -26.5191 0.0132 -3.75 0.0225 7.46 0.0207
3 -11.2587 0.3399 -2.42 0.3659 4.15 0.3489
5 -8.1422 0.5607 -1.95 0.6245 3.26 0.5268
c) Use order selection methods such as EACF or BIC to identify the order of the “best” AR/MA/ARMA model for the global temperature index time series. Note that since the TS is
not stationary, you should use an ARIMA(p,1,d) model.
Since TS is unit-root non stationary, only ARIMA(p,1,q) models will be evaluated.
In R: The EACF method suggests an ARIMA(1,1,2). The auto.arima() function selects the
ARIMA(0,1,1) model that exhibits the lowest BIC value.
In SAS: the EACF method suggests an ARIMA(0,1,1) model and the BIC model selects the
ARIMA(3,1,0)
> #EACF method > library(TSA) > #use numeric object not ts object. coredata() function retrieves numeric vector > d1_ts=diff(indexts) > eacf(coredata(d1_ts)) AR/MA 0 1 2 3 4 5 6 7 8 9 10 11 12 13 0 x o o x o o o o x o o o x o 1 x o o o o o o o o o o o o o
2 x o x o o o o o o o o o x o 3 o x x o o o o o o o o o o o 4 o x x x o o o o o o o o o o 5 x o x x x o o o o o o o o o 6 x o o o x o o o o o o o o o 7 x o o o x x o o o o o o o o
> # BIC criterion > # use numeric object not ts object > auto.arima(index, max.p = 5, max.q = 5, stationary = F, ic =c("bic"), trace=TRUE, allowdrift=F) ARIMA(2,1,2) : 982.1547 ARIMA(0,1,0) : 990.837 ARIMA(1,1,0) : 985.1276 ARIMA(0,1,1) : 972.8737 ARIMA(1,1,1) : 976.1241 ARIMA(0,1,2) : 973.7256 ARIMA(1,1,2) : 979.3824 Best model: ARIMA(0,1,1) Series: index ARIMA(0,1,1) Coefficients: ma1 -0.5398 s.e. 0.0838 sigma^2 estimated as 89.26: log likelihood=-483.91 AIC=971.82 AICc=971.92 BIC=977.59
In SAS ESACF Probability Values
Lags MA 0 MA 1 MA 2 MA 3 MA 4 MA 5
AR 0 0.0011 0.0635 0.4021 0.0552 0.1309 0.8882
AR 1 <.0001 0.7810 0.3314 0.3416 0.1542 0.5998
AR 2 <.0001 0.6174 0.0018 0.7358 0.1896 0.8318
AR 3 0.4231 0.0002 0.0001 0.1756 0.6531 0.7922
AR 4 0.2412 <.0001 0.0018 0.0597 0.3335 0.6631
AR 5 <.0001 0.4323 0.0527 0.0004 0.0120 0.9065
The ARIMA Procedure
ARMA(p+d,q)
Tentative
Order
Selection
Tests
---ESACF---
p+d q
0 1
3 3
(5% Significance Level)
Name of Variable = temp
Minimum Information Criterion
Lags MA 0 MA 1 MA 2 MA 3 MA 4 MA 5
AR 0 4.588787 4.487776 4.468956 4.495152 4.505573 4.533958
AR 1 4.541124 4.523001 4.480694 4.48462 4.503237 4.540091
AR 2 4.499424 4.522147 4.516266 4.503816 4.537365 4.574281
AR 3 4.441992 4.477332 4.494755 4.527052 4.558184 4.586585
AR 4 4.477766 4.514051 4.522759 4.556779 4.577564 4.612352
AR 5 4.484678 4.521373 4.55314 4.590039 4.610067 4.637321
Error series model: AR(10)
Minimum Table Value: BIC(3,0) = 4.441992
d) Fit the selected ARIMA model, and write down the result. The ARIMA(1,1,2) model selected by the EACF method in R has non-significant parameters.
The ARIMA(3,1,0) selected by BIC method in SAS is a possible model but has higher BIC
value (details of analysis are omitted). The best model is the ARIMA(0,1,1) selected by the BIC
criterion in R and EACF in SAS.
The fitted ARIMA(0,1,1) model for the global temperature index Xt can be written as:
(1-B)Xt = (1-0.5398B)at
> m2= Arima(index, order=c(0,1,1), method='ML') > m2 Series: index ARIMA(0,1,1) Coefficients: ma1 -0.5398 s.e. 0.0838 sigma^2 estimated as 89.26: log likelihood=-483.91 AIC=971.82 AICc=971.92 BIC=977.59 > arimaPrint(m2) [1] "T-test table for model coefficients" estimates std error ma1 "-0.5397611" "0.08376795" p-values ma1 "1.167279e-10"
e) Use residual analysis to check the model. Ljung Box test on residuals shows that hypothesis of
independence cannot be rejected. So we can assume that
residuals are white noise.
The normal quantile plot shows that distribution of residuals
is close to the normal distribution.
> Box.test(m2$residuals,lag=6,type='Ljung-Box', fitdf=1)
Box-Ljung test
data: m2$residuals
X-squared = 9.5895, df = 5,
p-value = 0.08774
> Box.test(m2$residuals,lag=12,type='Ljung-Box', fitdf=1)
Box-Ljung test
data: m2$residuals
X-squared = 16.3747, df = 11,
p-value = 0.1278
f) Compute 1-step to 4-step ahead forecasts of the fitted model with origin at the end of the data, i.e. 2012. Write down the forecasts and their standard errors.
> f=forecast.Arima(m2, h=4) > plot(f, include=50) > f Point Forecast Lo 80 Hi 80 Lo 95 Hi 95 134 58.1793 46.07184 70.28676 39.66253 76.69606 135 58.1793 44.85108 71.50751 37.79555 78.56305 136 58.1793 43.73311 72.62548 36.08577 80.27283 137 58.1793 42.69566 73.66293 34.49912 81.85947
g) EXTRA CREDIT [2pts]: apply backtesting procedure to compare the following two models: ARIMA(0,1,1) and ARIMA(0,1,2). Use 113
cases (85% of data) for training and 20 cases
(or 15%) for testing.
The procedure shows that the RMSE value of
the ARIMA(0,1,1) is 9.680. While the RMSE
value for the ARIMA(0,1,2) is 9.688. The two
values are very close showing that the two
models are equivalent in terms of predictive
power. However the ARIMA(0,1,1) is slightly
better.
> backtest(m2,index,113,1) [1] "RMSE of out-of-sample forecasts" [1] 9.680175 [1] "Mean absolute error of out-of-sample forecasts" [1] 7.925004 > m3=arima(index, order=c(0,1,2)) > backtest(m3,index,113,1) [1] "RMSE of out-of-sample forecasts" [1] 9.688697 [1] "Mean absolute error of out-of-sample forecasts" [1] 7.932232 > m3 Series: x ARIMA(0,1,2) Coefficients: ma1 ma2 -0.4287 -0.1591 s.e. 0.0843 0.0764
sigma^2 estimated as 86.63: log likelihood=-481.94 AIC=967.88 AICc=968.07 BIC=976.53
In SAS: backtest needs to be modified to fit ARIMA(p,1,q) models by changing the IDENTIFY
statement in the PROC ARIMA of the BACKTEST macro as follows identify var=&VAR(1) noprint;
/*--------- backtesting --------------*/
%backtest(trainpct=85, dataset=myd, var=temp, q=1, interval=year);
%backtest(trainpct=85, dataset=myd, var=temp, q=2, interval=year);
Backtest results for myd
Model: q=(1)
Obs _TYPE_ _FREQ_ mafe msfe rmsfe
1 0 20 7.71428 87.0438 9.32973
Backtest results for myd
Model: q=2
Obs _TYPE_ _FREQ_ mafe msfe rmsfe
1 0 20 7.60769 85.3367 9.23779
R code
# Analysis of global temperature index
#1. LOAD LIBRARIES
library(tseries)
library(fBasics)
library(forecast)
#Create a time series
library(zoo)
data=read.table("globtemp.csv",header=T, sep=',')
index=data[,2]
indexts=zoo(data[,2],as.Date(as.character(data[,1]),format="%Y"))
#plot ts and acf test
plot(indexts, type='l', xlab='time', ylab='temperature index ')
#Analysis of distribution
par(mfcol=c(1,1))
hist(index, xlab="Distribution of GT Index", prob=TRUE,
main="Histogram")
# add approximating normal density curve
xfit<-seq(min(index),max(index),length=40)
yfit<-dnorm(xfit,mean=mean(index),sd=sd(index))
lines(xfit, yfit, col="blue", lwd=2)
# CREATE NORMAL PROBABILITY PLOT
qqnorm(index)
qqline(index, col = 2)
acf(coredata(indexts), plot=T, lag=20)
# Dickey Fuller test
library(fUnitRoots)
adfTest(index, lags=3, type=c("ct"))
adfTest(index, lags=5, type=c("ct"))
adfTest(index, lags=3, type=c("c"))
adfTest(index, lags=5, type=c("c"))
#Ljung - Box test
Box.test(index,lag=6,type='Ljung')
Box.test(index,lag=12,type='Ljung')
#EACF method
library(TSA)
#use numeric object not ts object. coredata() function retrieves
numeric vector
d1_ts=diff(indexts)
eacf(coredata(d1_ts))
# BIC criterion
# use numeric object not ts object
auto.arima(index, max.p = 5, max.q = 5, stationary = F, ic
=c("bic"), trace=TRUE, allowdrift=F)
# 13. MODEL FITTING
# MODEL 1:
#EACF suggests ARIMA(1,1,2) p=1 and m=2
m1= arima(index, order=c(1,1,2), method='ML')
m1
source("arimaPrint.R")
arimaPrint(m1)
# RESIDUAL ANALYSIS
Box.test(m1$residuals,lag=6,type='Ljung-Box', fitdf=1)
Box.test(m1$residuals,lag=12,type='Ljung-Box', fitdf=1)
acf(m1$residuals)
qqnorm(m1$residuals)
qqline(m1$residuals)
hist(m1$residuals)
# MODEL 2 SELECTED BY AUTOARIMA
# FIT AN ARIMA(0,1,1) MODEL
#
m2= Arima(index, order=c(0,1,1), method='ML')
m2
arimaPrint(m2)
# RESIDUAL ANALYSIS
Box.test(m2$residuals,lag=6,type='Ljung-Box', fitdf=1)
Box.test(m2$residuals,lag=12,type='Ljung-Box', fitdf=1)
acf(m2$residuals)
#Analysis of distribution
par(mfcol=c(1,1))
hist(m2$residuals, xlab="Distribution of residuals", prob=TRUE,
main="Histogram")
# add approximating normal density curve
xfit<-seq(min(m2$residuals),max(m2$residuals),length=40)
yfit<-dnorm(xfit,mean=mean(m2$residuals),sd=sd(m2$residuals))
lines(xfit, yfit, col="blue", lwd=2)
# CREATE NORMAL PROBABILITY PLOT
qqnorm(m2$residuals)
qqline(m2$residuals, col = 2)
#forecast and plot
pred=predict(m2,n.ahead=4, se.fit=T)
pred
forecast.Arima(m2, h=4)
f=forecast.Arima(m2, h=4)
plot(f, include=50)
#Backtesting
source("backtest.R")
backtest(m2,index,113,1)
m3=arima(index, order=c(0,1,2))
backtest(m3,index,113,1)
SAS code: %macro backtest(TRAINPCT=80, DATASET=, VAR=, P=, Q=, D=, DATE=date,
INTERVAL=month);
* -------------------------------------------------------------------------
;
* T I M E S E R I E S B A C K T E S T M A C R O
* -------------------------------------------------------------------------
;
* DePaul CSC425, Winter 2013, Dr. Raffaella Settimi
* Macro written by Bill Qualls, First Analytics
* -------------------------------------------------------------------------
;
* E X P L A N A T I O N O F P A R A M E T E R S
* (Order of variables is insignificant)
* -------------------------------------------------------------------------
;
* TRAINPCT .. Percent of dataset to be used for training.
* So, (100 - TRAINPCT)% will be used for evaluation.
* Example: TRAINPCT=80
* DATASET .. Time series dataset. Libname optional, defaults to Work.
* Example: DATASET=Work.Unemp
* VAR .. Name of time series variable.
* Example: VAR=ratechg
* P .. Specified for AR models. Omit otherwise.
* Example: P=(1 3 6)
* Q .. Specified for MA models. Omit otherwise.
* Example: Q=(1 3 6)
* DATE .. Name of date variable. Defaults to date.
* Example: DATE=date
* INTERVAL .. Date interval. Defaults to month.
* Example: INTERVAL=day
* -------------------------------------------------------------------------
;
* S A M P L E U S A G E
* %backtest(trainpct=80, dataset=work.unemp, var=ratedif, p=(1),
interval=day);
* -------------------------------------------------------------------------
;
* How many records are in the dataset? ;
data _null_;
call symput('NRECS', trim(left(nrecs)));
set &DATASET nobs=nrecs;
stop;
run;
* Determine which ones are exclusively for training based on TRAINPCT ;
%let SIZE_OF_ROLLING_WINDOW = %sysfunc(round(&NRECS * &TRAINPCT / 100));
* create a working copy of dataset with observation number ;
* as a variable for use in a where clause with proc arima. ;
* also add a placeholder for the predicted value. ;
data Work._MY_COPY_ (keep = &VAR &DATE _OBS_ _PRED_);
set &DATASET;
_OBS_ = _N_;
_PRED_ = .;
run;
* turn off log -- too lengthy ;
filename junk dummy;
proc printto log=junk print=junk;
run;
* Will build the model once for each record used in evaluation. ;
* Each time I will predict one record forward. ;
%let MODELS_TO_BE_BUILT = %sysevalf(&NRECS - &SIZE_OF_ROLLING_WINDOW);
%do i = 1 %to &MODELS_TO_BE_BUILT;
* Model using SIZE_OF_ROLLING_WINDOW records, and make one prediction ;
proc arima data=Work._MY_COPY_ plots=none;
where _OBS_ ge &i
and _OBS_ le (&i + &SIZE_OF_ROLLING_WINDOW - 1);
identify var=&VAR(1) noprint;
estimate
%if (&P ne ) %then %do; p=&P %end;
%if (&Q ne ) %then %do; q=&Q %end;
method=ml noprint;
forecast lead=1 id=&DATE interval=&INTERVAL out=Work._MY_RESULTS_
noprint;
run;
* get the predicted value (in the last record) as a macro variable ;
data _null_;
p = nrecs;
set Work._MY_RESULTS_ point=p nobs=nrecs;
call symput("FORECAST", forecast);
stop;
run;
* move that prediction to its place in the output file ;
proc sql noprint;
update Work._MY_COPY_
set _PRED_ = &FORECAST
where _OBS_ = &i + &SIZE_OF_ROLLING_WINDOW;
quit;
run;
* show progress so far ;
%if (%sysfunc(mod(&i, 5)) = 0) %then %do;
* print on;
proc printto log=log print=print;
run;
%put Finished &i iterations;
* print off again;
proc printto log=junk print=junk;
run;
%end;
%end;
* turn print back on ;
proc printto log=log print=print;
run;
* calculate prediction error;
data Work._MY_COPY_;
set Work._MY_COPY_;
Predicted_Error = (&VAR - _PRED_) ;
Predicted_Error_Squared = (&VAR - _PRED_)**2;
absresidual = abs(Predicted_Error);
run;
* compute and report the mean square forecast error;
%if (&P eq ) %then %let PP = ; %else %let PP = p=&P;
%if (&Q eq ) %then %let QQ = ; %else %let QQ = q=&Q;
title "Backtest results for &DATASET";
title2 "Model: &PP &QQ";
proc summary data=Work._MY_COPY_;
where _OBS_ > &SIZE_OF_ROLLING_WINDOW;
var Predicted_Error absresidual;
output out=outm mean(absresidual)=mafe mean(Predicted_Error_Squared)=msfe;
run;
data outm;
set outm;
rmsfe=sqrt(msfe);
run;
proc print data=outm;
run;
/*
proc means data=Work._MY_COPY_ N MEAN STDDEV CLM T PROBT;
where _OBS_ > &SIZE_OF_ROLLING_WINDOW;
var Predicted_Error_Squared;
run;
title;
*/
%mend backtest;
/*-------------------------------------------------*/
proc import datafile="globtemp.csv" out=myd replace;
delimiter=',';
getnames=yes;
run;
proc print data=myd;
run;
* produced time plots;
goptions reset=global;
symbol interpol = join value=star;
proc gplot data=myd;
plot temp*year / haxis = 1880 to 2012 by 10;
run;
quit;
goptions reset = global;
proc univariate data=myd;
var temp;
histogram / normal;
qqplot / normal(mu=est sigma=est);
run;
* compute Dickey-Fuller unit-root tests;
proc arima data=myd;
identify var = temp stationarity = (adf=(1 3 5));
identify var = temp(1) stationarity = (adf=(1 3 5));
run;
proc arima data=myd;
identify var = temp esacf q=(0:5) p=(0:5) nlag =20;
identify var = temp minic q=(0:5) p=(0:5) nlag =20;
run; quit;
/* fit models from step above */
* fit ARIMA(p,1,q) models for unemployment rates;
* note that model intercept is set =0 using the noconstant option;
proc arima data=myd;
identify var = temp(1) noprint;
estimate p=0 q=1 method=ml plot noconstant;
estimate p=3 q=0 method=ml plot noconstant;
run;
quit;
proc arima data=myd;
identify var=temp(1) noprint;
estimate p=0 q=1 method=ml plot noconstant;
forecast back=0 lead=4 printall out=result id=year interval=day;
run;
quit;
/* Analysis of residuals*/
/* Residual plot: residual vs time*/
goptions reset=global;
symbol i=join;
proc gplot data=result;
plot residual*year / haxis = 1880 to 2012 by 10;
run;
quit;
/*analysis of distribution of residuals, to check
for normality */
goptions reset=global;
proc univariate data=result;
var residual;
histogram/normal (mu=est sigma=est);
qqplot/normal(mu=est sigma=est);
run;
goptions reset=global;
symbol1 interpol =join value=star color=red w=2;
symbol2 interpol = join color=black;
symbol3 interpol = join value=none color = blue;
symbol4 interpol = join value=none color = blue;
legend1 label=none
shape=symbol(4,2)
position=(top center inside)
mode=share;
proc gplot data=result;
plot forecast*year temp*year u95*year l95*year / overlay
haxis = 1880 to 2022 by 10 legend=legend1;
run;
/*--------- backtesting --------------*/
%backtest(trainpct=85, dataset=myd, var=temp, q=(1), interval=year);
%backtest(trainpct=85, dataset=myd, var=temp, q= 2, interval=year);