This one is a little more detailed to get everyone started

Load libraries

library(caret)

1. Load data ------------------------------------------------------------

library(readr) UniversalBank <- read_csv("C://UniversalBank.csv") View(UniversalBank)

bank <- read.csv("C://UniversalBank.csv") names(bank) head(bank,10) str(bank)

1.1. Clean up -------------------------------------------------------------

Load libraries

library(dplyr)

str(bank)
summary(bank)

Remove duplicate rows

bank <- bank %>% distinct()

Handle missing values

Remove rows with missing values

bank_clean <- na.omit(bank)

replace NA with the most frequent value (mode)

fill_mode <- function(x) { ux <- unique(x[!is.na(x)]) ux[which.max(tabulate(match(x, ux)))] }

bankclean <- bankclean %>% mutateif(is.factor, ~ ifelse(is.na(.), fillmode(.), .)) bankclean$job <- as.factor(bankclean$job) bankclean$marital <- as.factor(bankclean$marital) bankclean$education <- as.factor(bankclean$education)

Check the structure again

str(bank_clean)

Remove irrelevant columns

bankclean <- bankclean %>% select(-ID, -ZIP)

Handle outliers

winsorize <- function(x, probs = c(0.01, 0.99)) { quantiles <- quantile(x, probs = probs, na.rm = TRUE) x[x < quantiles[1]] <- quantiles[1] x[x > quantiles[2]] <- quantiles[2] return(x) }

bankclean <- bankclean %>% mutate_if(is.numeric, normalize)

Final check after cleaning

summary(bankclean) str(bankclean)

Drop ID and zip code columns.

bank <- bank[ , -c(1, 5)] names(bank)

Reorder variables. Put the response last.

bank <- bank[ , c(1:7, 9:12, 8)]

head(bank)

Set categorical variables as factor.

bank$Education <- as.factor(bank$Education) bank$Securities.Account <- as.factor(bank$Securities.Account) bank$CD.Account <- as.factor(bank$CD.Account) bank$Online <- as.factor(bank$Online) bank$CreditCard <- as.factor(bank$CreditCard)

Rename outcome variable values (optional).

Note: We can do the problem in "0" and "1" or name them.

bank$Personal.Loan <- factor(bank$Personal.Loan, levels = c("0", "1"), labels = c("No", "Yes"))

table(bank$Personal.Loan)

1.2. Set training and validation sets -------------------------------------

set.seed(23) train_index <- sample(1:nrow(bank), 0.6*nrow(bank)) validindex <- setdiff(1:nrow(bank), trainindex) traindf <- bank[train_index, ] validdf <- bank[valid_index, ] nrow(traindf) nrow(validdf) head(traindf) head(validdf) str(traindf) str(validdf)

4. Define new customer --------------------------------------------------

new_cust <- data.frame(Age = 40, Experience = 10, Income = 84, Family = 2, CCAvg = 2, Education = 2, Mortgage = 0, Securities.Account = 0, CD.Account = 0, Online = 1, CreditCard = 1)

Set categorical variables as factor.

newcust$Education <- as.factor(newcust$Education) newcust$Securities.Account <- as.factor(newcust$Securities.Account) newcust$CD.Account <- as.factor(newcust$CD.Account) newcust$Online <- as.factor(newcust$Online) newcust$CreditCard <- as.factor(newcust$CreditCard)

new_cust

5. prepare for kNN. -------------------------------------------------------------

Normalisation, only for numerical variables

norm_values <- preProcess(train[, -c(6, 8:12)], method = c("center", "scale"))

Then normalise the training and validation sets.

library(dplyr)

normalizeminmax <- function(df) {

df_normalized <- df %>% mutate(across(where(is.numeric), ~ (. - min(.)) / (max(.) - min(.))))

return(df_normalized) }

Normalize the training set

trainingsetnormalized <- normalizeminmax(training_set)

trainingmin <- sapply(trainingset, min, na.rm = TRUE) trainingmax <- sapply(trainingset, max, na.rm = TRUE)

Normalize the validation set

validationsetnormalized <- validationset %>% mutate(across(where(is.numeric), ~ (. - trainingmin[names(trainingmin) == curcolumn()]) / (trainingmax[names(trainingmax) == curcolumn()] - trainingmin[names(trainingmin) == curcolumn()]))))

Check the structure of the normalized sets

str(trainingsetnormalized) str(validationsetnormalized)

7. Train kNN for predictions ----------------------------------------

Load necessary libraries

library(class) # For k-NN

trainfeatures <- trainingsetnormalized[, -ncol(trainingsetnormalized)] # All but the last column traintarget <- trainingsetnormalized[, ncol(trainingsetnormalized)] # Last column is the target

validfeatures <- validationsetnormalized[, -ncol(validationsetnormalized)] validtarget <- validationsetnormalized[, ncol(validationsetnormalized)]

calculateaccuracy <- function(predictions, actual) { mean(predictions == actual) } accuracyresults <- list() for (k in c(3, 5, 7, 11)) { predictions <- knn(train = trainfeatures, test = validationfeatures, cl = train_target, k = k)

# Calculate accuracy accuracy <- calculateaccuracy(predictions, validationtarget)

# Store the results accuracy_results[[as.character(k)]] <- accuracy

# Print the accuracy for each k cat("Accuracy for k =", k, ":", accuracy, "\n") }

Display all accuracy results

accuracy_results

7.1 k = 3 ---------------------------------------------------------------

Train k = 3

knnmodelk3 <- caret::knn3(Personal.Loan ~ ., data = trainnorm, k = 3) knnmodel_k3

Predict training set

knnpredk3train <- predict(knnmodelk3, newdata = trainnorm[, -c(12)], type = "class") head(knnpredk3_train)

Evaluate

confusionMatrix(knnpredk3train, as.factor(trainnorm[, 12]), positive = "Yes")

7.2 k = 5 ---------------------------------------------------------------

train k = 5

knnmodelk5 <- caret::knn5(Personal.Loan ~ ., data = trainnorm, k = 5) knnmodel_k5

Predict training set

knnpredk5train <- predict(knnmodelk5, newdata = trainnorm[, -c(12)], type = "class") head(knnpredk5_train)

Evaluate

confusionMatrix(knnpredk5train, as.factor(trainnorm[, 12]), positive = "Yes")

7.3 k = 7 ---------------------------------------------------------------

train k = 7

knnmodelk7 <- caret::knn3(Personal.Loan ~ ., data = trainnorm, k = 7) knnmodel_k7

Predict training set

knnpredk7train <- predict(knnmodelk7, newdata = trainnorm[, -c(12)], type = "class") head(knnpredk7_train)

Evaluate

confusionMatrix(knnpredk7train, as.factor(trainnorm[, 12]), positive = "Yes")

7.4 predict validation set ----------------------------------------------

use k = 3

Predict training set

knnpredk3valid <- predict(knnmodelk3, newdata = validnorm[, -c(12)], type = "class") head(knnpredk3_valid)

Evaluate

confusionMatrix(knnpredk3valid, as.factor(validnorm[, 12]), positive = "Yes")

library(ROSE)

ROSE::roc.curve(validnorm$Personal.Loan, knnpredk3valid)

use k = 5

Predict training set

knnpredk5valid <- predict(knnmodelk5, newdata = validnorm[, -c(12)], type = "class") head(knnpredk5_valid)

Evaluate

confusionMatrix(knnpredk5valid, as.factor(validnorm[, 12]), positive = "Yes")

library(ROSE)

ROSE::roc.curve(validnorm$Personal.Loan, knnpredk5valid)

use k = 7

Predict training set

knnpredk7valid <- predict(knnmodelk7, newdata = validnorm[, -c(12)], type = "class") head(knnpredk7_valid)

Evaluate

confusionMatrix(knnpredk7valid, as.factor(validnorm[, 12]), positive = "Yes")

library(ROSE)

ROSE::roc.curve(validnorm$Personal.Loan, knnpredk7valid)

8. use kNN for new customer, k = ??? -------------------------------------------------------------

knnpredk11valid <- predict(knnmodelk11, newdata = validnorm[, -c(12)], type = "class") head(knnpredk11_valid)

Evaluate

confusionMatrix(knnpredk11valid, as.factor(validnorm[, 12]), positive = "Yes")

library(ROSE)

ROSE::roc.curve(validnorm$Personal.Loan, knnpredk11valid)

9. Answers --------------------------------------------------------------

Not sure ran into erros that ai couldn't quit figure out. I have also ran into issues with the confusion matrix during class'