#Data Preprocessing

library(readr)
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(tidyr)
library(ggplot2)
library(corrplot)
## corrplot 0.92 loaded
library(caTools)
#Data Cleaning
#Load the dataset
data <- read_csv('C:/Users/USer/Downloads/archive (8)/creditcard_2023.csv')
## Rows: 568630 Columns: 31
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## dbl (31): id, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V11, V12, V13, V14, V...
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
head(data)
## # A tibble: 6 × 31
##      id      V1     V2    V3      V4     V5    V6    V7      V8     V9   V10
##   <dbl>   <dbl>  <dbl> <dbl>   <dbl>  <dbl> <dbl> <dbl>   <dbl>  <dbl> <dbl>
## 1     0 -0.261  -0.470 2.50  -0.0837 0.130  0.733 0.519 -0.130   0.727 0.638
## 2     1  0.985  -0.356 0.558 -0.430  0.277  0.429 0.406 -0.133   0.347 0.530
## 3     2 -0.260  -0.949 1.73  -0.458  0.0741 1.42  0.744 -0.0956 -0.261 0.691
## 4     3 -0.152  -0.509 1.75  -1.09   0.249  1.14  0.518 -0.0651 -0.206 0.575
## 5     4 -0.207  -0.165 1.53  -0.448  0.106  0.531 0.659 -0.213   1.05  0.968
## 6     5  0.0253 -0.141 1.19  -0.708  0.430  0.459 0.611 -0.0926  0.181 0.452
## # ℹ 20 more variables: V11 <dbl>, V12 <dbl>, V13 <dbl>, V14 <dbl>, V15 <dbl>,
## #   V16 <dbl>, V17 <dbl>, V18 <dbl>, V19 <dbl>, V20 <dbl>, V21 <dbl>,
## #   V22 <dbl>, V23 <dbl>, V24 <dbl>, V25 <dbl>, V26 <dbl>, V27 <dbl>,
## #   V28 <dbl>, Amount <dbl>, Class <dbl>
View(data)
nrow(data)
## [1] 568630
ncol(data)
## [1] 31
#Check the structure of the dataset
str(data)
## spc_tbl_ [568,630 × 31] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
##  $ id    : num [1:568630] 0 1 2 3 4 5 6 7 8 9 ...
##  $ V1    : num [1:568630] -0.261 0.985 -0.26 -0.152 -0.207 ...
##  $ V2    : num [1:568630] -0.47 -0.356 -0.949 -0.509 -0.165 ...
##  $ V3    : num [1:568630] 2.496 0.558 1.729 1.747 1.527 ...
##  $ V4    : num [1:568630] -0.0837 -0.4297 -0.458 -1.0902 -0.4483 ...
##  $ V5    : num [1:568630] 0.1297 0.2771 0.0741 0.2495 0.1061 ...
##  $ V6    : num [1:568630] 0.733 0.429 1.419 1.143 0.531 ...
##  $ V7    : num [1:568630] 0.519 0.406 0.744 0.518 0.659 ...
##  $ V8    : num [1:568630] -0.13 -0.1331 -0.0956 -0.0651 -0.2127 ...
##  $ V9    : num [1:568630] 0.727 0.347 -0.261 -0.206 1.05 ...
##  $ V10   : num [1:568630] 0.638 0.53 0.691 0.575 0.968 ...
##  $ V11   : num [1:568630] -0.987 0.14 -0.273 -0.753 -1.203 ...
##  $ V12   : num [1:568630] 0.293 1.564 0.659 0.737 1.03 ...
##  $ V13   : num [1:568630] -0.941 0.574 0.805 0.593 1.439 ...
##  $ V14   : num [1:568630] 0.549 0.628 0.617 0.56 0.241 ...
##  $ V15   : num [1:568630] 1.805 0.706 3.069 -0.698 0.153 ...
##  $ V16   : num [1:568630] 0.2156 0.7892 -0.5775 -0.0307 0.2245 ...
##  $ V17   : num [1:568630] 0.512 0.404 0.887 0.243 0.366 ...
##  $ V18   : num [1:568630] 0.334 0.202 0.239 2.179 0.292 ...
##  $ V19   : num [1:568630] 0.124 -0.341 -2.366 -1.345 0.445 ...
##  $ V20   : num [1:568630] 0.0912 -0.234 0.3617 -0.3782 0.2472 ...
##  $ V21   : num [1:568630] -0.11055 -0.19494 -0.00502 -0.14693 -0.10698 ...
##  $ V22   : num [1:568630] 0.2176 -0.6058 0.7029 -0.0382 0.7297 ...
##  $ V23   : num [1:568630] -0.1348 0.0795 0.945 -0.214 -0.1617 ...
##  $ V24   : num [1:568630] 0.166 -0.577 -1.155 -1.893 0.313 ...
##  $ V25   : num [1:568630] 0.126 0.19 -0.606 1.004 -0.414 ...
##  $ V26   : num [1:568630] -0.435 0.297 -0.313 -0.516 1.071 ...
##  $ V27   : num [1:568630] -0.0812 -0.2481 -0.3003 -0.1653 0.0237 ...
##  $ V28   : num [1:568630] -0.151 -0.0645 -0.2447 0.0484 0.4191 ...
##  $ Amount: num [1:568630] 17982 6531 2514 5384 14279 ...
##  $ Class : num [1:568630] 0 0 0 0 0 0 0 0 0 0 ...
##  - attr(*, "spec")=
##   .. cols(
##   ..   id = col_double(),
##   ..   V1 = col_double(),
##   ..   V2 = col_double(),
##   ..   V3 = col_double(),
##   ..   V4 = col_double(),
##   ..   V5 = col_double(),
##   ..   V6 = col_double(),
##   ..   V7 = col_double(),
##   ..   V8 = col_double(),
##   ..   V9 = col_double(),
##   ..   V10 = col_double(),
##   ..   V11 = col_double(),
##   ..   V12 = col_double(),
##   ..   V13 = col_double(),
##   ..   V14 = col_double(),
##   ..   V15 = col_double(),
##   ..   V16 = col_double(),
##   ..   V17 = col_double(),
##   ..   V18 = col_double(),
##   ..   V19 = col_double(),
##   ..   V20 = col_double(),
##   ..   V21 = col_double(),
##   ..   V22 = col_double(),
##   ..   V23 = col_double(),
##   ..   V24 = col_double(),
##   ..   V25 = col_double(),
##   ..   V26 = col_double(),
##   ..   V27 = col_double(),
##   ..   V28 = col_double(),
##   ..   Amount = col_double(),
##   ..   Class = col_double()
##   .. )
##  - attr(*, "problems")=<externalptr>
#Summary statistics of the dataset
summary(data)
##        id               V1                 V2                 V3           
##  Min.   :     0   Min.   :-3.49558   Min.   :-49.9666   Min.   :-3.183760  
##  1st Qu.:142157   1st Qu.:-0.56529   1st Qu.: -0.4867   1st Qu.:-0.649299  
##  Median :284315   Median :-0.09364   Median : -0.1359   Median : 0.000353  
##  Mean   :284315   Mean   : 0.00000   Mean   :  0.0000   Mean   : 0.000000  
##  3rd Qu.:426472   3rd Qu.: 0.83266   3rd Qu.:  0.3436   3rd Qu.: 0.628538  
##  Max.   :568629   Max.   : 2.22905   Max.   :  4.3619   Max.   :14.125834  
##        V4                 V5                 V6                  V7          
##  Min.   :-4.95122   Min.   :-9.95279   Min.   :-21.11111   Min.   : -4.3518  
##  1st Qu.:-0.65602   1st Qu.:-0.29350   1st Qu.: -0.44587   1st Qu.: -0.2835  
##  Median :-0.07376   Median : 0.08109   Median :  0.07872   Median :  0.2334  
##  Mean   : 0.00000   Mean   : 0.00000   Mean   :  0.00000   Mean   :  0.0000  
##  3rd Qu.: 0.70700   3rd Qu.: 0.43974   3rd Qu.:  0.49779   3rd Qu.:  0.5260  
##  Max.   : 3.20154   Max.   :42.71689   Max.   : 26.16840   Max.   :217.8730  
##        V8                 V9                V10               V11          
##  Min.   :-10.7563   Min.   :-3.75192   Min.   :-3.1633   Min.   :-5.95472  
##  1st Qu.: -0.1923   1st Qu.:-0.56874   1st Qu.:-0.5901   1st Qu.:-0.70145  
##  Median : -0.1145   Median : 0.09253   Median : 0.2626   Median :-0.04105  
##  Mean   :  0.0000   Mean   : 0.00000   Mean   : 0.0000   Mean   : 0.00000  
##  3rd Qu.:  0.0473   3rd Qu.: 0.55926   3rd Qu.: 0.5925   3rd Qu.: 0.74777  
##  Max.   :  5.9580   Max.   :20.27006   Max.   :31.7227   Max.   : 2.51357  
##       V12               V13                V14               V15          
##  Min.   :-2.0204   Min.   :-5.95523   Min.   :-2.1074   Min.   :-3.86181  
##  1st Qu.:-0.8311   1st Qu.:-0.69667   1st Qu.:-0.8732   1st Qu.:-0.62125  
##  Median : 0.1621   Median : 0.01761   Median : 0.2305   Median :-0.03926  
##  Mean   : 0.0000   Mean   : 0.00000   Mean   : 0.0000   Mean   : 0.00000  
##  3rd Qu.: 0.7447   3rd Qu.: 0.68561   3rd Qu.: 0.7518   3rd Qu.: 0.66541  
##  Max.   :17.9136   Max.   : 7.18749   Max.   :19.1695   Max.   :14.53220  
##       V16               V17               V18                V19          
##  Min.   :-2.2145   Min.   :-2.4849   Min.   :-2.42195   Min.   :-7.80499  
##  1st Qu.:-0.7163   1st Qu.:-0.6195   1st Qu.:-0.55605   1st Qu.:-0.56531  
##  Median : 0.1340   Median : 0.2716   Median : 0.08729   Median :-0.02598  
##  Mean   : 0.0000   Mean   : 0.0000   Mean   : 0.00000   Mean   : 0.00000  
##  3rd Qu.: 0.6556   3rd Qu.: 0.5182   3rd Qu.: 0.54439   3rd Qu.: 0.56012  
##  Max.   :46.6529   Max.   : 6.9941   Max.   : 6.78372   Max.   : 3.83167  
##       V20                V21                 V22                V23           
##  Min.   :-78.1478   Min.   :-19.38252   Min.   :-7.73480   Min.   :-30.29545  
##  1st Qu.: -0.3502   1st Qu.: -0.16644   1st Qu.:-0.49049   1st Qu.: -0.23763  
##  Median : -0.1234   Median : -0.03743   Median :-0.02733   Median : -0.05969  
##  Mean   :  0.0000   Mean   :  0.00000   Mean   : 0.00000   Mean   :  0.00000  
##  3rd Qu.:  0.2482   3rd Qu.:  0.14798   3rd Qu.: 0.46388   3rd Qu.:  0.15572  
##  Max.   : 29.8728   Max.   :  8.08708   Max.   :12.63251   Max.   : 31.70763  
##       V24               V25                  V26                V27          
##  Min.   :-4.0680   Min.   :-13.612633   Min.   :-8.22697   Min.   :-10.4986  
##  1st Qu.:-0.6516   1st Qu.: -0.554148   1st Qu.:-0.63189   1st Qu.: -0.3050  
##  Median : 0.0159   Median : -0.008193   Median :-0.01189   Median : -0.1729  
##  Mean   : 0.0000   Mean   :  0.000000   Mean   : 0.00000   Mean   :  0.0000  
##  3rd Qu.: 0.7007   3rd Qu.:  0.550015   3rd Qu.: 0.67289   3rd Qu.:  0.3340  
##  Max.   :12.9656   Max.   : 14.621509   Max.   : 5.62329   Max.   :113.2311  
##       V28                Amount             Class    
##  Min.   :-39.03524   Min.   :   50.01   Min.   :0.0  
##  1st Qu.: -0.23188   1st Qu.: 6054.89   1st Qu.:0.0  
##  Median : -0.01393   Median :12030.15   Median :0.5  
##  Mean   :  0.00000   Mean   :12041.96   Mean   :0.5  
##  3rd Qu.:  0.40959   3rd Qu.:18036.33   3rd Qu.:1.0  
##  Max.   : 77.25594   Max.   :24039.93   Max.   :1.0
#Check for missing values
colSums(is.na(data))
##     id     V1     V2     V3     V4     V5     V6     V7     V8     V9    V10 
##      0      0      0      0      0      0      0      0      0      0      0 
##    V11    V12    V13    V14    V15    V16    V17    V18    V19    V20    V21 
##      0      0      0      0      0      0      0      0      0      0      0 
##    V22    V23    V24    V25    V26    V27    V28 Amount  Class 
##      0      0      0      0      0      0      0      0      0
#Data Visualization
# Visualize the class distribution
ggplot(data, aes(x = factor(Class))) +
  geom_bar(fill = "blue") +
  labs(title = "Class Distribution: Non-Fraud (0) vs. Fraud(0)", x = "Class", y = "Count")

#Boxplot to check for outliers
ggplot(data, aes(x = factor(Class), y = Amount)) +
  geom_boxplot(fill = "lightblue") +
  labs(title = "Transaction Amounts by Class", x = "Class (0 = Non-Fraud, 1 = Fraud)", y = "Transaction Amount") +
  theme_minimal()

#Correlation plot
correlation_matrix <- cor(data)
corrplot(correlation_matrix, method = "color", type = "upper", order = "hclust", tl.cex = 0.7)

#Data Normalization
# Normalize numerical features (excluding 'Class' and 'id')
numerical_features <- data %>% select(-id, -Class)
normalized_data <- as.data.frame(lapply(numerical_features, function(x) (x - min(x)) / (max(x) - min(x))))

#Add the 'Class' and 'id' columns back to the dataset
data_normalized <- cbind(data %>% select(id, Class), normalized_data)
#Feature Engineering
#Calculate the total transaction amount per transaction
#Sum all numerical features
data_normalized$total_amount <- rowSums(data_normalized[, 3:31])  

#Normalize 'total_amount' using min-max normalization
total_amount_min <- min(data_normalized$total_amount)
total_amount_max <- max(data_normalized$total_amount)
data_normalized$total_amount <- (data_normalized$total_amount - total_amount_min) / (total_amount_max - total_amount_min)

#Ensure 'Class' is a factor with levels 0 and 1
data_normalized$Class <- factor(data_normalized$Class, levels = c(0, 1))

head(data_normalized)
##   id Class        V1        V2        V3        V4        V5        V6
## 1  0     0 0.5650908 0.9110684 0.3281432 0.5970370 0.1914283 0.4620185
## 2  1     0 0.7827027 0.9131595 0.2161701 0.5546060 0.1942280 0.4555824
## 3  2     0 0.5651565 0.9022381 0.2837905 0.5511308 0.1903723 0.4765402
## 4  3     0 0.5840433 0.9103449 0.2848478 0.4735875 0.1937029 0.4706990
## 5  4     0 0.5744938 0.9166708 0.2721504 0.5523198 0.1909811 0.4577386
## 6  5     0 0.6150417 0.9171267 0.2527441 0.5204673 0.1971395 0.4562247
##           V7        V8        V9       V10       V11       V12       V13
## 1 0.02191858 0.6357600 0.1864575 0.1089552 0.5866237 0.1160752 0.3814921
## 2 0.02141212 0.6355738 0.1706508 0.1058615 0.7197234 0.1798261 0.4968001
## 3 0.02292880 0.6378199 0.1453095 0.1104737 0.6709423 0.1344239 0.5143839
## 4 0.02191522 0.6396415 0.1476240 0.1071636 0.6143080 0.1383510 0.4982396
## 5 0.02254783 0.6308149 0.1998936 0.1184235 0.5610990 0.1530041 0.5626340
## 6 0.02233273 0.6379963 0.1637138 0.1036251 0.7074380 0.1453619 0.4310758
##         V14       V15        V16       V17       V18       V19       V20
## 1 0.1248504 0.3080726 0.04972865 0.3161964 0.2993366 0.6814033 0.7242971
## 2 0.1285492 0.2483381 0.06146634 0.3047504 0.2850145 0.6414470 0.7212867
## 3 0.1280395 0.3767985 0.03349879 0.3556749 0.2891036 0.4673944 0.7268008
## 4 0.1253446 0.1720206 0.04468916 0.2877466 0.4997537 0.5551359 0.7199514
## 5 0.1103950 0.2182678 0.04991160 0.3008108 0.2947892 0.7089925 0.7257416
## 6 0.1287030 0.2404050 0.06048293 0.3066447 0.3024717 0.6498634 0.7227455
##         V21       V22       V23       V24       V25       V26        V27
## 1 0.7015744 0.3904494 0.4864380 0.2485632 0.4866064 0.5625994 0.08419483
## 2 0.6985025 0.3500235 0.4898937 0.2049227 0.4888664 0.6154018 0.08284655
## 3 0.7054162 0.4142768 0.5038540 0.1710326 0.4606858 0.5714028 0.08242462
## 4 0.7002502 0.3778892 0.4851598 0.1276792 0.5176922 0.5567420 0.08351523
## 5 0.7017043 0.4155937 0.4860047 0.2571698 0.4674665 0.6713302 0.08504298
## 6 0.6987645 0.3533250 0.4877981 0.2017432 0.4659661 0.6122371 0.08539026
##         V28    Amount total_amount
## 1 0.3343693 0.7474844    0.3941976
## 2 0.3351134 0.2701701    0.3527213
## 3 0.3335638 0.1026902    0.2832060
## 4 0.3360845 0.2223613    0.2782535
## 5 0.3392722 0.5931224    0.3942216
## 6 0.3364920 0.2855983    0.3114595
#Data Splitting

set.seed(123)
split = sample.split(data_normalized$Class, SplitRatio = 0.8)
training_data = subset(data_normalized, split == TRUE)
test_data= subset(data_normalized, split == FALSE)


nrow(training_data)
## [1] 454904
nrow(test_data)
## [1] 113726
#Data Modelling
library(caret)
## Loading required package: lattice
library(e1071)

#Logistic Regression
set.seed(123)
glm_model = glm(Class~. ,data = training_data, family = binomial(link = 'logit'))
## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred
pred_glm <- predict(glm_model, newdata = test_data, type = 'response')

#Naive Bayes
start_time_nb <- Sys.time()
nb_model <- naiveBayes(Class ~ ., data = training_data)
end_time_nb <- Sys.time()
time_nb <- end_time_nb - start_time_nb

pred_nb <- predict(nb_model, newdata = test_data)
pred_nb_prob <- predict(nb_model, newdata = test_data, type = "raw")[, 2]
#Model Evaluation
library(pROC)
## Type 'citation("pROC")' for a citation.
## 
## Attaching package: 'pROC'
## The following objects are masked from 'package:stats':
## 
##     cov, smooth, var
library(reshape2)
## 
## Attaching package: 'reshape2'
## The following object is masked from 'package:tidyr':
## 
##     smiths
#Logistic Regression
#Convert pred_glm  to factors with common levels
pred_glm <- factor(ifelse(pred_glm > 0.5, 1, 0), levels = c(0, 1))

#Create confusion matrix
confusion <- confusionMatrix(pred_glm, test_data$Class)

#Calculate accuracy
accuracy <- confusion$overall['Accuracy']

#Calculate precision
precision <- confusion$byClass['Pos Pred Value']

#Calculate recall (sensitivity)
recall <- confusion$byClass['Sensitivity']

#Calculate F1-score
f1_score <- confusion$byClass['F1']

#Calculate AUC-ROC using predicted probabilities
roc_auc <- roc(test_data$Class, as.numeric(pred_glm))
## Setting levels: control = 0, case = 1
## Setting direction: controls < cases
auc_roc <- auc(roc_auc)


#Print the metrics
cat("Logistic Regression Metrics:\n")
## Logistic Regression Metrics:
cat("Accuracy:", accuracy, "\n")
## Accuracy: 0.9984964
cat("Precision:", precision, "\n")
## Precision: 0.9981022
cat("Recall:", recall, "\n")
## Recall: 0.9988921
cat("F1-Score:", f1_score, "\n")
## F1-Score: 0.998497
cat("AUC-ROC:", auc_roc, "\n")
## AUC-ROC: 0.9984964
#Model Evaluation
#Naive Bayes

#Create confusion matrix
confusion_nb <- confusionMatrix(pred_nb, test_data$Class)

#Calculate accuracy
accuracy_nb <- confusion_nb$overall['Accuracy']

#Calculate precision
precision_nb <- confusion_nb$byClass['Pos Pred Value']

#Calculate recall (sensitivity)
recall_nb <- confusion_nb$byClass['Sensitivity']

#Calculate F1-score
f1_score_nb <- confusion_nb$byClass['F1']

#Calculate AUC-ROC
nb_probabilities <- predict(nb_model, newdata = test_data, type = "raw")
nb_roc <- roc(test_data$Class, nb_probabilities[, 2])
## Setting levels: control = 0, case = 1
## Setting direction: controls < cases
auc_roc_nb <- auc(nb_roc)

#Print the metrics
cat("Naive Bayes Metrics:\n")
## Naive Bayes Metrics:
cat("Accuracy:", accuracy_nb, "\n")
## Accuracy: 0.9314053
cat("Precision:", precision_nb, "\n")
## Precision: 0.8915563
cat("Recall:", recall_nb, "\n")
## Recall: 0.9822908
cat("F1-Score:", f1_score_nb, "\n")
## F1-Score: 0.9347268
cat("AUC-ROC:", auc_roc_nb, "\n")
## AUC-ROC: 0.9889559
#Compare model performance

#Create a data frame for model evaluation comparison
evaluation_comparison <- data.frame(
  Model = c("Logistic Regression", "Naive Bayes"),
  Accuracy = c(accuracy, accuracy_nb),
  Precision = c(precision, precision_nb),
  Recall = c(recall, recall_nb),
  F1_Score = c(f1_score, f1_score_nb),
  AUC_ROC = c(auc_roc, auc_roc_nb)
)

#Melt the data frame for ggplot2
evaluation_comparison_melted <- melt(evaluation_comparison, id.vars = 'Model')

#Plot
ggplot(evaluation_comparison_melted, aes(x = Model, y = value, fill = variable)) +
  geom_bar(stat = 'identity', position = 'dodge') +
  labs(title = 'Model Evaluation Comparison', x = 'Model', y = 'Score') +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))