Data 624 HW6

library(knitr)
library(rmdformats)

## Global options
options(max.print="31")
opts_chunk$set(cache=TRUE,
               prompt=FALSE,
               tidy=TRUE,
               comment=NA,
               message=FALSE,
               warning=FALSE)
opts_knit$set(width=31)

library(forecast)
## Registered S3 method overwritten by 'quantmod':
##   method            from
##   as.zoo.data.frame zoo
library(fma)
library(expsmooth)
library(urca)
library(tseries)
library(ggplot2)
library(graphics)
library(fpp2)

Exercise 8.11.1

Figure 8.31 shows the ACFs for 36 random numbers, 360 random numbers and 1,000 random numbers.

a. Explain the differences among these figures. Do they all indicate that the data are white noise?

Ans: As sample size increases from 36 to 360 to 1000, we expect the corresponding ACFs to shrink to approach 0. That’s what we observed, i.e., the regions banding the y = 0 are getting narrower. As we don’t see more than 5% of the T values portend beyond the blue dotted lines, I rule that the data are white noise.

b. Why are the critical values at different distances from the mean of zero? Why are the autocorrelations different in each figure when they each refer to white noise?

The critical values resulted at different distances from the mean of zero as there are random autocorrelations with positive magnitude or negative magnitude. By the sheer definition of white noises, the autocorrelations from 3 independently chosen sets of random numbers should exhibit an expected level of randomness in autocorrelations.

Exercise 8.11.2

A classic example of a non-stationary series is the daily closing IBM stock price series (data set ibmclose). Use R to plot the daily closing prices for IBM stock and the ACF and PACF. Explain how each plot shows that the series is non-stationary and should be differenced.

Ans: From the ACF plot, we can tell this time series is a non-stationary ts. It decreases slowly and it doesn’t drop to zero quickly. PACF plot does show there is definitely need for an ordinary differencing at lag 1. Namely, there is a high correlation between t and t - 1, or lag 1.

ggtsdisplay(ibmclose)

Exercise 8.11.3

For the following series, find an appropriate Box-Cox transformation and order of differencing in order to obtain stationary data.

a. usnetelec

Transformations such as logarithms can help to stabilize the variance of a time series. Differencing can help stabilize the mean of a time series by removing changes in the level of a time series, and therefore eliminating (or reducing) trend and seasonality. And that’s the requisite for obtaining stationary data.

We’re going to use Unit root test as it is a statistical hypothesis test of stationarity that is designed for determining whether differencing is required.

ggtsdisplay(usnetelec, main = "Annual US Net Electricity Generation", ylab = "Billion kWh", 
    xlab = "Year")

First off, there is no BoxCox transformations needed as there is no apparent increasing or decreasing variation in the time series.

Next, we check to see if we need any sort of differncing.

# Number of differences required for a stationary series
ndiffs(usnetelec)
[1] 1
# Number of differences required for a seasonally stationary series
# options(on.error.just.continue.the.next.line) = TRUE usnetelec %>%
# try(nsdiffs(),silent=T) nsdiffs(usnetelec) Error in nsdiffs(usnetelec) : Non
# seasonal data

Ans: As there is no evident seasonality seen in this ts, seasonal differencing is not required.

usnetelec %>% diff %>% ur.kpss %>% summary

####################### 
# KPSS Unit Root Test # 
####################### 

Test is of type: mu with 3 lags. 

Value of test-statistic is: 0.1585 

Critical value for a significance level of: 
                10pct  5pct 2.5pct  1pct
critical values 0.347 0.463  0.574 0.739

As you can text the test-statistic is not in the critical region, we fail to reject the null hypothesis. Meaning we ordinary differencing (or differences at lag 1) is sufficient to obtain stationary data, which is the objective of this exercise.

b. usgdp

ggtsdisplay(usgdp, main = "Quarterly US GDP", ylab = "GDP", xlab = "Year")

print(BoxCox.lambda(usgdp))
[1] 0.366352
usgdp.bc = BoxCox(usgdp, BoxCox.lambda(usgdp))
autoplot(usgdp.bc, main = "Quarterly US GDP (BoxCox transformed)")

Ans: It seems an appropriate lambda for the BoxCox transformation is .37. And there seems to be a demonstrated effect on the ts after the BoxCox transformation. It smooths out the variation. Next we try to determine if we need any differencing.

ggtsdisplay(usgdp.bc)

# Number of differences required for a stationary series
ndiffs(usgdp.bc)
[1] 1
# Number of differences required for a seasonally stationary series
nsdiffs(usgdp.bc)
[1] 0

Both ndiffs and the PACF show that we need a first difference, or ordinary differencing. On the other hand, there is no seasonal differencing needed as indicated in the results of nsdiffs( ).

# KPSS Unit Root Test to test if we have stationary data
usgdp.bc %>% diff %>% ur.kpss %>% summary

####################### 
# KPSS Unit Root Test # 
####################### 

Test is of type: mu with 4 lags. 

Value of test-statistic is: 0.2013 

Critical value for a significance level of: 
                10pct  5pct 2.5pct  1pct
critical values 0.347 0.463  0.574 0.739

The test-statistic .2013 doesn’t fall in the critical region. Thus, we fail to reject the null hypothesis. Meaning, we achieved stationarity with merely first difference.

c. mcopper

ggtsdisplay(mcopper, main = "Monthly Copper Prices", ylab = "Price", xlab = "Year")

Ans: To begin, this ts is a non-stationary ts as you do see there is an apparent upward trend since around 2003.

print(BoxCox.lambda(mcopper))
[1] 0.1919047
mcopper.bc = BoxCox(mcopper, BoxCox.lambda(mcopper))
autoplot(mcopper.bc, main = "Monthly Copper Prices (BoxCox transformed)")

ggtsdisplay(mcopper.bc)

The lambda .19 from the BoxCox transformation did have an effect on the time series. You see that the slope of the decrease in the ACF plot has been smoothed out. As a result, the ACF is more like a straight line. That is the exact intention of BoxCox transformation.

# Number of differences required for a stationary series
ndiffs(mcopper.bc)
[1] 1
# Number of differences required for a seasonally stationary series
nsdiffs(mcopper.bc)
[1] 0

The results from ndiffs and PACF did signify that we need an ordinary difference of the ts. Since the result of the KPSS Unit Root Test rejects the null hypothesis at alpha level .05, we need to check with adf.test() to make sure we do not attain false positive, or Type I Error.

Reference: https://www.statisticshowto.com/kpss-test/

# KPSS Unit Root Test to test if we have stationary data

mcopper.bc %>% diff %>% ur.kpss %>% summary

# KPSS Unit Root Test to test if we have stationary data
mcopper.bc %>% diff %>% ur.kpss %>% summary

####################### 
# KPSS Unit Root Test # 
####################### 

Test is of type: mu with 6 lags. 

Value of test-statistic is: 0.0573 

Critical value for a significance level of: 
                10pct  5pct 2.5pct  1pct
critical values 0.347 0.463  0.574 0.739
mcopper.bc %>% diff %>% adf.test

    Augmented Dickey-Fuller Test

data:  .
Dickey-Fuller = -8.2555, Lag order = 8, p-value = 0.01
alternative hypothesis: stationary

As p-value from the Augmented Dickey-Fuller (Adf) Test is .01, we have convincing evidence to reject the null hypothesis at .05. So what this means we still do not have stationary data.

# 2 rounds of differencing, at lag 1 and lag 2.
mcopper.bc %>% diff %>% diff(lag = 2) %>% ur.kpss %>% summary

####################### 
# KPSS Unit Root Test # 
####################### 

Test is of type: mu with 6 lags. 

Value of test-statistic is: 0.0148 

Critical value for a significance level of: 
                10pct  5pct 2.5pct  1pct
critical values 0.347 0.463  0.574 0.739

In order to achieve stationarity, we need to do an additional differencing at lag 2, i.e. First difference and Second difference (at lag 2, t - 2) in combination. Now we have stationary data as the test-statistic is no longer in the critical region.

d. enplanements

ggtsdisplay(enplanements, main = "Monthly US Domestic Enplanements", ylab = "million", 
    xlab = "Year")

Ans: I don’t think BoxCox transformation is needed for this ts. It barely registered any effects in the ACF plot as well as in the time series itself. Lambda was at -.23. But I insist that no BoxCox transformation is needed.

print(BoxCox.lambda(enplanements))
[1] -0.2269461
enplanements.bc = BoxCox(enplanements, BoxCox.lambda(enplanements))
autoplot(enplanements.bc, main = "Monthly US Domestic Enplanements (BoxCox transformed)")

ggtsdisplay(enplanements.bc, main = "Monthly US Domestic Enplanements", ylab = "million", 
    xlab = "Year")

Next we are supposed to find the most appropriate method of differencing.

# Number of differences required for a stationary series
ndiffs(enplanements)
[1] 1
# Number of differences required for a seasonally stationary series
nsdiffs(enplanements)
[1] 1

We found that we need 2 differencing. One at lag 1 as seen in PACF plot

enplanements %>% diff(lag = frequency(enplanements)) %>% ggtsdisplay()

# KPSS Unit Root Test to test if we have stationary data
enplanements %>% diff %>% ur.kpss %>% summary

####################### 
# KPSS Unit Root Test # 
####################### 

Test is of type: mu with 5 lags. 

Value of test-statistic is: 0.0086 

Critical value for a significance level of: 
                10pct  5pct 2.5pct  1pct
critical values 0.347 0.463  0.574 0.739

Even tho’ the nsdiffs results came back suggesting we do a seasonal differencing, I don’t think it’s absolutely required after seeing KPSS Unit Root Test results that we have a confirmation that we are not going to reject the null hypothesis and test-statistics does not fall into the critical region. Meaning we already attained a stationary ts after a first-order ordinary differencing.

e. visitors

ggtsdisplay(visitors, main = "Monthly Australian Short-Term Overseas Vistors", ylab = "Visitors in Thousands", 
    xlab = "Year")

print(BoxCox.lambda(visitors))
[1] 0.2775249
visitors.bc = BoxCox(visitors, BoxCox.lambda(visitors))
autoplot(visitors.bc, main = "Monthly Australian Short-Term Overseas Vistors (BoxCox transformed)")

ggtsdisplay(visitors.bc, main = "Monthly Australian Short-Term Overseas Vistors", 
    ylab = "Visitors in Thousands", xlab = "Year")

Ans: This time series after BoxCox transformation is very much like the original ts. I don’t see major differences between the 2 ACFs (before and after) the transformation. I am not convinced that a BoxCox transformation is needed. Lambda from the BoxCox transformation was at .28.

# Number of differences required for a stationary series
ndiffs(visitors)
[1] 1
# Number of differences required for a seasonally stationary series
nsdiffs(visitors)
[1] 1

PACF plot tells me lag at 1, 13, and lag at 12.

# KPSS Unit Root Test to test if we have stationary data
visitors %>% diff %>% ur.kpss %>% summary

####################### 
# KPSS Unit Root Test # 
####################### 

Test is of type: mu with 4 lags. 

Value of test-statistic is: 0.0191 

Critical value for a significance level of: 
                10pct  5pct 2.5pct  1pct
critical values 0.347 0.463  0.574 0.739

The KPSS Unit Root Test results tells me that test-statistic is not in critical region. Thus we have a stationary ts already with just first-order ordinary differencing. We can skip the seasonal differencing.

Exercise 8.11.5

For your retail data (from Exercise 3 in Section 2.10), find the appropriate order of differencing (after transformation if necessary) to obtain stationary data.

retaildata <- readxl::read_excel("/Users/dpong/Data624/Presentation/retail.xlsx", 
    skip = 1)
myts <- ts(retaildata[, "A3349398A"], frequency = 12, start = c(1982, 4))
autoplot(myts) + ylab("Retail Food Sales") + ggtitle("New South Wales - Food Sales")

myts %>% ggtsdisplay()

print(BoxCox.lambda(myts))
[1] 0.1231563
myts.bc = BoxCox(myts, BoxCox.lambda(myts))
autoplot(myts.bc, main = "New South Wales - Food Sales (BoxCox transformed)")

The BoxCox transformation with a low-value lambda (λ=0.12) reduces the variations in the ts data.

# Number of differences required for a stationary series
ndiffs(myts.bc)
[1] 1
# Number of differences required for a seasonally stationary series
nsdiffs(myts.bc)
[1] 1
# KPSS Unit Root Test to test if we have stationary data
myts.bc %>% diff %>% ur.kpss %>% summary

####################### 
# KPSS Unit Root Test # 
####################### 

Test is of type: mu with 5 lags. 

Value of test-statistic is: 0.0117 

Critical value for a significance level of: 
                10pct  5pct 2.5pct  1pct
critical values 0.347 0.463  0.574 0.739

The results of the test tells me that we have a test-statistic that is not in the critical region. The hypothesis test fails to rejecdt its null hypothesis. Meaning we do have a stationary ts merely after first-order ordinary differencing.

Exercise 8.11.6

Use R to simulate and plot some data from simple ARIMA models.

a. Use the following R code to generate data from an AR(1) model with \(\phi_1\)=0.6 and \(\sigma^2\)=1. The process starts with \(y_1\)=0.

y <- ts(numeric(100))
e <- rnorm(100)
for (i in 2:100) y[i] <- 0.6 * y[i - 1] + e[i]

b. Produce a time plot for the series. How does the plot change as you change \(\phi_1\)?

seed = 3098
generate_ts <- function(n, phi) {
    set.seed(seed)
    y <- ts(numeric(n))
    e <- rnorm(n)
    for (i in 2:n) y[i] <- phi * y[i - 1] + e[i]
    return(y)
}


autoplot(generate_ts(n = 100, phi = 0.6), ylim = c(-3, 4), series = "4. Phi=.60", 
    main = "Let's look at the time series generated with phi between 0 and .60") + 
    # autolayer(generate_ts(n=100, phi=0.75), series='Phi=0.75') +
# autolayer(generate_ts(n=100, phi=0.99), series='Phi=0.99') +
autolayer(generate_ts(n = 100, phi = 0.45), series = "3. Phi=0.45") + autolayer(generate_ts(n = 100, 
    phi = 0.2), series = "2. Phi=0.20") + autolayer(generate_ts(n = 100, phi = 0), 
    series = "1. Phi=0")

autoplot(generate_ts(n = 100, phi = 0.6), ylim = c(-7, 3), series = "4. Phi=.60", 
    main = "Let's look at the time series generated with phi between 0.60 and .99") + 
    autolayer(generate_ts(n = 100, phi = 0.75), series = "5. Phi=0.75") + autolayer(generate_ts(n = 100, 
    phi = 0.99), series = "6. Phi=0.99")

# autolayer(generate_ts(n=100, phi=0.45), series='3. Phi=0.45') +
# autolayer(generate_ts(n=100, phi=0.20), series='2. Phi=0.20') +
# autolayer(generate_ts(n=100, phi=0), series='1. Phi=0')

Ans: As \(\phi_1\) changes and within the range of 0 and .75, one can tell the ts oscillates and but trends very similarly to each of the time series generated with n = 100. With the exception of when \(\phi_1 \cong 1\), that’s when the generated ts becomes a random walk where you can’t predict whether T = t+1 is going up or going down. In other words, the time plot itself became unpredictable and dissimilar to the rest of the time plots for any other values of \(\phi_1\)’s.

c. Write your own code to generate data from an MA(1) model with θ1=0.6 and σ2=1.

Ans: MA(1) = \(y_t=c+ϵ_t+θ_{1}ϵ_{t−1}\)

seed <- 318
ma.1 <- function(n, theta, c, sigma) {
    set.seed(seed)
    y = ts(numeric(n))
    e = rnorm(n, sigma)
    for (i in 2:n) y[i] = c + e[i] + theta * e[i - 1]
    return(y)
}
autoplot(ma.1(100, 0.6, 0, 1))

d. Produce a time plot for the series. How does the plot change as you change θ1?

For -1 < θ1 < 1,

autoplot(ma.1(n = 100, theta = 0.6, c = 0, sigma = 1), ylim = c(-2, 4), series = "4. Theta=.60", 
    main = "Let's look at the time series generated with theta between -.45 and .60") + 
    autolayer(ma.1(n = 100, theta = 0.15, c = 0, sigma = 1), series = "3. Theta=.15") + 
    autolayer(ma.1(n = 100, theta = 0, c = 0, sigma = 1), series = "2. Theta=0") + 
    autolayer(ma.1(n = 100, theta = -0.45, c = 0, sigma = 1), series = "1. Theta=-.45")

autoplot(ma.1(n = 100, theta = 0.6, c = 0, sigma = 1), ylim = c(-2, 4), series = "4. Theta=.60", 
    main = "Let's look at the time series generated with theta between .60 and .99") + 
    autolayer(ma.1(n = 100, theta = 0.75, c = 0, sigma = 1), series = "3. Theta=.75") + 
    autolayer(ma.1(n = 100, theta = 0.99, c = 0, sigma = 1), series = "2. Theta=0.99")

ma.1(n = 100, theta = 0, c = 0, sigma = 1) %>% ggtsdisplay(main = "theta = 0")

ma.1(n = 100, theta = 0.15, c = 0, sigma = 1) %>% ggtsdisplay(main = "theta = 0.15")

ma.1(n = 100, theta = 0.6, c = 0, sigma = 1) %>% ggtsdisplay(main = "theta = 0.60")

ma.1(n = 100, theta = -0.45, c = 0, sigma = 1) %>% ggtsdisplay(main = "theta = -0.45")

Ans: The effect of theta as displayed in the graphs above is that it tames the autocorrelations (the spikes) within the ACF and PACF plots. The closer the theta is to 0, the smaller the spikes you can see in those 2 plots. Vice versa. On the other hand, I don’t see there are any detectable effects on the time plots themselves basing just on the variations of theta’s.

e. Generate data from an ARMA(1,1) model with ϕ1=0.6, θ1=0.6 and σ2=1.

seed <- 398
ARMA.1.1 <- function(n, phi, theta, c, sigma) {
    set.seed(seed)
    y <- ts(numeric(n))
    e <- rnorm(n, sigma)
    for (i in 2:n) y[i] <- c + phi * y[i - 1] + theta * e[i - 1] + e[i]
    return(y)
}
autoplot(ARMA.1.1(100, 0.6, 0.6, 0, 1), main = "ARMA(1,1)")

f. Generate data from an AR(2) model with ϕ1=−0.8, ϕ2=0.3 and σ2=1. (Note that these parameters will give a non-stationary series.)

set.seed(301)
phi_1 = -0.8
phi_2 = 0.3
sigma = 1
y2 = ts(numeric(100))
e = rnorm(100, sigma)
for (i in 3:100) y2[i] = phi_1 * y2[i - 1] + phi_2 * y2[i - 2] + e[i]

plot_y2 = autoplot(y2) + labs(title = expression(paste("AR(2): ", phi[1], "= -0.8, ", 
    phi[2], "= 0.3")))
acf_y2 = ggAcf(y2)
gridExtra::grid.arrange(plot_y2, acf_y2, ncol = 2)

g. Graph the latter two series and compare them.

ggtsdisplay(ARMA.1.1(100, 0.6, 0.6, 0, 1), main = "ARMA(1,1): phi[1] = 0.6, theta[1] = 0.6")

ggtsdisplay(y2, main = "AR(2): phi[1] = -0.8, phi[2] = 0.3")

Ans:

AR(1,1) is a white noise as its 95% ACF spikes lie within the dotted blue lines.

AR(2) has an oscillating time plot where there is an increase in the variations at time increases. Because of the two phi’s are of opposite signs, the ACF plot does show autocorrelations of alternate signs lag after lag.

Both series have an ACF plot that is decreasing in autocorrelations as lag increases.

Exercise 8.11.7

Consider wmurders, the number of women murdered each year (per 100,000 standard population) in the United States.

a. By studying appropriate graphs of the series in R, find an appropriate ARIMA(p,d,q) model for these data.

ggtsdisplay(wmurders, main = "Total Murdered Women", ylab = "Unit: 100K")

Ans:

An ARIMA model is defined by,

  • p, the order of autoregression (y regressed on previous values)

  • d, differencing required for stationarity

  • q, the order of the moving average component

First off, do we need any transformations of the time plot? No. We do not. As we don’t see apparent seasonal variations of the time plot, we decide not to pursue any transformations of the series.

To determine the order of differencing, we use ndiffs and nsdiffs().

# Number of differences required for a stationary series
ndiffs(wmurders)
[1] 2
# Number of differences required for a seasonally stationary series
# nsdiffs(wmurders) Non seasonal data.

There is no seasonal differencing needed as this ts is a non-seasonal data.

ur.kpss(diff(wmurders, differences = 2)) %>% summary

####################### 
# KPSS Unit Root Test # 
####################### 

Test is of type: mu with 3 lags. 

Value of test-statistic is: 0.0458 

Critical value for a significance level of: 
                10pct  5pct 2.5pct  1pct
critical values 0.347 0.463  0.574 0.739

At significance level of .05, we do not reject the null hypothesis so the series is stationary.

To determine the parameter value of p, the autoregressive term, we look at the PACF plot of the differenced series.

ggPacf(diff(wmurders, differences = 2))

It has a significant spike at lag 1, so p = 1.

To determine the parameter value q, the order of moving average, we look at the ACF plot of the differenced series.

ggAcf(diff(wmurders, differences = 2))

The major spike was at lag = 1, so we use q = 1. We can also try q = 2.

Here are the candidates to check:

ARIMA(1,2,1)

ARIMA(1,2,2)

ARIMA(1,2,0)

ARIMA(0,2,1)

ARIMA(0,2,2)

ARIMA(0,2,0)

ARIMA(2,2,1)

ARIMA(2,2,0)

ARIMA(2,2,2)

Arima(wmurders, order = c(1, 2, 1))
Series: wmurders 
ARIMA(1,2,1) 

Coefficients:
          ar1      ma1
      -0.2434  -0.8261
s.e.   0.1553   0.1143

sigma^2 estimated as 0.04632:  log likelihood=6.44
AIC=-6.88   AICc=-6.39   BIC=-0.97
Arima(wmurders, order = c(1, 2, 2))
Series: wmurders 
ARIMA(1,2,2) 

Coefficients:
          ar1      ma1      ma2
      -0.7677  -0.2812  -0.4977
s.e.   0.2351   0.2879   0.2762

sigma^2 estimated as 0.04552:  log likelihood=7.38
AIC=-6.75   AICc=-5.92   BIC=1.13
Arima(wmurders, order = c(1, 2, 0))
Series: wmurders 
ARIMA(1,2,0) 

Coefficients:
          ar1
      -0.6719
s.e.   0.0981

sigma^2 estimated as 0.05471:  log likelihood=2
AIC=0   AICc=0.24   BIC=3.94
Arima(wmurders, order = c(0, 2, 1))
Series: wmurders 
ARIMA(0,2,1) 

Coefficients:
          ma1
      -0.8995
s.e.   0.0669

sigma^2 estimated as 0.04747:  log likelihood=5.24
AIC=-6.48   AICc=-6.24   BIC=-2.54
Arima(wmurders, order = c(0, 2, 2))
Series: wmurders 
ARIMA(0,2,2) 

Coefficients:
          ma1     ma2
      -1.0181  0.1470
s.e.   0.1220  0.1156

sigma^2 estimated as 0.04702:  log likelihood=6.03
AIC=-6.06   AICc=-5.57   BIC=-0.15
Arima(wmurders, order = c(0, 2, 0))
Series: wmurders 
ARIMA(0,2,0) 

sigma^2 estimated as 0.1007:  log likelihood=-14.38
AIC=30.76   AICc=30.84   BIC=32.73
Arima(wmurders, order = c(2, 2, 1))
Series: wmurders 
ARIMA(2,2,1) 

Coefficients:
          ar1     ar2      ma1
      -0.1247  0.2348  -0.9082
s.e.   0.1612  0.1560   0.0866

sigma^2 estimated as 0.04518:  log likelihood=7.56
AIC=-7.12   AICc=-6.28   BIC=0.76
Arima(wmurders, order = c(2, 2, 0))
Series: wmurders 
ARIMA(2,2,0) 

Coefficients:
          ar1      ar2
      -0.8289  -0.2246
s.e.   0.1346   0.1353

sigma^2 estimated as 0.05292:  log likelihood=3.34
AIC=-0.68   AICc=-0.19   BIC=5.23
Arima(wmurders, order = c(2, 2, 2))
Series: wmurders 
ARIMA(2,2,2) 

Coefficients:
          ar1     ar2      ma1      ma2
      -0.3200  0.1947  -0.7027  -0.1776
s.e.   0.5955  0.2161   0.6030   0.5090

sigma^2 estimated as 0.04597:  log likelihood=7.63
AIC=-5.26   AICc=-3.98   BIC=4.59

The final ARIMA model to pick is ARIMA(2,2,0).

b. Should you include a constant in the model? Explain.

Given that d=2, a positive non-zero constant would give forecasts a quadratic trend, which is undesirable in this case.

c. Write this model in terms of the backshift operator.

For ARIMA(2,2,0), p = 2, d = 2, q = 0

according formula 8.2, we have

(1−ϕ1B-ϕ2B2)(1−B)2ytt

d. Fit the model using R and examine the residuals. Is the model satisfactory?

(fit = Arima(wmurders, order = c(2, 2, 0)))
Series: wmurders 
ARIMA(2,2,0) 

Coefficients:
          ar1      ar2
      -0.8289  -0.2246
s.e.   0.1346   0.1353

sigma^2 estimated as 0.05292:  log likelihood=3.34
AIC=-0.68   AICc=-0.19   BIC=5.23
checkresiduals(fit)


    Ljung-Box test

data:  Residuals from ARIMA(2,2,0)
Q* = 21.05, df = 8, p-value = 0.007015

Model df: 2.   Total lags used: 10

Ans: The distributions of residuals look okay normal. I think it’s satisfactory.

e. Forecast three times ahead. Check your forecasts by hand to make sure that you know how they have been calculated.

f3 <- forecast(fit, h = 3)
f3
     Point Forecast    Lo 80    Hi 80    Lo 95    Hi 95
2005       2.381222 2.086401 2.676043 1.930333 2.832112
2006       2.271154 1.817137 2.725171 1.576795 2.965513
2007       2.110176 1.410744 2.809609 1.040487 3.179866

The formula for ARIMA(2,2,0) is:

\(y_{t}^{''} = c + \phi_1 y_{t-1}^{''} + \phi_2 y_{t-2}^{''} + \epsilon_t\)

Or alternatively, using the B notation and knowing that c = 0, we have

$$ \[\begin{multline*} \begin{split} (1 - \phi_1B - \phi_2B^2)(1-B)^2y_t &= \epsilon_t \\ (1 - \phi_1B - \phi_2B^2)(1-2B-B^2)y_t &= \epsilon_t \\ y_t-2y_{t-1}+y_{t-2}-\phi_1y_{t-1}+2\phi_1y_{t-2}-\phi_1y_{t-3}-\phi_2y_{t-2}+2\phi_2y_{t-3}-\phi_2y_{t-4} &=\epsilon_{t} \\ y_t = (2+\phi_1)y_{t-1} + (-1+\phi_2-2\phi_1)y_{t-2}+(\phi_1-2\phi_2)y_{t-3}+\phi_2y_{t-4}+\epsilon_{t} \end{split} \end{multline*}\] $$

So yT+1 denoted as yt_h1 in the R code block below.

yT+2 denoted as yt_h2

yT+3 denoted as yt_h3

res <- resid(fit)
len <- length(res)

phi1 <- coef(fit)["ar1"]
phi2 <- coef(fit)["ar2"]
yt_h1 <- (2 + phi1) * wmurders[length(wmurders)] + (-1 + phi2 - 2 * phi1) * wmurders[length(wmurders) - 
    1] + (phi1 - 2 * phi2) * wmurders[length(wmurders) - 2] + phi2 * wmurders[length(wmurders) - 
    3]
names(yt_h1) <- "yt_h1"
yt_h1
   yt_h1 
2.381222 
yt_h2 <- (2 + phi1) * yt_h1 + (-1 + phi2 - 2 * phi1) * wmurders[length(wmurders)] + 
    (phi1 - 2 * phi2) * wmurders[length(wmurders) - 1] + phi2 * wmurders[length(wmurders) - 
    2]
names(yt_h2) <- "yt_h2"
yt_h2
   yt_h2 
2.271154 
yt_h3 <- (2 + phi1) * yt_h2 + (-1 + phi2 - 2 * phi1) * yt_h1 + (phi1 - 2 * phi2) * 
    wmurders[length(wmurders)] + phi2 * wmurders[length(wmurders) - 1]
names(yt_h3) <- "yt_h3"
yt_h3
   yt_h3 
2.110176 

The results above matched exactly with the ones in the forecast (f3).

f. Create a plot of the series with forecasts and prediction intervals for the next three periods shown.

autoplot(forecast(fit, h = 3), PI = TRUE)

g. Does auto.arima() give the same model you have chosen? If not, which model do you think is better?

(fit2 = auto.arima(wmurders, stepwise = TRUE, seasonal = FALSE))
Series: wmurders 
ARIMA(1,2,1) 

Coefficients:
          ar1      ma1
      -0.2434  -0.8261
s.e.   0.1553   0.1143

sigma^2 estimated as 0.04632:  log likelihood=6.44
AIC=-6.88   AICc=-6.39   BIC=-0.97

Ans: The auto.arima() doesn’t give me the same model as it picked ARIMA(1,2,1) instead of ARIMA(2,2,0) that I had.

When comparing the metric corrected AIC, namely AICc, my handpicked model was better, with

AICc=-0.19

Let me know if you think otherwise.