library(caret)
library(dplyr)
library(randomForest)
library(MLmetrics)
library(pROC)
library(gbm)
library(kernlab)
library(glmnet)
library(e1071)


rm(list=ls())
set.seed(21)

# Read in training and test data 
santander.df <- read.csv('train.csv',header=T, sep=',')
#test.data <- read.csv('test.csv', header = T, sep=',')

# Convert target variable to a factor 0 = No purchase; 1 = Made purchase
santander.df$target <- factor(santander.df$target)
# Drop ID_Code column
santander.df <- select(santander.df, -c('ID_code'))


# Looking at the data frame
head(santander.df)
str(santander.df$target)
table(santander.df$target)

# Split into train and test set
n <- nrow(santander.df)
train.indices <- sample(n, .8 * n)
train.data <- santander.df[train.indices,]
test.x <- santander.df[-train.indices, ]
test.y <- santander.df$target[-train.indices]

# Down sample the minority class: Changes 'target' variable to 'Class' in new DF
down_train <- downSample(x = train.data[, !(names(train.data) %in% 'target')], y = train.data$target)   
# Change Class column back to target and check if down sample worked
down_train <- down_train %>% rename(target = Class)
levels(down_train$target) <- c('No', 'Yes')
table(down_train$target)
# Shuffle rows in down sampled so target variable is not in order
down_train <- down_train[sample(nrow(down_train)),]
# Create train X and Y variables
train.x <- select(down_train, -c('target'))
train.y <- down_train$target


##################################################################
########### Logistic Regression (Down-sampling) ##################
##################################################################
set.seed(21)

# Fit the model
glm_Fit <- train(target ~ .,data = down_train, trControl = trainControl(method = "none"),
                 method = "glm", family = "binomial")


# Predictions and probs
glm_Fit.probs <- predict(glm_Fit, newdata = test.x, type = 'prob')[,2]
glm_Fit.preds <- predict(glm_Fit, newdata = test.x)

# Scoring metrics
glm_Fit.Acc <- Accuracy(glm_Fit.preds, ifelse(test.y==0,'No','Yes'))
glm_Fit.AUC <- AUC(glm_Fit.probs, test.y)
glm_Fit.PRAUC <- PRAUC(glm_Fit.probs, test.y)

##################################################################
################## Lasso/Ridge (Down-sampling) ###################
##################################################################
set.seed(21)

scaled.down_train <- data.frame(scale(down_train[,-ncol(down_train)]))
scaled.down_train <- mutate(scaled.down_train, target = down_train$target)

# Initialize grid and training method
fitControl <- trainControl(method = "cv", number = 5, classProbs = TRUE, summaryFunction = twoClassSummary)
netGrid <-  expand.grid(alpha = 0:1, lambda = seq(0.0001, 1, length = 20))

set.seed(21)
# Perform CV to tune parameters
glmnet_Fit <- train(target ~ ., data = scaled.down_train, method = "glmnet", trControl = fitControl, 
                    verbose = TRUE, tuneGrid = netGrid, metric = "ROC")


# Make predictions
glmnet.probs <- predict(glmnet_Fit, newdata = test.x, type = 'prob')[,2]
glmnet.preds <- predict(glmnet_Fit, newdata = test.x)

#Confusion Matrix
glmnet.cMatrix <- table(glmnet.preds, ifelse(test.y==0,'No','Yes'))
# Overall Accuracy Rate
glmnet.Acc <- Accuracy(glmnet.preds, ifelse(test.y==0,'No','Yes'))
# ROC Area Under Curve
glmnet.AUC <- AUC(glmnet.probs, test.y)
# PRAUCfac
glmnet.PRAUC <- PRAUC(glmnet.probs, test.y)


##################################################################
################## Random Forest (down-sampling) #################
##################################################################
set.seed(21)


# Initialize grid and training method
fitControl <- trainControl(method = "cv", number = 5, classProbs = TRUE, summaryFunction = twoClassSummary)
rfGrid <-  expand.grid(mtry = c(5,10,15,20))

# Perform CV to tune parameters
rf_Fit <- train(target ~ ., data = down_train, method = "rf", trControl = fitControl, 
                verbose = TRUE, tuneGrid = rfGrid, metric = "ROC")

# Make predictions
rf.probs <- predict(rf_Fit, newdata = test.x, type = 'prob')[,2]
rf.preds <- predict(rf_Fit, newdata = test.x)

#Confusion Matrix
rf.cMatrix <- table(rf.preds, ifelse(test.y==0,'No','Yes'))
# Overall Accuracy Rate
rf.Acc <- Accuracy(rf.preds, ifelse(test.y==0,'No','Yes'))
# ROC Area Under Curve
rf.AUC <- AUC(rf.probs, test.y)
# PRAUCfac
rf.PRAUC <- PRAUC(rf.probs, test.y)

rf.final <- rf_Fit$finalModel
varImpPlot(rf.final)

##################################################################
################## Boosting (Down-sampling) ######################
##################################################################


# Initialize grid and training method
fitControl <- trainControl(method = "cv", number = 5, classProbs = TRUE, summaryFunction = twoClassSummary)
gbmGrid <-  expand.grid(interaction.depth = c(1, 5, 10), n.trees = c(100,500,1000), 
                        shrinkage =  c(0.01, .001), n.minobsinnode = 20)

set.seed(21)

# Perform CV to tune parameters
gbm_Fit <- train(target ~ ., data = down_train, method = "gbm", trControl = fitControl, 
                 verbose = TRUE, tuneGrid = gbmGrid, metric = "ROC")


# Make predictions
gbm.probs <- predict(gbm_Fit, newdata = test.x, type = 'prob')[,2]
gbm.preds <- predict(gbm_Fit, newdata = test.x)

#Confusion Matrix
gbm.cMatrix <- table(gbm.preds, ifelse(test.y==0,'No','Yes'))
# Overall Accuracy Rate
glmnet.Acc <- Accuracy(gbm.preds, ifelse(test.y==0,'No','Yes'))
# ROC Area Under Curve
gbm.AUC <- AUC(gbm.probs, test.y)
# PRAUCfac
gbm.PRAUC <- PRAUC(gbm.probs, test.y)




##################################################################
################## Naive Bayes (Down-sampling) ##################
##################################################################
# Fit the Naive Bayes Model
nBayes_fit <- naiveBayes(target ~ ., data = down_train)

# Make predictions
nBayes.probs <- predict(nBayes_fit, newdata = test.x, type = 'raw') # Class probabilities
nBayes.probs <- nBayes.probs[,2] # Class probabilities for the Purchase (1) Class
nBayes.preds <- predict(nBayes_fit, newdata = test.x) # Class predicitions

#Confusion Matrix
nBayes.cMatrix <- table(nBayes.preds, ifelse(test.y==0,'No','Yes'))
# Overall Accuracy Rate
nBayes.Acc <- Accuracy(nBayes.preds, ifelse(test.y==0,'No','Yes'))
# ROC Area Under Curve
nBayes.AUC <- AUC(nBayes.probs, test.y)
# PRAUCfac
nBayes.PRAUC <- PRAUC(nBayes.probs, test.y)
