1. Importing the Required Files, Scales, Algorithms, Metrics and Warnings¶

In [1]:
# Importing the required files to provide the correlation and confusion matrices

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

# Scaling the data using z-score to standardise the data 

from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split, GridSearchCV

# Algortihms being used for the customer churn prediction models

from sklearn.linear_model import LogisticRegression
from sklearn.svm import SVC

# Metrics to evaluate models (including precision and f1 scores)

from sklearn import metrics
from sklearn.metrics import confusion_matrix, classification_report, precision_recall_curve, recall_score, roc_auc_score, accuracy_score, precision_score, f1_score

# Ignoring any warnings

import warnings
warnings.filterwarnings("ignore")

# Inserting and loading the dataset using the below filepath 

df = pd.read_excel('C:/Telco_Customer_Churn.xlsx')

2. Checking and Understanding the Dataset¶

In [2]:
# Checking the first 5 rows of the dataset to ensure the dataset has loaded correctly

df.head()
Out[2]:
CustomerID Count Country State City Zip Code Lat Long Latitude Longitude Gender ... Contract Paperless Billing Payment Method Monthly Charges Total Charges Churn Label Churn Value Churn Score CLTV Churn Reason
0 3668-QPYBK 1 United States California Los Angeles 90003 33.964131, -118.272783 33.964131 -118.272783 Male ... Month-to-month Yes Mailed check 53.85 108.15 Yes 1 86 3239 Competitor made better offer
1 9237-HQITU 1 United States California Los Angeles 90005 34.059281, -118.30742 34.059281 -118.307420 Female ... Month-to-month Yes Electronic check 70.70 151.65 Yes 1 67 2701 Moved
2 9305-CDSKC 1 United States California Los Angeles 90006 34.048013, -118.293953 34.048013 -118.293953 Female ... Month-to-month Yes Electronic check 99.65 820.5 Yes 1 86 5372 Moved
3 7892-POOKP 1 United States California Los Angeles 90010 34.062125, -118.315709 34.062125 -118.315709 Female ... Month-to-month Yes Electronic check 104.80 3046.05 Yes 1 84 5003 Moved
4 0280-XJGEX 1 United States California Los Angeles 90015 34.039224, -118.266293 34.039224 -118.266293 Male ... Month-to-month Yes Bank transfer (automatic) 103.70 5036.3 Yes 1 89 5340 Competitor had better devices

5 rows × 33 columns

In [3]:
# Checking the first 5 rows of the dataset to ensure the dataset has loaded correctly

df.tail()
Out[3]:
CustomerID Count Country State City Zip Code Lat Long Latitude Longitude Gender ... Contract Paperless Billing Payment Method Monthly Charges Total Charges Churn Label Churn Value Churn Score CLTV Churn Reason
7038 2569-WGERO 1 United States California Landers 92285 34.341737, -116.539416 34.341737 -116.539416 Female ... Two year Yes Bank transfer (automatic) 21.15 1419.4 No 0 45 5306 NaN
7039 6840-RESVB 1 United States California Adelanto 92301 34.667815, -117.536183 34.667815 -117.536183 Male ... One year Yes Mailed check 84.80 1990.5 No 0 59 2140 NaN
7040 2234-XADUH 1 United States California Amboy 92304 34.559882, -115.637164 34.559882 -115.637164 Female ... One year Yes Credit card (automatic) 103.20 7362.9 No 0 71 5560 NaN
7041 4801-JZAZL 1 United States California Angelus Oaks 92305 34.1678, -116.86433 34.167800 -116.864330 Female ... Month-to-month Yes Electronic check 29.60 346.45 No 0 59 2793 NaN
7042 3186-AJIEK 1 United States California Apple Valley 92308 34.424926, -117.184503 34.424926 -117.184503 Male ... Two year Yes Bank transfer (automatic) 105.65 6844.5 No 0 38 5097 NaN

5 rows × 33 columns

In [4]:
# Checking the statistical overview of the numerical dataset

df.describe()
Out[4]:
Count Zip Code Latitude Longitude Tenure Months Monthly Charges Churn Value Churn Score CLTV
count 7043.0 7043.000000 7043.000000 7043.000000 7043.000000 7043.000000 7043.000000 7043.000000 7043.000000
mean 1.0 93521.964646 36.282441 -119.798880 32.371149 64.761692 0.265370 58.699418 4400.295755
std 0.0 1865.794555 2.455723 2.157889 24.559481 30.090047 0.441561 21.525131 1183.057152
min 1.0 90001.000000 32.555828 -124.301372 0.000000 18.250000 0.000000 5.000000 2003.000000
25% 1.0 92102.000000 34.030915 -121.815412 9.000000 35.500000 0.000000 40.000000 3469.000000
50% 1.0 93552.000000 36.391777 -119.730885 29.000000 70.350000 0.000000 61.000000 4527.000000
75% 1.0 95351.000000 38.224869 -118.043237 55.000000 89.850000 1.000000 75.000000 5380.500000
max 1.0 96161.000000 41.962127 -114.192901 72.000000 118.750000 1.000000 100.000000 6500.000000
In [5]:
# Checking the data types and any missing values from the dataset to understand what the data shows

df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 7043 entries, 0 to 7042
Data columns (total 33 columns):
 #   Column             Non-Null Count  Dtype  
---  ------             --------------  -----  
 0   CustomerID         7043 non-null   object 
 1   Count              7043 non-null   int64  
 2   Country            7043 non-null   object 
 3   State              7043 non-null   object 
 4   City               7043 non-null   object 
 5   Zip Code           7043 non-null   int64  
 6   Lat Long           7043 non-null   object 
 7   Latitude           7043 non-null   float64
 8   Longitude          7043 non-null   float64
 9   Gender             7043 non-null   object 
 10  Senior Citizen     7043 non-null   object 
 11  Partner            7043 non-null   object 
 12  Dependents         7043 non-null   object 
 13  Tenure Months      7043 non-null   int64  
 14  Phone Service      7043 non-null   object 
 15  Multiple Lines     7043 non-null   object 
 16  Internet Service   7043 non-null   object 
 17  Online Security    7043 non-null   object 
 18  Online Backup      7043 non-null   object 
 19  Device Protection  7043 non-null   object 
 20  Tech Support       7043 non-null   object 
 21  Streaming TV       7043 non-null   object 
 22  Streaming Movies   7043 non-null   object 
 23  Contract           7043 non-null   object 
 24  Paperless Billing  7043 non-null   object 
 25  Payment Method     7043 non-null   object 
 26  Monthly Charges    7043 non-null   float64
 27  Total Charges      7043 non-null   object 
 28  Churn Label        7043 non-null   object 
 29  Churn Value        7043 non-null   int64  
 30  Churn Score        7043 non-null   int64  
 31  CLTV               7043 non-null   int64  
 32  Churn Reason       1869 non-null   object 
dtypes: float64(3), int64(6), object(24)
memory usage: 1.8+ MB
In [6]:
# Checking the dataset for any unique values

df.nunique()
Out[6]:
CustomerID           7043
Count                   1
Country                 1
State                   1
City                 1129
Zip Code             1652
Lat Long             1652
Latitude             1652
Longitude            1651
Gender                  2
Senior Citizen          2
Partner                 2
Dependents              2
Tenure Months          73
Phone Service           2
Multiple Lines          3
Internet Service        3
Online Security         3
Online Backup           3
Device Protection       3
Tech Support            3
Streaming TV            3
Streaming Movies        3
Contract                3
Paperless Billing       2
Payment Method          4
Monthly Charges      1585
Total Charges        6531
Churn Label             2
Churn Value             2
Churn Score            85
CLTV                 3438
Churn Reason           20
dtype: int64

3. Cleansing the Dataset¶

In [7]:
# Dropping columns with only one unique value overall or every vakue being unique to remove unnecessary data for model predictions 

# For reference, the column dropped and unique value are:

# Count value is '1'
# Country value is 'United States'
# State value is 'California'

df=df.drop(['Count','Country','State','CustomerID','Lat Long','Zip Code','Latitude','Longitude'],axis=1) # axis=1 is for columns.

# Changing any blank Churn Reason to 'Unknown'

df['Churn Reason'].fillna('Unknown', inplace=True)

# Changing data to numerical values

num_cols=['Tenure Months','Monthly Charges','Total Charges','Churn Value','Churn Score','CLTV']
df[num_cols] = df[num_cols].apply(pd.to_numeric, errors='coerce')

# Dropping rows with NaN values in numerical columns

df = df.dropna(subset=num_cols)

# Changing data to categorical variables

cat_cols=['City','Gender','Senior Citizen','Partner','Dependents','Phone Service','Multiple Lines',
          'Internet Service','Online Security','Online Backup','Device Protection','Tech Support','Streaming TV','Streaming Movies',
          'Contract','Paperless Billing','Payment Method','Churn Label','Churn Reason']

4. Exploratory Data Analysis and Data Preprocessing¶

Univariate Analysis of Numerical Columns¶

In [8]:
# Checking the summarised statistics of the numerical columns after data cleansing

df[num_cols].describe().T
Out[8]:
count mean std min 25% 50% 75% max
Tenure Months 7032.0 32.421786 24.545260 1.00 9.0000 29.000 55.0000 72.00
Monthly Charges 7032.0 64.798208 30.085974 18.25 35.5875 70.350 89.8625 118.75
Total Charges 7032.0 2283.300441 2266.771362 18.80 401.4500 1397.475 3794.7375 8684.80
Churn Value 7032.0 0.265785 0.441782 0.00 0.0000 0.000 1.0000 1.00
Churn Score 7032.0 58.715301 21.531321 5.00 40.0000 61.000 75.0000 100.00
CLTV 7032.0 4401.445108 1182.414266 2003.00 3469.7500 4527.500 5381.0000 6500.00
In [9]:
# Creating the histograms to plot and compare numerical values

axes = df[num_cols].hist(figsize=(14,14))

# Labelling the x and y axes

for ax in axes.flatten():
    ax.set_xlabel('Value')
    ax.set_ylabel('Frequency')

# Display the histograms

plt.show()
No description has been provided for this image

Univariate Analysis for Categorical Variables¶

In [10]:
# Printing the percentage (%) sub categories of each category, rounding to two decimal places

for i in cat_cols:
    print(df[i].value_counts (normalize=True).round(4) * 100)
    print('*'*40)
City
Los Angeles      4.32
San Diego        2.13
San Jose         1.59
Sacramento       1.54
San Francisco    1.48
                 ... 
Point Arena      0.06
Independence     0.04
Cupertino        0.04
Ben Lomond       0.04
Redcrest         0.04
Name: proportion, Length: 1129, dtype: float64
****************************************
Gender
Male      50.47
Female    49.53
Name: proportion, dtype: float64
****************************************
Senior Citizen
No     83.76
Yes    16.24
Name: proportion, dtype: float64
****************************************
Partner
No     51.75
Yes    48.25
Name: proportion, dtype: float64
****************************************
Dependents
No     76.96
Yes    23.04
Name: proportion, dtype: float64
****************************************
Phone Service
Yes    90.33
No      9.67
Name: proportion, dtype: float64
****************************************
Multiple Lines
No                  48.14
Yes                 42.19
No phone service     9.67
Name: proportion, dtype: float64
****************************************
Internet Service
Fiber optic    44.03
DSL            34.36
No             21.62
Name: proportion, dtype: float64
****************************************
Online Security
No                     49.73
Yes                    28.65
No internet service    21.62
Name: proportion, dtype: float64
****************************************
Online Backup
No                     43.90
Yes                    34.49
No internet service    21.62
Name: proportion, dtype: float64
****************************************
Device Protection
No                     44.00
Yes                    34.39
No internet service    21.62
Name: proportion, dtype: float64
****************************************
Tech Support
No                     49.37
Yes                    29.01
No internet service    21.62
Name: proportion, dtype: float64
****************************************
Streaming TV
No                     39.95
Yes                    38.44
No internet service    21.62
Name: proportion, dtype: float64
****************************************
Streaming Movies
No                     39.55
Yes                    38.84
No internet service    21.62
Name: proportion, dtype: float64
****************************************
Contract
Month-to-month    55.11
Two year          23.96
One year          20.93
Name: proportion, dtype: float64
****************************************
Paperless Billing
Yes    59.27
No     40.73
Name: proportion, dtype: float64
****************************************
Payment Method
Electronic check             33.63
Mailed check                 22.81
Bank transfer (automatic)    21.93
Credit card (automatic)      21.63
Name: proportion, dtype: float64
****************************************
Churn Label
No     73.42
Yes    26.58
Name: proportion, dtype: float64
****************************************
Churn Reason
Unknown                                      73.42
Attitude of support person                    2.73
Competitor offered higher download speeds     2.69
Competitor offered more data                  2.30
Don't know                                    2.19
Competitor made better offer                  1.99
Attitude of service provider                  1.92
Competitor had better devices                 1.85
Network reliability                           1.46
Product dissatisfaction                       1.45
Price too high                                1.39
Service dissatisfaction                       1.27
Lack of self-service on Website               1.25
Extra data charges                            0.81
Moved                                         0.75
Lack of affordable download/upload speed      0.63
Long distance charges                         0.63
Limited range of services                     0.63
Poor expertise of phone support               0.28
Poor expertise of online support              0.27
Deceased                                      0.09
Name: proportion, dtype: float64
****************************************

Bivariate and Multivariate Analysis for Categorical Variables¶

In [11]:
# Excluding the columns from the graph creation

exclude_columns = ['Count','Country','State','CustomerID','Lat Long','Zip Code','Latitude','Longitude']  # List of columns to exclude

# Checking how 'Churn Label' is related to other categorical variables

for i in cat_cols:
    if i != 'Churn Label' and i not in exclude_columns:
        (pd.crosstab(df[i], df['Churn Label'], normalize='index') * 100).plot(kind='bar', figsize=(8, 4), stacked=True)
        plt.ylabel('Percentage Churn %')
        plt.title(f'Relationship between {i} and Churn Label')
        plt.show()
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
In [12]:
# Checking the relationship between different numerical variables

# Checking for non-numeric values in numerical columns and converting them to NaN

for col in num_cols:
    df[col] = pd.to_numeric(df[col], errors='coerce')

# Plotting the correlation between numerical variables to two decimal places

plt.figure(figsize=(15, 8))
sns.heatmap(df[num_cols].corr(), annot=True, fmt='.2f', cmap='YlOrRd')
plt.title('Correlation Matrix of Numerical Variables')
plt.show()
No description has been provided for this image

5. Data Preparation¶

Creating Dummy Variables for Categorical Variables¶

In [13]:
# Creating a list of dummy columns

to_get_dummies_for = ['City', 'Gender', 'Senior Citizen', 'Partner', 'Dependents', 'Phone Service', 'Multiple Lines',
                      'Internet Service', 'Online Security', 'Online Backup', 'Device Protection', 'Tech Support',
                      'Streaming TV', 'Streaming Movies', 'Contract', 'Paperless Billing', 'Payment Method', 'Churn Reason']

# Creating the dummy variables

df = pd.get_dummies(data=df, columns=to_get_dummies_for, drop_first=True)

# Mapping Churn Label to 'Yes' and 'No'

df['Churn Label'] = df['Churn Label'].map({'Yes': 1, 'No': 0})

Separating Independent Variables (X) and Dependent Variable (Y)¶

In [14]:
# Separating the target variable and other variables

Y = df['Churn Label']
X = df.drop(columns=['Churn Label'])

Splitting the Data into 70% Train and 30% Test Set¶

In [15]:
# Splitting the data to 70% training and 30% test

x_train, x_test, y_train, y_test = train_test_split(X, Y, test_size = 0.3, random_state = 1, stratify = Y)

# Scaling the data to standardise the data to remove the mean and scale to variance

sc = StandardScaler()

# Transforming the training data

x_train_scaled = sc.fit_transform(x_train)
x_train_scaled = pd.DataFrame(x_train_scaled, columns = X.columns)

# Transforming the test data

x_test_scaled = sc.transform(x_test)
x_test_scaled = pd.DataFrame(x_test_scaled, columns = X.columns)
In [16]:
# Creating the confusion metric function, as well as providing the 'Actual' and Predicted' values and whether to 'Churn or Not Churn'.

def metrics_score(actual, predicted):
    print(classification_report(actual, predicted))

    cm = confusion_matrix(actual, predicted)
    plt.figure(figsize = (8,5))

    sns.heatmap(cm, annot = True, fmt = '.2f', xticklabels = ['Not Churn', 'Churn'], yticklabels = ['Not Churn', 'Churn'])
    plt.ylabel('Actual')
    plt.xlabel('Predicted')
    plt.title('Confusion Matrix')
    plt.show()

6. Implementing the Logistic Regression Model¶

In [17]:
# Fitting the Logistic Regression model

lg = LogisticRegression()
lg.fit(x_train_scaled, y_train)
Out[17]:
LogisticRegression()
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
LogisticRegression()
In [18]:
# Checking the Logistic Regression performance on the training dataset

y_pred_train = lg.predict(x_train_scaled)
metrics_score(y_train, y_pred_train)

# Hyperparameter tuning for Logistic Regression training

param_grid_log_reg = {
    'C': [0.01, 0.1, 1, 10, 100],   # Regularisation, with smaller values being stronger 
    'solver': ['liblinear', 'saga'] # Optimising algortihms
}
grid_search_log_reg = GridSearchCV(LogisticRegression(max_iter=1000), param_grid_log_reg, cv=3, verbose=2)
grid_search_log_reg.fit(x_train_scaled, y_train)

# Finding the best parameters for Logistic Regression training

best_params_log_reg = grid_search_log_reg.best_params_
print("Best Hyperparameters for Logistic Regression:", best_params_log_reg)

# Evaluating Logistic Regression model on the train set

best_log_reg_model = grid_search_log_reg.best_estimator_
y_pred_log_reg = best_log_reg_model.predict(x_train_scaled)
print("Logistic Regression Classification Report:")
print(classification_report(y_train, y_pred_log_reg))
              precision    recall  f1-score   support

           0       1.00      1.00      1.00      3614
           1       1.00      1.00      1.00      1308

    accuracy                           1.00      4922
   macro avg       1.00      1.00      1.00      4922
weighted avg       1.00      1.00      1.00      4922

No description has been provided for this image
Fitting 3 folds for each of 10 candidates, totalling 30 fits
[CV] END ...........................C=0.01, solver=liblinear; total time=   0.3s
[CV] END ...........................C=0.01, solver=liblinear; total time=   0.3s
[CV] END ...........................C=0.01, solver=liblinear; total time=   0.3s
[CV] END ................................C=0.01, solver=saga; total time=   5.6s
[CV] END ................................C=0.01, solver=saga; total time=   6.2s
[CV] END ................................C=0.01, solver=saga; total time=   5.3s
[CV] END ............................C=0.1, solver=liblinear; total time=   0.4s
[CV] END ............................C=0.1, solver=liblinear; total time=   0.3s
[CV] END ............................C=0.1, solver=liblinear; total time=   0.3s
[CV] END .................................C=0.1, solver=saga; total time=   8.3s
[CV] END .................................C=0.1, solver=saga; total time=   4.4s
[CV] END .................................C=0.1, solver=saga; total time=  12.8s
[CV] END ..............................C=1, solver=liblinear; total time=   0.4s
[CV] END ..............................C=1, solver=liblinear; total time=   0.4s
[CV] END ..............................C=1, solver=liblinear; total time=   0.4s
[CV] END ...................................C=1, solver=saga; total time=  16.7s
[CV] END ...................................C=1, solver=saga; total time=  17.2s
[CV] END ...................................C=1, solver=saga; total time=  16.2s
[CV] END .............................C=10, solver=liblinear; total time=   0.6s
[CV] END .............................C=10, solver=liblinear; total time=   0.5s
[CV] END .............................C=10, solver=liblinear; total time=   0.6s
[CV] END ..................................C=10, solver=saga; total time=  30.3s
[CV] END ..................................C=10, solver=saga; total time=  29.6s
[CV] END ..................................C=10, solver=saga; total time=  30.4s
[CV] END ............................C=100, solver=liblinear; total time=   0.5s
[CV] END ............................C=100, solver=liblinear; total time=   0.5s
[CV] END ............................C=100, solver=liblinear; total time=   0.5s
[CV] END .................................C=100, solver=saga; total time=  29.6s
[CV] END .................................C=100, solver=saga; total time=  29.8s
[CV] END .................................C=100, solver=saga; total time=  29.6s
Best Hyperparameters for Logistic Regression: {'C': 0.01, 'solver': 'liblinear'}
Logistic Regression Classification Report:
              precision    recall  f1-score   support

           0       1.00      1.00      1.00      3614
           1       1.00      1.00      1.00      1308

    accuracy                           1.00      4922
   macro avg       1.00      1.00      1.00      4922
weighted avg       1.00      1.00      1.00      4922

In [19]:
# Checking the Logistic Regression performance on the test dataset

y_pred_test = lg.predict(x_test_scaled)
metrics_score(y_test, y_pred_test)

# Hyperparameter tuning for Logistic Regression test

param_grid_log_reg = {
    'C': [0.01, 0.1, 1, 10, 100],   # Regularisation, with smaller values being stronger 
    'solver': ['liblinear', 'saga'] # Optimising algortihms
}
grid_search_log_reg = GridSearchCV(LogisticRegression(max_iter=1000), param_grid_log_reg, cv=3, verbose=2)
grid_search_log_reg.fit(x_test_scaled, y_test)

# Finding the best parameters for Logistic Regression testing

best_params_log_reg = grid_search_log_reg.best_params_
print("Best Hyperparameters for Logistic Regression:", best_params_log_reg)

# Evaluating the best Logistic Regression model on the test set

best_log_reg_model = grid_search_log_reg.best_estimator_
y_pred_log_reg = best_log_reg_model.predict(x_test_scaled)
print("Logistic Regression Classification Report:")
print(classification_report(y_test, y_pred_log_reg))
              precision    recall  f1-score   support

           0       1.00      1.00      1.00      1549
           1       1.00      1.00      1.00       561

    accuracy                           1.00      2110
   macro avg       1.00      1.00      1.00      2110
weighted avg       1.00      1.00      1.00      2110

No description has been provided for this image
Fitting 3 folds for each of 10 candidates, totalling 30 fits
[CV] END ...........................C=0.01, solver=liblinear; total time=   0.1s
[CV] END ...........................C=0.01, solver=liblinear; total time=   0.1s
[CV] END ...........................C=0.01, solver=liblinear; total time=   0.1s
[CV] END ................................C=0.01, solver=saga; total time=   2.8s
[CV] END ................................C=0.01, solver=saga; total time=   2.7s
[CV] END ................................C=0.01, solver=saga; total time=   2.9s
[CV] END ............................C=0.1, solver=liblinear; total time=   0.2s
[CV] END ............................C=0.1, solver=liblinear; total time=   0.2s
[CV] END ............................C=0.1, solver=liblinear; total time=   0.2s
[CV] END .................................C=0.1, solver=saga; total time=   5.6s
[CV] END .................................C=0.1, solver=saga; total time=   4.6s
[CV] END .................................C=0.1, solver=saga; total time=   6.2s
[CV] END ..............................C=1, solver=liblinear; total time=   0.2s
[CV] END ..............................C=1, solver=liblinear; total time=   0.3s
[CV] END ..............................C=1, solver=liblinear; total time=   0.3s
[CV] END ...................................C=1, solver=saga; total time=   8.4s
[CV] END ...................................C=1, solver=saga; total time=   8.3s
[CV] END ...................................C=1, solver=saga; total time=   8.5s
[CV] END .............................C=10, solver=liblinear; total time=   0.3s
[CV] END .............................C=10, solver=liblinear; total time=   0.3s
[CV] END .............................C=10, solver=liblinear; total time=   0.3s
[CV] END ..................................C=10, solver=saga; total time=  12.4s
[CV] END ..................................C=10, solver=saga; total time=  12.4s
[CV] END ..................................C=10, solver=saga; total time=  12.5s
[CV] END ............................C=100, solver=liblinear; total time=   0.3s
[CV] END ............................C=100, solver=liblinear; total time=   0.3s
[CV] END ............................C=100, solver=liblinear; total time=   0.3s
[CV] END .................................C=100, solver=saga; total time=  12.4s
[CV] END .................................C=100, solver=saga; total time=  12.3s
[CV] END .................................C=100, solver=saga; total time=  12.3s
Best Hyperparameters for Logistic Regression: {'C': 0.1, 'solver': 'liblinear'}
Logistic Regression Classification Report:
              precision    recall  f1-score   support

           0       1.00      1.00      1.00      1549
           1       1.00      1.00      1.00       561

    accuracy                           1.00      2110
   macro avg       1.00      1.00      1.00      2110
weighted avg       1.00      1.00      1.00      2110

In [20]:
# Checking and printing the coefficients of Logistic Regression to find variables leading to churning and not churning

cols = X.columns
coef_lg = lg.coef_
pd.DataFrame(coef_lg, columns = cols).T.sort_values(by = 0, ascending = False)
Out[20]:
0
Churn Value 2.392259
Churn Score 0.808473
Churn Reason_Attitude of support person 0.502931
Churn Reason_Competitor offered higher download speeds 0.492066
Churn Reason_Competitor offered more data 0.470662
... ...
Total Charges -0.147175
Dependents_Yes -0.158703
Contract_Two year -0.165549
Tenure Months -0.233913
Churn Reason_Unknown -2.392259

1181 rows × 1 columns

The coefficients of the logisitcal regression model give us the log of odds, which is hard to interpret in the real world. We can convert the log of odds into real odds by taking its exponential.

In [21]:
# Finding the odds

odds = np.exp(lg.coef_[0])

# Adding the odds to a dataframe and sorting the values

pd.DataFrame(odds, x_train_scaled.columns, columns = ['odds']).sort_values(by = 'odds', ascending = False)
Out[21]:
odds
Churn Value 10.938171
Churn Score 2.244478
Churn Reason_Attitude of support person 1.653560
Churn Reason_Competitor offered higher download speeds 1.635692
Churn Reason_Competitor offered more data 1.601055
... ...
Total Charges 0.863143
Dependents_Yes 0.853249
Contract_Two year 0.847428
Tenure Months 0.791431
Churn Reason_Unknown 0.091423

1181 rows × 1 columns

7. Implementing the Support Vector Machine Model¶

In [22]:
# Fitting the Support Vector Machine model

svm = SVC(kernel = 'linear')
svm.fit(x_train_scaled, y_train)
Out[22]:
SVC(kernel='linear')
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
SVC(kernel='linear')
In [23]:
# Checking the Support Vector Machine performance on the training dataset

y_pred_train = svm.predict(x_train_scaled)
metrics_score(y_train, y_pred_train)

# Hyperparameter tuning for Support Vector Machine training

param_grid_svm = {
    'C': [0.1, 1, 10, 100],
    'gamma': [1, 0.1, 0.01, 0.001],
    'kernel': ['rbf', 'linear']
}
grid_search_svm = GridSearchCV(SVC(), param_grid_svm, cv=3, verbose=2)
grid_search_svm.fit(x_train_scaled, y_train)

# Finding the best parameters for Support Vector Machine training

best_params_svm = grid_search_svm.best_params_
print("Best Hyperparameters for SVM:", best_params_svm)

# Evaluating Support Vector Machine model on the train set

best_svm_model = grid_search_svm.best_estimator_
y_pred_svm = best_svm_model.predict(x_train_scaled)
print("Support Vector Machine Classification Report:")
print(classification_report(y_train, y_pred_svm))
              precision    recall  f1-score   support

           0       1.00      1.00      1.00      3614
           1       1.00      1.00      1.00      1308

    accuracy                           1.00      4922
   macro avg       1.00      1.00      1.00      4922
weighted avg       1.00      1.00      1.00      4922

No description has been provided for this image
Fitting 3 folds for each of 32 candidates, totalling 96 fits
[CV] END .........................C=0.1, gamma=1, kernel=rbf; total time=   9.7s
[CV] END .........................C=0.1, gamma=1, kernel=rbf; total time=   9.5s
[CV] END .........................C=0.1, gamma=1, kernel=rbf; total time=   9.5s
[CV] END ......................C=0.1, gamma=1, kernel=linear; total time=   0.6s
[CV] END ......................C=0.1, gamma=1, kernel=linear; total time=   0.9s
[CV] END ......................C=0.1, gamma=1, kernel=linear; total time=   0.8s
[CV] END .......................C=0.1, gamma=0.1, kernel=rbf; total time=   9.3s
[CV] END .......................C=0.1, gamma=0.1, kernel=rbf; total time=   9.1s
[CV] END .......................C=0.1, gamma=0.1, kernel=rbf; total time=   9.1s
[CV] END ....................C=0.1, gamma=0.1, kernel=linear; total time=   0.6s
[CV] END ....................C=0.1, gamma=0.1, kernel=linear; total time=   0.9s
[CV] END ....................C=0.1, gamma=0.1, kernel=linear; total time=   0.8s
[CV] END ......................C=0.1, gamma=0.01, kernel=rbf; total time=   8.6s
[CV] END ......................C=0.1, gamma=0.01, kernel=rbf; total time=   8.5s
[CV] END ......................C=0.1, gamma=0.01, kernel=rbf; total time=   8.6s
[CV] END ...................C=0.1, gamma=0.01, kernel=linear; total time=   0.6s
[CV] END ...................C=0.1, gamma=0.01, kernel=linear; total time=   0.9s
[CV] END ...................C=0.1, gamma=0.01, kernel=linear; total time=   0.8s
[CV] END .....................C=0.1, gamma=0.001, kernel=rbf; total time=   6.2s
[CV] END .....................C=0.1, gamma=0.001, kernel=rbf; total time=   6.5s
[CV] END .....................C=0.1, gamma=0.001, kernel=rbf; total time=   6.3s
[CV] END ..................C=0.1, gamma=0.001, kernel=linear; total time=   0.6s
[CV] END ..................C=0.1, gamma=0.001, kernel=linear; total time=   0.9s
[CV] END ..................C=0.1, gamma=0.001, kernel=linear; total time=   0.7s
[CV] END ...........................C=1, gamma=1, kernel=rbf; total time=  10.2s
[CV] END ...........................C=1, gamma=1, kernel=rbf; total time=  10.9s
[CV] END ...........................C=1, gamma=1, kernel=rbf; total time=   9.9s
[CV] END ........................C=1, gamma=1, kernel=linear; total time=   0.7s
[CV] END ........................C=1, gamma=1, kernel=linear; total time=   1.1s
[CV] END ........................C=1, gamma=1, kernel=linear; total time=   0.8s
[CV] END .........................C=1, gamma=0.1, kernel=rbf; total time=   9.1s
[CV] END .........................C=1, gamma=0.1, kernel=rbf; total time=   9.3s
[CV] END .........................C=1, gamma=0.1, kernel=rbf; total time=   9.0s
[CV] END ......................C=1, gamma=0.1, kernel=linear; total time=   0.6s
[CV] END ......................C=1, gamma=0.1, kernel=linear; total time=   0.9s
[CV] END ......................C=1, gamma=0.1, kernel=linear; total time=   0.8s
[CV] END ........................C=1, gamma=0.01, kernel=rbf; total time=   8.7s
[CV] END ........................C=1, gamma=0.01, kernel=rbf; total time=   8.7s
[CV] END ........................C=1, gamma=0.01, kernel=rbf; total time=   9.1s
[CV] END .....................C=1, gamma=0.01, kernel=linear; total time=   0.6s
[CV] END .....................C=1, gamma=0.01, kernel=linear; total time=   1.0s
[CV] END .....................C=1, gamma=0.01, kernel=linear; total time=   0.8s
[CV] END .......................C=1, gamma=0.001, kernel=rbf; total time=   5.0s
[CV] END .......................C=1, gamma=0.001, kernel=rbf; total time=   5.0s
[CV] END .......................C=1, gamma=0.001, kernel=rbf; total time=   4.8s
[CV] END ....................C=1, gamma=0.001, kernel=linear; total time=   0.5s
[CV] END ....................C=1, gamma=0.001, kernel=linear; total time=   0.9s
[CV] END ....................C=1, gamma=0.001, kernel=linear; total time=   0.8s
[CV] END ..........................C=10, gamma=1, kernel=rbf; total time=  10.5s
[CV] END ..........................C=10, gamma=1, kernel=rbf; total time=  10.3s
[CV] END ..........................C=10, gamma=1, kernel=rbf; total time=  10.2s
[CV] END .......................C=10, gamma=1, kernel=linear; total time=   0.6s
[CV] END .......................C=10, gamma=1, kernel=linear; total time=   1.0s
[CV] END .......................C=10, gamma=1, kernel=linear; total time=   0.8s
[CV] END ........................C=10, gamma=0.1, kernel=rbf; total time=   9.6s
[CV] END ........................C=10, gamma=0.1, kernel=rbf; total time=   9.7s
[CV] END ........................C=10, gamma=0.1, kernel=rbf; total time=   9.6s
[CV] END .....................C=10, gamma=0.1, kernel=linear; total time=   0.6s
[CV] END .....................C=10, gamma=0.1, kernel=linear; total time=   0.9s
[CV] END .....................C=10, gamma=0.1, kernel=linear; total time=   0.9s
[CV] END .......................C=10, gamma=0.01, kernel=rbf; total time=   9.1s
[CV] END .......................C=10, gamma=0.01, kernel=rbf; total time=   9.3s
[CV] END .......................C=10, gamma=0.01, kernel=rbf; total time=   9.1s
[CV] END ....................C=10, gamma=0.01, kernel=linear; total time=   0.6s
[CV] END ....................C=10, gamma=0.01, kernel=linear; total time=   0.9s
[CV] END ....................C=10, gamma=0.01, kernel=linear; total time=   0.7s
[CV] END ......................C=10, gamma=0.001, kernel=rbf; total time=   3.9s
[CV] END ......................C=10, gamma=0.001, kernel=rbf; total time=   3.6s
[CV] END ......................C=10, gamma=0.001, kernel=rbf; total time=   3.6s
[CV] END ...................C=10, gamma=0.001, kernel=linear; total time=   0.6s
[CV] END ...................C=10, gamma=0.001, kernel=linear; total time=   0.9s
[CV] END ...................C=10, gamma=0.001, kernel=linear; total time=   0.7s
[CV] END .........................C=100, gamma=1, kernel=rbf; total time=  10.5s
[CV] END .........................C=100, gamma=1, kernel=rbf; total time=  10.3s
[CV] END .........................C=100, gamma=1, kernel=rbf; total time=  10.3s
[CV] END ......................C=100, gamma=1, kernel=linear; total time=   0.6s
[CV] END ......................C=100, gamma=1, kernel=linear; total time=   0.9s
[CV] END ......................C=100, gamma=1, kernel=linear; total time=   0.8s
[CV] END .......................C=100, gamma=0.1, kernel=rbf; total time=   9.8s
[CV] END .......................C=100, gamma=0.1, kernel=rbf; total time=   9.8s
[CV] END .......................C=100, gamma=0.1, kernel=rbf; total time=   9.5s
[CV] END ....................C=100, gamma=0.1, kernel=linear; total time=   0.6s
[CV] END ....................C=100, gamma=0.1, kernel=linear; total time=   0.9s
[CV] END ....................C=100, gamma=0.1, kernel=linear; total time=   0.8s
[CV] END ......................C=100, gamma=0.01, kernel=rbf; total time=   9.4s
[CV] END ......................C=100, gamma=0.01, kernel=rbf; total time=   9.2s
[CV] END ......................C=100, gamma=0.01, kernel=rbf; total time=   9.5s
[CV] END ...................C=100, gamma=0.01, kernel=linear; total time=   0.7s
[CV] END ...................C=100, gamma=0.01, kernel=linear; total time=   0.9s
[CV] END ...................C=100, gamma=0.01, kernel=linear; total time=   0.7s
[CV] END .....................C=100, gamma=0.001, kernel=rbf; total time=   3.8s
[CV] END .....................C=100, gamma=0.001, kernel=rbf; total time=   4.4s
[CV] END .....................C=100, gamma=0.001, kernel=rbf; total time=   4.6s
[CV] END ..................C=100, gamma=0.001, kernel=linear; total time=   0.8s
[CV] END ..................C=100, gamma=0.001, kernel=linear; total time=   1.4s
[CV] END ..................C=100, gamma=0.001, kernel=linear; total time=   1.0s
Best Hyperparameters for SVM: {'C': 0.1, 'gamma': 1, 'kernel': 'linear'}
Support Vector Machine Classification Report:
              precision    recall  f1-score   support

           0       1.00      1.00      1.00      3614
           1       1.00      1.00      1.00      1308

    accuracy                           1.00      4922
   macro avg       1.00      1.00      1.00      4922
weighted avg       1.00      1.00      1.00      4922

In [24]:
# Checking the Support Vector Machine performance on the test dataset

y_pred_test = svm.predict(x_test_scaled)
metrics_score(y_test, y_pred_test)

# Hyperparameter tuning for Support Vector Machine test

param_grid_svm = {
    'C': [0.1, 1, 10, 100],
    'gamma': [1, 0.1, 0.01, 0.001],
    'kernel': ['rbf', 'linear']
}
grid_search_svm = GridSearchCV(SVC(), param_grid_svm, cv=3, verbose=2)
grid_search_svm.fit(x_test_scaled, y_test)

# Finding the best parameters for Support Vector Machine test

best_params_svm = grid_search_svm.best_params_
print("Best Hyperparameters for SVM:", best_params_svm)

# Evaluating Support Vector Machine model on the test set

best_svm_model = grid_search_svm.best_estimator_
y_pred_svm = best_svm_model.predict(x_test_scaled)
print("Support Vector Machine Classification Report:")
print(classification_report(y_test, y_pred_svm))
              precision    recall  f1-score   support

           0       1.00      1.00      1.00      1549
           1       1.00      1.00      1.00       561

    accuracy                           1.00      2110
   macro avg       1.00      1.00      1.00      2110
weighted avg       1.00      1.00      1.00      2110

No description has been provided for this image
Fitting 3 folds for each of 32 candidates, totalling 96 fits
[CV] END .........................C=0.1, gamma=1, kernel=rbf; total time=   2.3s
[CV] END .........................C=0.1, gamma=1, kernel=rbf; total time=   1.9s
[CV] END .........................C=0.1, gamma=1, kernel=rbf; total time=   2.2s
[CV] END ......................C=0.1, gamma=1, kernel=linear; total time=   0.2s
[CV] END ......................C=0.1, gamma=1, kernel=linear; total time=   0.4s
[CV] END ......................C=0.1, gamma=1, kernel=linear; total time=   0.2s
[CV] END .......................C=0.1, gamma=0.1, kernel=rbf; total time=   1.9s
[CV] END .......................C=0.1, gamma=0.1, kernel=rbf; total time=   2.3s
[CV] END .......................C=0.1, gamma=0.1, kernel=rbf; total time=   1.7s
[CV] END ....................C=0.1, gamma=0.1, kernel=linear; total time=   0.5s
[CV] END ....................C=0.1, gamma=0.1, kernel=linear; total time=   0.4s
[CV] END ....................C=0.1, gamma=0.1, kernel=linear; total time=   0.4s
[CV] END ......................C=0.1, gamma=0.01, kernel=rbf; total time=   2.9s
[CV] END ......................C=0.1, gamma=0.01, kernel=rbf; total time=   1.7s
[CV] END ......................C=0.1, gamma=0.01, kernel=rbf; total time=   1.6s
[CV] END ...................C=0.1, gamma=0.01, kernel=linear; total time=   0.1s
[CV] END ...................C=0.1, gamma=0.01, kernel=linear; total time=   0.1s
[CV] END ...................C=0.1, gamma=0.01, kernel=linear; total time=   0.1s
[CV] END .....................C=0.1, gamma=0.001, kernel=rbf; total time=   1.3s
[CV] END .....................C=0.1, gamma=0.001, kernel=rbf; total time=   1.3s
[CV] END .....................C=0.1, gamma=0.001, kernel=rbf; total time=   1.3s
[CV] END ..................C=0.1, gamma=0.001, kernel=linear; total time=   0.2s
[CV] END ..................C=0.1, gamma=0.001, kernel=linear; total time=   0.2s
[CV] END ..................C=0.1, gamma=0.001, kernel=linear; total time=   0.1s
[CV] END ...........................C=1, gamma=1, kernel=rbf; total time=   1.9s
[CV] END ...........................C=1, gamma=1, kernel=rbf; total time=   2.0s
[CV] END ...........................C=1, gamma=1, kernel=rbf; total time=   2.1s
[CV] END ........................C=1, gamma=1, kernel=linear; total time=   0.2s
[CV] END ........................C=1, gamma=1, kernel=linear; total time=   0.2s
[CV] END ........................C=1, gamma=1, kernel=linear; total time=   0.2s
[CV] END .........................C=1, gamma=0.1, kernel=rbf; total time=   2.0s
[CV] END .........................C=1, gamma=0.1, kernel=rbf; total time=   2.1s
[CV] END .........................C=1, gamma=0.1, kernel=rbf; total time=   2.2s
[CV] END ......................C=1, gamma=0.1, kernel=linear; total time=   0.2s
[CV] END ......................C=1, gamma=0.1, kernel=linear; total time=   0.2s
[CV] END ......................C=1, gamma=0.1, kernel=linear; total time=   0.3s
[CV] END ........................C=1, gamma=0.01, kernel=rbf; total time=   1.7s
[CV] END ........................C=1, gamma=0.01, kernel=rbf; total time=   2.2s
[CV] END ........................C=1, gamma=0.01, kernel=rbf; total time=   2.5s
[CV] END .....................C=1, gamma=0.01, kernel=linear; total time=   0.5s
[CV] END .....................C=1, gamma=0.01, kernel=linear; total time=   0.2s
[CV] END .....................C=1, gamma=0.01, kernel=linear; total time=   0.2s
[CV] END .......................C=1, gamma=0.001, kernel=rbf; total time=   2.2s
[CV] END .......................C=1, gamma=0.001, kernel=rbf; total time=   1.4s
[CV] END .......................C=1, gamma=0.001, kernel=rbf; total time=   1.3s
[CV] END ....................C=1, gamma=0.001, kernel=linear; total time=   0.2s
[CV] END ....................C=1, gamma=0.001, kernel=linear; total time=   0.2s
[CV] END ....................C=1, gamma=0.001, kernel=linear; total time=   0.2s
[CV] END ..........................C=10, gamma=1, kernel=rbf; total time=   1.8s
[CV] END ..........................C=10, gamma=1, kernel=rbf; total time=   2.2s
[CV] END ..........................C=10, gamma=1, kernel=rbf; total time=   2.5s
[CV] END .......................C=10, gamma=1, kernel=linear; total time=   0.2s
[CV] END .......................C=10, gamma=1, kernel=linear; total time=   0.3s
[CV] END .......................C=10, gamma=1, kernel=linear; total time=   0.2s
[CV] END ........................C=10, gamma=0.1, kernel=rbf; total time=   1.9s
[CV] END ........................C=10, gamma=0.1, kernel=rbf; total time=   1.8s
[CV] END ........................C=10, gamma=0.1, kernel=rbf; total time=   1.7s
[CV] END .....................C=10, gamma=0.1, kernel=linear; total time=   0.3s
[CV] END .....................C=10, gamma=0.1, kernel=linear; total time=   0.2s
[CV] END .....................C=10, gamma=0.1, kernel=linear; total time=   0.2s
[CV] END .......................C=10, gamma=0.01, kernel=rbf; total time=   2.0s
[CV] END .......................C=10, gamma=0.01, kernel=rbf; total time=   2.2s
[CV] END .......................C=10, gamma=0.01, kernel=rbf; total time=   1.6s
[CV] END ....................C=10, gamma=0.01, kernel=linear; total time=   0.2s
[CV] END ....................C=10, gamma=0.01, kernel=linear; total time=   0.2s
[CV] END ....................C=10, gamma=0.01, kernel=linear; total time=   0.2s
[CV] END ......................C=10, gamma=0.001, kernel=rbf; total time=   1.4s
[CV] END ......................C=10, gamma=0.001, kernel=rbf; total time=   1.3s
[CV] END ......................C=10, gamma=0.001, kernel=rbf; total time=   1.2s
[CV] END ...................C=10, gamma=0.001, kernel=linear; total time=   0.2s
[CV] END ...................C=10, gamma=0.001, kernel=linear; total time=   0.2s
[CV] END ...................C=10, gamma=0.001, kernel=linear; total time=   0.2s
[CV] END .........................C=100, gamma=1, kernel=rbf; total time=   1.8s
[CV] END .........................C=100, gamma=1, kernel=rbf; total time=   1.7s
[CV] END .........................C=100, gamma=1, kernel=rbf; total time=   1.9s
[CV] END ......................C=100, gamma=1, kernel=linear; total time=   0.2s
[CV] END ......................C=100, gamma=1, kernel=linear; total time=   0.2s
[CV] END ......................C=100, gamma=1, kernel=linear; total time=   0.2s
[CV] END .......................C=100, gamma=0.1, kernel=rbf; total time=   1.7s
[CV] END .......................C=100, gamma=0.1, kernel=rbf; total time=   2.7s
[CV] END .......................C=100, gamma=0.1, kernel=rbf; total time=   2.8s
[CV] END ....................C=100, gamma=0.1, kernel=linear; total time=   0.6s
[CV] END ....................C=100, gamma=0.1, kernel=linear; total time=   0.5s
[CV] END ....................C=100, gamma=0.1, kernel=linear; total time=   0.5s
[CV] END ......................C=100, gamma=0.01, kernel=rbf; total time=   2.3s
[CV] END ......................C=100, gamma=0.01, kernel=rbf; total time=   1.7s
[CV] END ......................C=100, gamma=0.01, kernel=rbf; total time=   2.1s
[CV] END ...................C=100, gamma=0.01, kernel=linear; total time=   0.3s
[CV] END ...................C=100, gamma=0.01, kernel=linear; total time=   0.2s
[CV] END ...................C=100, gamma=0.01, kernel=linear; total time=   0.4s
[CV] END .....................C=100, gamma=0.001, kernel=rbf; total time=   1.7s
[CV] END .....................C=100, gamma=0.001, kernel=rbf; total time=   1.5s
[CV] END .....................C=100, gamma=0.001, kernel=rbf; total time=   1.4s
[CV] END ..................C=100, gamma=0.001, kernel=linear; total time=   0.2s
[CV] END ..................C=100, gamma=0.001, kernel=linear; total time=   0.2s
[CV] END ..................C=100, gamma=0.001, kernel=linear; total time=   0.2s
Best Hyperparameters for SVM: {'C': 0.1, 'gamma': 1, 'kernel': 'linear'}
Support Vector Machine Classification Report:
              precision    recall  f1-score   support

           0       1.00      1.00      1.00      1549
           1       1.00      1.00      1.00       561

    accuracy                           1.00      2110
   macro avg       1.00      1.00      1.00      2110
weighted avg       1.00      1.00      1.00      2110

In [25]:
# Checking the coefficients of Support Vector Machine to find variables leading to churning and not churning

cols = X.columns
coef_svm = svm.coef_
pd.DataFrame(coef_svm, columns = cols).T.sort_values(by = 0, ascending = False)
Out[25]:
0
Churn Value 0.440544
Churn Score 0.022761
Internet Service_Fiber optic 0.007234
Churn Reason_Don't know 0.006867
Churn Reason_Competitor offered higher download speeds 0.006726
... ...
Online Backup_Yes -0.003150
Device Protection_Yes -0.003345
Tenure Months -0.004434
Dependents_Yes -0.004744
Churn Reason_Unknown -0.440544

1181 rows × 1 columns

8. Model Evaluation¶

In [26]:
# Providing the accuracy, precision, recall, F1 score and AUC-ROC, while providing the best parameters for the training set

print("Best Parameters:", grid_search_svm.best_params_)
print("Accuracy :", metrics.accuracy_score(y_train, y_pred_train))
print("Precision :", metrics.precision_score(y_train, y_pred_train))
print("Recall :", metrics.recall_score(y_train, y_pred_train))
print("F1 score :", metrics.f1_score(y_train, y_pred_train))
print("AUC-ROC :", roc_auc_score(y_train, y_pred_train))

# Providing the accuracy, precision, recall, F1 score and AUC-ROC, while providing the best parameters for the test set

print("Best Parameters:", grid_search_svm.best_params_)
print("Accuracy :", metrics.accuracy_score(y_test, y_pred_test))
print("Precision :", metrics.precision_score(y_test, y_pred_test))
print("Recall :", metrics.recall_score(y_test, y_pred_test))
print("F1 score :", metrics.f1_score(y_test, y_pred_test))
print("AUC-ROC :", roc_auc_score(y_test, y_pred_test))
Best Parameters: {'C': 0.1, 'gamma': 1, 'kernel': 'linear'}
Accuracy : 1.0
Precision : 1.0
Recall : 1.0
F1 score : 1.0
AUC-ROC : 1.0
Best Parameters: {'C': 0.1, 'gamma': 1, 'kernel': 'linear'}
Accuracy : 1.0
Precision : 1.0
Recall : 1.0
F1 score : 1.0
AUC-ROC : 1.0