### R Environment
# Clear the workspace
rm(list = ls()) # Clear environment
gc() # Clear unused memory
## used (Mb) gc trigger (Mb) limit (Mb) max used (Mb)
## Ncells 519613 27.8 1149965 61.5 NA 669285 35.8
## Vcells 955384 7.3 8388608 64.0 16384 1840107 14.1
cat("\f") # Clear the console
dev.off # Clear the charts
## function (which = dev.cur())
## {
## if (which == 1)
## stop("cannot shut down device 1 (the null device)")
## .External(C_devoff, as.integer(which))
## dev.cur()
## }
## <bytecode: 0x7fedf6a7aec8>
## <environment: namespace:grDevices>
#make vector containing the packages
packages <- c("ggplot2",
"knitr",
"fpp3",
"forecast",
"dplyr",
"fable")
#Install packages
for (i in 1:length(packages)) {# Iterate through each package in the 'packages' vector.
if (!packages[i] %in% rownames(installed.packages())) {#check if package is installed
install.packages(packages[i], #install package if it isn't already
repos = "http://cran.rstudio.com/",
dependencies = TRUE)}
library(packages[i], character.only = TRUE)} # Load the package into the R session.
## ── Attaching packages ────────────────────────────────────────────── fpp3 0.5 ──
## ✔ tibble 3.2.1 ✔ tsibbledata 0.4.1
## ✔ dplyr 1.1.1 ✔ feasts 0.3.2
## ✔ tidyr 1.3.0 ✔ fable 0.3.3
## ✔ lubridate 1.9.2 ✔ fabletools 0.4.1
## ✔ tsibble 1.1.4
## ── Conflicts ───────────────────────────────────────────────── fpp3_conflicts ──
## ✖ lubridate::date() masks base::date()
## ✖ dplyr::filter() masks stats::filter()
## ✖ tsibble::intersect() masks base::intersect()
## ✖ tsibble::interval() masks lubridate::interval()
## ✖ dplyr::lag() masks stats::lag()
## ✖ tsibble::setdiff() masks base::setdiff()
## ✖ tsibble::union() masks base::union()
## Registered S3 method overwritten by 'quantmod':
## method from
## as.zoo.data.frame zoo
# Remove unnecessary values from environment
rm(i,packages)
### Data
# Import the data
IR <- read.csv("/Users/cam/Desktop/PREDICTIVE ANALYTICS/Discussions/Data/10YR_IR.csv")
# Adjust variable formats where necessary
IR$DATE <- as.Date(IR$DATE, format = "%m/%d/%y")
IR <- IR %>%
rename(RATE = REAINTRATREARAT10Y)
## Separate into training and testing data
# Training
IR_ts <- subset(IR, DATE <= max(IR$DATE) - months(6))
# testing data
IR_test <- subset(IR, DATE > max(IR$DATE) - months(6))
# Convert to time series
IR_ts <- ts(IR_ts$RATE,
start = c(2014,3),
frequency = 12
)
IR_test <- ts(IR_test$RATE,
start = c(2023,10),
frequency = 12
)
Source: FRED - 10YR IR
The dataset used in this discussion comes from FRED and contains monthly data for the past 10 years.
# Show summary stats
summary(IR)
## DATE RATE
## Min. :2014-03-01 Min. :-0.4071
## 1st Qu.:2016-09-01 1st Qu.: 0.3466
## Median :2019-03-01 Median : 0.6245
## Mean :2019-03-02 Mean : 0.6884
## 3rd Qu.:2021-09-01 3rd Qu.: 1.0606
## Max. :2024-03-01 Max. : 2.0943
#Show head of table
head(IR)
## DATE RATE
## 1 2014-03-01 0.5804532
## 2 2014-04-01 0.7022221
## 3 2014-05-01 0.6268541
## 4 2014-06-01 0.6245294
## 5 2014-07-01 0.5909950
## 6 2014-08-01 0.6494057
# Show plot of data
ggplot(IR, aes(x = DATE, y = RATE)) +
geom_line() +
labs(x = "Date",
y = "Real Interest Rate (%)",
title = "10-Year Real Interest Rate")
# Create Arima model
arima_mod <- auto.arima(IR_ts)
# forecast arima model
arima_forecast <- forecast(arima_mod, h = 6)
autoplot(arima_mod)
# Display ETS model
autoplot(IR_ts)+
autolayer(arima_forecast)+
labs(x = "Date",
y = "Real IR",
title = "ARIMA Forecast") +
autolayer(IR_test,
series = "True Values")
# Evaluate accuracy
# Make combined df
arima_data <- arima_forecast$mean
arima_data <- data.frame(IR_test,arima_data)
# Residuals
arima_data$residuals <- arima_data$IR_test - arima_data$arima_data
# MSE (for )
MSE_arima <- mean(arima_data$residuals^2)
print(paste("MSE for predictions: ",MSE_arima))
## [1] "MSE for predictions: 0.15235030662069"
# Summarize the model to ge
print(summary(arima_mod))
## Series: IR_ts
## ARIMA(2,0,1) with non-zero mean
##
## Coefficients:
## ar1 ar2 ma1 mean
## 0.1011 0.7996 0.6983 0.7433
## s.e. 0.1556 0.1398 0.1935 0.2785
##
## sigma^2 = 0.03973: log likelihood = 23.21
## AIC=-36.43 AICc=-35.88 BIC=-22.7
##
## Training set error measures:
## ME RMSE MAE MPE MAPE MASE
## Training set 0.002388211 0.1958325 0.1416181 27.95411 62.24141 0.2826038
## ACF1
## Training set -0.002893051
# Create ets model
ets_mod <- ets(IR_ts)
# forecast ets model
ets_forecast <- forecast(ets_mod, h = 6)
autoplot(ets_mod)
# Display ETS model
autoplot(IR_ts)+
autolayer(ets_forecast)+
labs(x = "Date",
y = "Real IR",
title = "ETS Forecast") +
autolayer(IR_test,
series = "True Values")
# Evaluate accuracy
# Make combined df
ets_data <- ets_forecast$mean
ets_data <- data.frame(IR_test,ets_data)
# Residuals
ets_data$residuals <- ets_data$IR_test - ets_data$ets_data
# MSE (for )
MSE_ets <- mean(ets_data$residuals^2)
print(paste("MSE for predictions: ",MSE_ets))
## [1] "MSE for predictions: 0.0709431981151992"
# Summarize the model to ge
print(summary(ets_mod))
## ETS(A,N,N)
##
## Call:
## ets(y = IR_ts)
##
## Smoothing parameters:
## alpha = 0.7938
##
## Initial states:
## l = 0.6023
##
## sigma: 0.2022
##
## AIC AICc BIC
## 181.9802 182.1965 190.2150
##
## Training set error measures:
## ME RMSE MAE MPE MAPE MASE
## Training set 0.01169328 0.2004211 0.1430129 30.05544 59.18304 0.2853871
## ACF1
## Training set -0.01717967
After examining the two models, it appears that the ANN ETS model was a better predictor for the data. The first thing to note is that it was considerably more accurate than the ARIMA model (ANN: 0.07, ARIMA: 0.15). Second, while both appear to have a negative bias, the scale of said bias is lower for ANN. It should be noted that the data is quite volatile and lacks any clear trend or seasonality. Therefore, a different model aside from these two would be more efficient.