Naive Bayes (GaussianNB)

Credit Card Fraud Detection

- Credit card companies need to have the ability to recognize fraudulent credit card transactions so that customers are not charged for items that they did not purchase.

- Datasets contains transactions made by credit cards in September 2013 by european cardholders. This dataset presents transactions that occurred in two days, where we have 492 frauds out of 284,807 transactions. The dataset is highly unbalanced, the positive class (frauds) account for 0.172% of all transactions.

- The data contains only numerical input variables which are the result of a PCA transformation. Unfortunately, due to confidentiality issues, we cannot provide the original features and more background information about the data. 

- Input Features: V1, V2, ... V28 are the principal components obtained with PCA, the only features which have not been transformed with PCA are 'Time' and 'Amount'. Feature 'Time' contains the seconds elapsed between each transaction and the first transaction in the dataset. The feature 'Amount' is the transaction Amount, this feature can be used for example-dependant cost-senstive learning. 

- Output: 1 in case of fraud and 0 otherwise.

Download Dataset

Dr. Ryan @STEMplicity

Importing the Relevant Libraries

In [1]:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
sns.set()

Importing the Dataset

In [2]:
df = pd.read_csv('creditcard.csv')

df.head()
Out[2]:
Time V1 V2 V3 V4 V5 V6 V7 V8 V9 ... V21 V22 V23 V24 V25 V26 V27 V28 Amount Class
0 0.0 -1.359807 -0.072781 2.536347 1.378155 -0.338321 0.462388 0.239599 0.098698 0.363787 ... -0.018307 0.277838 -0.110474 0.066928 0.128539 -0.189115 0.133558 -0.021053 149.62 0
1 0.0 1.191857 0.266151 0.166480 0.448154 0.060018 -0.082361 -0.078803 0.085102 -0.255425 ... -0.225775 -0.638672 0.101288 -0.339846 0.167170 0.125895 -0.008983 0.014724 2.69 0
2 1.0 -1.358354 -1.340163 1.773209 0.379780 -0.503198 1.800499 0.791461 0.247676 -1.514654 ... 0.247998 0.771679 0.909412 -0.689281 -0.327642 -0.139097 -0.055353 -0.059752 378.66 0
3 1.0 -0.966272 -0.185226 1.792993 -0.863291 -0.010309 1.247203 0.237609 0.377436 -1.387024 ... -0.108300 0.005274 -0.190321 -1.175575 0.647376 -0.221929 0.062723 0.061458 123.50 0
4 2.0 -1.158233 0.877737 1.548718 0.403034 -0.407193 0.095921 0.592941 -0.270533 0.817739 ... -0.009431 0.798278 -0.137458 0.141267 -0.206010 0.502292 0.219422 0.215153 69.99 0

5 rows × 31 columns

Number & Percentage of Fraud/Not Fraud

In [3]:
fraud = df[df['Class'] == 1]

not_fraud = df[df['Class'] == 0]

print("Total =", len(df))

print("\nFraud =", len(fraud))
print("Percentage of Fraud = {:.2f} %".format(1.*len(fraud)/len(df)*100.0))
 
print("\nNot Fraud =", len(not_fraud))
print("Percentage of Not Fraud = {:.2f} %".format(1.*len(not_fraud)/len(df)*100.0))
Total = 284807

Fraud = 492
Percentage of Fraud = 0.17 %

Not Fraud = 284315
Percentage of Not Fraud = 99.83 %

Countplot (Fraud/Not Fraud)

In [4]:
sns.countplot(df['Class'], palette= 'Set1')

plt.show()

Heatmap (Relationship between Variables)

In [5]:
plt.figure(figsize=(40,30)) 

corr = df.corr()

matrix = np.triu(corr)

sns.heatmap(corr, annot=True, mask=matrix) 

plt.show()

Kdeplot

In [6]:
column_headers = df.columns.values

i = 1

fig, ax = plt.subplots(8,4,figsize=(18,30))
for column_header in column_headers:    
    plt.subplot(8,4,i)
    sns.kdeplot(fraud[column_header], bw = 0.4, label = "Fraud", shade=True, color="r", linestyle="--")
    sns.kdeplot(not_fraud[column_header], bw = 0.4, label = "Not Fraud", shade=True, color= "y", linestyle=":")
    plt.title(column_header, fontsize=12)
    i = i + 1
plt.show();
/home/bahar/anaconda3/lib/python3.7/site-packages/seaborn/distributions.py:283: UserWarning: Data must have variance to compute a kernel density estimate.
  warnings.warn(msg, UserWarning)
/home/bahar/anaconda3/lib/python3.7/site-packages/seaborn/distributions.py:283: UserWarning: Data must have variance to compute a kernel density estimate.
  warnings.warn(msg, UserWarning)

Declaring the Dependent & the Independent Variables

In [7]:
X = df.iloc[:, :-1].values

y = df.iloc[:, -1].values

Splitting the Dataset into the Training Set and Test Set

In [8]:
from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.20, random_state = 8)

Feature Scaling

In [9]:
from sklearn.preprocessing import StandardScaler

sc = StandardScaler()

X_train = sc.fit_transform(X_train)

X_test = sc.transform(X_test)

Training the Naive Bayes Model (GaussianNB)

In [10]:
from sklearn.naive_bayes import GaussianNB

model = GaussianNB()

model.fit(X_train, y_train)
Out[10]:
GaussianNB()

Predicting the Test Set Results

In [11]:
y_pred = model.predict(X_test)

Confusion Matrix

In [12]:
from sklearn.metrics import confusion_matrix, accuracy_score

cm = confusion_matrix(y_test, y_pred)

accuracy = accuracy_score(y_test, y_pred)

print("Accuracy is: {:.2f} %".format(accuracy*100))

sns.heatmap(cm, annot=True, fmt='d')

plt.show()
Accuracy is: 97.83 %

Classification Report

In [13]:
from sklearn.metrics import classification_report

print(classification_report(y_test, y_pred))
              precision    recall  f1-score   support

           0       1.00      0.98      0.99     56861
           1       0.07      0.87      0.12       101

    accuracy                           0.98     56962
   macro avg       0.53      0.92      0.56     56962
weighted avg       1.00      0.98      0.99     56962

K-Fold Cross Validation

In [14]:
from sklearn.model_selection import cross_val_score

accuracies = cross_val_score(estimator = model, X = X_train, y = y_train, cv = 10)

print("Accuracy: {:.2f} %".format(accuracies.mean()*100))

print("Standard Deviation: {:.2f} %".format(accuracies.std()*100))
Accuracy: 97.79 %
Standard Deviation: 0.11 %

Improving the Model

Remove Similar Features

In [15]:
df2 = df.drop(['Time','V8','V13','V15','V20','V22','V23','V24','V25','V26','V27','V28'], axis = 1)

df2.head()
Out[15]:
V1 V2 V3 V4 V5 V6 V7 V9 V10 V11 V12 V14 V16 V17 V18 V19 V21 Amount Class
0 -1.359807 -0.072781 2.536347 1.378155 -0.338321 0.462388 0.239599 0.363787 0.090794 -0.551600 -0.617801 -0.311169 -0.470401 0.207971 0.025791 0.403993 -0.018307 149.62 0
1 1.191857 0.266151 0.166480 0.448154 0.060018 -0.082361 -0.078803 -0.255425 -0.166974 1.612727 1.065235 -0.143772 0.463917 -0.114805 -0.183361 -0.145783 -0.225775 2.69 0
2 -1.358354 -1.340163 1.773209 0.379780 -0.503198 1.800499 0.791461 -1.514654 0.207643 0.624501 0.066084 -0.165946 -2.890083 1.109969 -0.121359 -2.261857 0.247998 378.66 0
3 -0.966272 -0.185226 1.792993 -0.863291 -0.010309 1.247203 0.237609 -1.387024 -0.054952 -0.226487 0.178228 -0.287924 -1.059647 -0.684093 1.965775 -1.232622 -0.108300 123.50 0
4 -1.158233 0.877737 1.548718 0.403034 -0.407193 0.095921 0.592941 0.817739 0.753074 -0.822843 0.538196 -1.119670 -0.451449 -0.237033 -0.038195 0.803487 -0.009431 69.99 0

Declaring the Dependent & the Independent Variables

In [16]:
X = df2.iloc[:, :-1].values

y = df2.iloc[:, -1].values

Splitting the Dataset into the Training Set and Test Set

In [17]:
from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.20, random_state = 8)

Feature Scaling

In [18]:
from sklearn.preprocessing import StandardScaler

sc = StandardScaler()

X_train = sc.fit_transform(X_train)

X_test = sc.transform(X_test)

Training the Naive Bayes Model (GaussianNB)

In [19]:
from sklearn.naive_bayes import GaussianNB

model = GaussianNB()

model.fit(X_train, y_train)
Out[19]:
GaussianNB()

Predicting the Test Set Results

In [20]:
y_pred = model.predict(X_test)

Confusion Matrix

In [21]:
from sklearn.metrics import confusion_matrix, accuracy_score

cm = confusion_matrix(y_test, y_pred)

accuracy = accuracy_score(y_test, y_pred)

print("Accuracy is: {:.2f} %".format(accuracy*100))

sns.heatmap(cm, annot=True, fmt='d')

plt.show()
Accuracy is: 98.45 %

Classification Report

In [22]:
from sklearn.metrics import classification_report

print(classification_report(y_test, y_pred))
              precision    recall  f1-score   support

           0       1.00      0.98      0.99     56861
           1       0.09      0.90      0.17       101

    accuracy                           0.98     56962
   macro avg       0.55      0.94      0.58     56962
weighted avg       1.00      0.98      0.99     56962

K-Fold Cross Validation

In [23]:
from sklearn.model_selection import cross_val_score

accuracies = cross_val_score(estimator = model, X = X_train, y = y_train, cv = 10)

print("Accuracy: {:.2f} %".format(accuracies.mean()*100))

print("Standard Deviation: {:.2f} %".format(accuracies.std()*100))
Accuracy: 98.44 %
Standard Deviation: 0.08 %