title: “Final Project FRED” author: “Joel Steele” date: “2025-04-26” output: pdf_document
#Motivation
#Statistical learning models are becoming a popular tool used to forecast and analyze Gross Domestic Product (GDP). They use macroeconomic indicators and time series data to improve prediction accuracy. This project will use a linear model to produce results that predict GDP over a 10-year period and compare it with actual results. If successful, it may be helpful for weathering unexpected shocks in the economy.
#Problem
#GDP growth rate is perhaps the best indicators of economic growth for a country. It is important to test theories and hypotheses using past data to hopefully get an idea of future trends. Accurate predictions of GDP growth will allow economists and politicians to make better adjustments to monetary and fiscal policy. The biggest challenge/problem is developing accurate models. This project is intended to assist with the many tools already used for determining GDP trends. This project starts with a linear model (LM) and is constructed using the GDP as a response variable. The CPI and Unemployment rate will be used as predictors. Cross-Validation will be used to estimate the accuracy of the test error (model assessment). It will not be an exhausted model for capturing all possibilities within the economic framework, but a functioning statistical learning code with the capacity for adding additional relevant models in the future.
#Analysis
#The linear regression model showed that unemployment rate is inversely proportionate to GDP (as unemployment goes up, GDP goes down). This was expected; it follows Okun’s law. However, the scatter plot revealed a clear nonlinear pattern between them. Therefore, a nonlinear regression method was used, the polynomial regression. A 4-degree polynomial was initial used in the model as a starting point. However, the cross-validation test showed that the best polynomial regression model is with a 2-degree polynomial. #The coefficient of determination R^2 method was use to predict the country’s Gross Domestic Product (GDP) on the basis of statistical variables associated with its performance, i.e., the unemployment rate (UNRATE), consumer price index (CPI) and certain dates that recorded unexpected shocks in the economy (observation date). The regsubsets function was used to help select variables for the best model. The model with the lowest Bayesian Information Criteria (BIC) is the two variable model that contains CPI and UNRATE.
#Solution
#The variables that had the most impact on GDP were CPI and UNRATE. UNRATE and CPI had the least errors in the test, -213.75, 139.27 respectively, indicating they have the most impact on GDP. Of the three variables, observation date had the least impact. This is consistent with real world experiences. For example, during a major economic shock, like in 2020 with Covid and mandatory government shut-downs, the data is radically inconsistent. Aside from rare unforeseen events that result in major economic shocks, seen in the observation date variable, GDP and UNRATE are the indicators most likely to impact GDP.
{r FRED, include=FALSE}
summary(FRED)
library(VAR)
FRED <- read_csv("C:/Users/joels/OneDrive/FRED.xlsx")
attach(FRED)
View(FRED)
head(FRED)
lm.fit <-lm(GDP~UNRATE, data=FRED)
lm.fit <- lm(GDP~UNRATE)
lm.fit
summary(lm.fit)
names(lm.fit)
coef(lm.fit)
predict(lm.fit, data.frame(UNRATE=(c(5,10,15))),interval = "confidence")
predict(lm.fit, data.frame(UNRATE=(c(5,10,15))),interval = "prediction")
#plot response variable with the predictor and the least square regression.
plot(UNRATE, GDP)
abline(lm.fit)
#Unemployment rate is inversely proportionate to GDP(as unemployment goes up, GDP goes down).
# This is expected, it follows Okun's law.
#The scatter plot shows a clear nonlinear pattern between them.
#So, simple linear regression may not be a good choice. Therefore, a nonlinear regression
#method will be used, the polynomial regression.
library(VAR)
attach(FRED)
head(GDP)
plot(UNRATE, GDP)
fit.poly <-lm(GDP~poly(UNRATE,4), data = FRED)
summary(fit.poly)
plot(UNRATE, GDP)
lines(sort(UNRATE), fitted(fit.poly)[order(UNRATE)], col="red")
# Create a grid of values for UNRATE which we want to predict.
UNRATElims <- range(UNRATE)
UNRATElims
UNRATE.grid <- seq(from=UNRATElims[1], to=UNRATElims[2])
UNRATE.grid
#plot the data and add the fit from the degree-4 polynomial.
preds <- predict(fit.poly, newdata = data.frame(UNRATE=UNRATE.grid), se=TRUE)
head(preds)
plot(UNRATE, GDP)
lines(UNRATE.grid, preds$fit, col="purple")
# Error bounds for approximate 95% confidence intervals(empirical rule, +2-2).
se.bounds <- cbind(preds$fit+2*preds$se.fit, preds$fit-2*preds$se.fit)
head(se.bounds)
plot(UNRATE, GDP, xlim = UNRATElims, cex=0.5, col="darkgrey")
title (" Degree-4 Polynomial ",outer =F)
lines(UNRATE.grid, preds$fit ,lwd =2, col ="red")
matlines (UNRATE.grid , se.bounds ,lwd =1, col ="blue",lty =3)
#Cross-Validation used to decide on the degree of the polynomial to use.
# 9 folds are training and 1 is testing.
set.seed(1)
k=10
folds=sample(rep (1:k, length = nrow(FRED)))
head(folds)
max.degree <- 5
cv.errors =matrix (NA, k, max.degree, dimnames =list(NULL, paste (1:max.degree)))
cv.errors
for(j in 1:k){
for(i in 1:max.degree) {
cv.fit.ploy =lm(GDP ~ poly(UNRATE , i), data = FRED[folds!=j,])
pred=predict(cv.fit.ploy, newdata=data.frame(UNRATE=UNRATE[folds==j]))
cv.errors[j,i]=mean( (FRED$GDP[folds ==j]-pred)^2)
}
}
cv.errors
mean.cv.errors =apply(cv.errors, MARGIN = 2, mean)
mean.cv.errors
which.min(unname(mean.cv.errors))
# Only 2 degrees are recommended, higher-order models are not justified.
# Best model is polynomial with a degree of 2.
plot(mean.cv.errors, type='b')
fit.ploy.best=lm(GDP ~ poly(UNRATE , 2), data = FRED)
coef(fit.ploy.best)
#We wish to predict the country's Gross Domestic Product(GDP) on the basis of various
#statistical variables associated with it's performance, i.e., the unemployment rate (UNRATE) and
#consumer price index (CPI).
library(VAR)
head(FRED)
names(FRED)
dim(FRED)
attach(FRED)
sum(is.na(GDP))
# No missing values.
library(leaps)
regfit.full <- regsubsets(GDP~., data= FRED)
reg.summary <- summary(regfit.full)
reg.summary
names(reg.summary)
reg.summary$adjr2
plot(reg.summary$adjr2 , xlab = "Number of Variables",
ylab = "Adjusted RSq", type = "b")
which.max(reg.summary$adjr2)
plot(reg.summary$bic , xlab = "Number of Variables",
ylab = "BIC", type = "b")
which.min(reg.summary$bic)
plot(regfit.full , scale = "r2")
plot(regfit.full , scale = "adjr2")
plot(regfit.full , scale = "Cp")
plot(regfit.full , scale = "bic")
# Best model using Bayesian Information Criteria (BIC) shows 2 variables.
coef(regfit.full , 3)
# Forward and backward stepwise selection.
regfit.forward <- regsubsets(GDP~., data=FRED, method = "forward")
plot(regfit.forward, scale = "Cp")
coef(regfit.forward, 3)
regfit.backward <- regsubsets(GDP~., data=FRED, method = "backward")
plot(regfit.backward, scale = "Cp")
coef(regfit.backward, 3)
# Estimate the test error using a validation approach.
set.seed (1)
train=sample(x=c(TRUE,FALSE), size = nrow(FRED), rep=TRUE,
prob=c(0.7,0.3))
head(train)
test <- (!train)
head(test)
sum(train==TRUE)
sum(train==FALSE)
length(train)
length(test)
reg.fit.valid <- regsubsets(GDP~., data = FRED[train, ], nvmax = 3)
summary(reg.fit.valid)
# Calculate testing errors.
test.matrix<- model.matrix(GDP~., data = FRED[test, ])
head(test.matrix)
dim(test.matrix)
sum <- 0
for(i in 1:3){
sum <- sum+i
}
sum
# Test errors.
errors <- c()
for(i in 1:3){
coe <- coef(reg.fit.valid, id=i) # for different number of variables
pred <- test.matrix[, names(coe)]%*%coe
errors[i]=mean((FRED$GDP[test]-pred)^2)
}
coef(reg.fit.valid, id=2)
errors
plot(errors, type="b")
which.min(errors)
coef(reg.fit.valid, which.min(errors))
#Two variables had the most impact on GDP, CPI and UNRATE. CPI had the least
#errors in the test, indicating it has the most impact on GDP. Of the
#three variables, observation_date had the least impact. This is consistent with
#real world experiences. For example, during major economic shock, like in 2020 with mandatory
#government shut-downs, the data is radically inconsistent.