# Packages list
library(sandwich)
## Warning: package 'sandwich' was built under R version 4.3.2
library(foreign)
library(lmtest)
## Loading required package: zoo
##
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
##
## as.Date, as.Date.numeric
library(dplyr)
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(texreg)
## Warning: package 'texreg' was built under R version 4.3.2
## Version: 1.39.3
## Date: 2023-11-09
## Author: Philip Leifeld (University of Essex)
##
## Consider submitting praise using the praise or praise_interactive functions.
## Please cite the JSS article in your publications -- see citation("texreg").
library(caret)
## Warning: package 'caret' was built under R version 4.3.2
## Loading required package: ggplot2
## Loading required package: lattice
library(ISLR)
## Warning: package 'ISLR' was built under R version 4.3.2
dt <- data.frame(Default)
#Function to change yes and no to 1 and 0
Default1 = Default %>%
mutate(
default_numeric = case_when(
default == "Yes" ~ 1,
default == "No" ~ 0
)
)
table(Default1$default_numeric)
##
## 0 1
## 9667 333
plot(x= Default1$income, y = Default1$default_numeric)
model1 <- glm(formula = default_numeric ~ income + balance,
family = binomial(link = "logit"),
data = Default1)
# regression output
options(scipen = 999)
summary(model1)
##
## Call:
## glm(formula = default_numeric ~ income + balance, family = binomial(link = "logit"),
## data = Default1)
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -11.540468437 0.434756357 -26.545 < 0.0000000000000002 ***
## income 0.000020809 0.000004985 4.174 0.0000299 ***
## balance 0.005647103 0.000227373 24.836 < 0.0000000000000002 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 2920.6 on 9999 degrees of freedom
## Residual deviance: 1579.0 on 9997 degrees of freedom
## AIC: 1585
##
## Number of Fisher Scoring iterations: 8
For an increase in 1 unit of income, the log-odds of default increase by 0.000020809.
For an increase in 1 unit of balance, the log-odds of default increase by 0.005647103
We cannot use linear regression model because it will not be a good approximation. This is due to the fact that OLS could yiels results greater than 1 or less than 0. The other issue is interpreting the values between 1 and 0. Lastly, since OLS has a constant rate of change, and this assumes that the increase is equal. In the case of my logistic model it might not be true, people with more or less income and balance have different rate of changes in their probabilities of default.
predicted_probabilities <- predict(object = model1,
type = "response")
# Convert predicted probabilities to binary outcomes (0 or 1) using a threshold (e.g., 0.5)
threshold <- 0.5
binary_predictions <- ifelse(test = predicted_probabilities >= threshold,
yes = 1,
no = 0
)
# Attach binary predictions to the original dataset
Default1$default_numeric <- binary_predictions
summary(Default1$default_numeric)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 0.0000 0.0000 0.0000 0.0146 0.0000 1.0000
conf_matrix <- table(Default1$default,Default1$default_numeric)
print(conf_matrix)
##
## 0 1
## No 9629 38
## Yes 225 108
TP<- conf_matrix[2, 2]
FP <- conf_matrix[1, 2]
TN <- conf_matrix[1, 1]
FN <- conf_matrix[2, 1]
# Calculate sensitivity and specificity
sensitivity <- TP / (TP + FP)
specificity <- TN / (TN + FP)
print(sensitivity)
## [1] 0.739726
print(specificity)
## [1] 0.9960691
Accuracy <- (TP+TN)/(TP+FP+FN+TN)
Accuracy
## [1] 0.9737
Precision <- TP/TP+FP
Recall <- TP/TP+FN
F1s <- 2*(Recall*Precision)/Recall+Precision
F1s
## [1] 117
binary_predictions <- factor(binary_predictions,
levels = levels(Default1$default))
confusionMatrix(binary_predictions,
Default1$default)
## Confusion Matrix and Statistics
##
## Reference
## Prediction No Yes
## No 0 0
## Yes 0 0
##
## Accuracy : NaN
## 95% CI : (NA, NA)
## No Information Rate : NA
## P-Value [Acc > NIR] : NA
##
## Kappa : NaN
##
## Mcnemar's Test P-Value : NA
##
## Sensitivity : NA
## Specificity : NA
## Pos Pred Value : NA
## Neg Pred Value : NA
## Prevalence : NaN
## Detection Rate : NaN
## Detection Prevalence : NaN
## Balanced Accuracy : NA
##
## 'Positive' Class : No
##
The biggest takeaway for me is the methodology that we follow in order to produce a much more accurate analysis. Checking for the type and level of data, skewness, type of distribution before even doing anything with the data. Data preparation and cleaning, checking for missing observations. Depending on the interest of the study and the data perform either an linear or Logit regression and testing for accuracy using residual analysis. Performing any transformation to the data in order to make it better to fit a linear regression. Depending on model and transformation, the results change in interpretation. Following this methodology during the semester has made develop more my analytical thinking rather than just jumping into performing statistical analysis.
Over the course of 14 weeks I have also learned some of the things that go more in depth about statistical analysis such as the Gauss-Markov assumptions and its importance in OLS, the methods for hypothesis testing, characteristics of distributions, central limit theorem.