Skip to content

Commercial banks receive a lot of applications for credit cards. Many of them get rejected for many reasons, like high loan balances, low income levels, or too many inquiries on an individual's credit report, for example. Manually analyzing these applications is mundane, error-prone, and time-consuming (and time is money!). Luckily, this task can be automated with the power of machine learning and pretty much every commercial bank does so nowadays. In this workbook, you will build an automatic credit card approval predictor using machine learning techniques, just like real banks do.

The Data

The data is a small subset of the Credit Card Approval dataset from the UCI Machine Learning Repository showing the credit card applications a bank receives. This dataset has been loaded as a pandas DataFrame called cc_apps. The last column in the dataset is the target value.

# Import necessary libraries
import pandas as pd
import numpy as np
import seaborn as sns
from sklearn.model_selection import train_test_split, cross_val_score, KFold
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import confusion_matrix, roc_auc_score, classification_report, ConfusionMatrixDisplay
from sklearn.model_selection import GridSearchCV

# Load the dataset
cc_apps = pd.read_csv("cc_approvals.data", header=None) 
cc_apps.head()

Additional Variable Information from dataset source https://archive.ics.uci.edu/dataset/27/credit+approval

0: b, a. 1: continuous. 2: continuous. 3: u, y, l, t. 4: g, p, gg. 5: c, d, cc, i, j, k, m, r, q, w, x, e, aa, ff. 6: v, h, bb, j, n, z, dd, ff, o. 7: continuous. 8: t, f. 9: t, f. 10: continuous. 11: g, p, s. 12: continuous. 13: +,- (class attribute)

# Check data types
cc_apps.dtypes
# Check the shape of the DataFrame
cc_apps.shape
# Check for missing values
cc_apps.isna().sum().sort_values()
# Missing values are represented as '?'
cc_apps[4].unique()
# Replace missing values with NaN
cc_apps.replace('?', np.nan, inplace=True)
# Verify that NaN values were properly replaced
cc_apps[4].unique()
cc_apps.isna().sum().sort_values(ascending=False)
cc_apps.info()
# Convert to the right data type
cc_apps[1] = cc_apps[1].astype('float')
cc_apps.info()
cc_apps.isna().sum().sort_values(ascending=False)
# Specify list of categorical columns to impute
cc_apps_cat = [0, 3, 4, 5, 6]
cc_apps_cat

# Impute categorical columns with the mode
cc_apps[cc_apps_cat] = cc_apps[cc_apps_cat].apply(lambda col: col.fillna(col.mode()[0]))

# Check missing values
cc_apps.isna().sum().sort_values(ascending=False)
# Show descriptive statistics
cc_apps.describe()