<jupyter_start><jupyter_text>EDA Credit Risk Dataset<jupyter_code>df = pd.read_csv("./Data/credit_risk_dataset.csv")
df.head()
df.shape
print(df.dtypes)<jupyter_output>person_age                      int64
person_income                   int64
person_home_ownership          object
person_emp_length             float64
loan_intent                    object
loan_grade                     object
loan_amnt                       int64
loan_int_rate                 float64
loan_status                     int64
loan_percent_income           float64
cb_person_default_on_file      object
cb_person_cred_hist_length      int64
dtype: object<jupyter_text>Percentage of null values<jupyter_code>df.loan_int_rate.isnull().sum()/ df.shape[0]
df.isnull().sum()
plt.hist(df['person_emp_length'])
plt.xlabel("Employment Length")
plt.ylabel("Frequency")
plt.title("Freq vs Employment Length")
plt.show()

plt.hist(df['loan_int_rate'])
plt.xlabel("Interest Rate")
plt.ylabel("Frequency")
plt.title("Freq vs Interest Rate")
# filling NaNs with the median values for both the loan interest rate and employment length variables, due to unnormal distribution
emp_len_null = df[df['person_emp_length'].isnull()].index
int_rate_null = df[df['loan_int_rate'].isnull()].index

df['person_emp_length'].fillna((df['person_emp_length'].median()), inplace=True)
df['loan_int_rate'].fillna((df['loan_int_rate'].median()), inplace = True)

# outlier check Age vs Interest Rate
colors = ["blue","red"]
plt.scatter(df['person_age'], df['loan_int_rate'],
            c = df['loan_status'],
            cmap = mpl.colors.ListedColormap(colors), alpha=0.5)
plt.xlabel("Person Age")
plt.ylabel("Loan Interest Rate")
plt.title("Interest Rate vs Age")
# removing outliers for age > 100
df_clean1 = df[df['person_age']<=100]

df[df['person_age']>100]
# distribution of nr of loans based on loan_grade (credit assessment) and cb_person_default_on_file (credit default history)
pd.crosstab(df_clean1['cb_person_default_on_file'], df_clean1['loan_grade'])
#distribution of mean interest rate by credit default history (Y/N) and loan_intent
pd.crosstab(df_clean1['cb_person_default_on_file'], df_clean1['loan_intent'], 
            values = df_clean1['loan_int_rate'], aggfunc = 'median')
# 0 is non-default, 1 = default
default_hist_status_tab = pd.crosstab(df_clean1['cb_person_default_on_file'], df_clean1['loan_status'])
default_hist_status_tab
# number of customers whith no default/"bad credit" history
total1 = default_hist_status_tab.iloc[0].sum()
print(total1,"customers did not have a previous default history")
# number of customers with no default/"bad credit" history who have defaulted
defaulted1 = default_hist_status_tab.iloc[0,1]
print(defaulted1,"customers with no previous default history have defaulted")
# customers with "bad credit" history
total2 = default_hist_status_tab.iloc[1].sum()
print(total2,"customers had a previous default history")
# number of customers with "bad credit" who have defaulted
defaulted2 = default_hist_status_tab.iloc[1,1]
print(defaulted2,"customers who previously defaulted have defaulted again")
first_default = round(defaulted1 / total1 * 100, 2)
second_default = round(defaulted2 / total2 * 100, 2)

print("{}% of clients with no previous default history have defaulted.".format(first_default))
print("And {}% of clients who had previously defaulted, defaulted again.".format(second_default))
# percentage of total defaults
total_default = round((defaulted1+defaulted2) / (total1+total2) *100,2)
print("{}% of total clients population have defaulted.".format(total_default))
# Correlation matrix
corrmat = df_clean1.corr()
fig = plt.figure(figsize = (12, 9))
sns.heatmap(corrmat, vmax = .8, square = True)
plt.show()<jupyter_output><empty_output><jupyter_text>ML Logistic Regression<jupyter_code>from sklearn import model_selection,linear_model, metrics
# turning categorical values (object dtypes) into dummies
num_col = df_clean1.select_dtypes(exclude = 'object')
char_col = df_clean1.select_dtypes(include = 'object')

encoded_char_col = pd.get_dummies(char_col)

df_clean2 = pd.concat([num_col, encoded_char_col], axis=1)
df_clean2
# Split Train and Test Sets
Y = df_clean2['loan_status']
X = df_clean2.drop('loan_status',axis=1)
 


X_train, X_test, y_train, y_test = model_selection.train_test_split(X, Y, random_state=2020, test_size=.30)<jupyter_output><empty_output><jupyter_text>Logisitc RegressionDefault ('loan_status') is modelled as a function of:- person_age- person_income- person_emp_length        .        .        .- loan_grade_G- cb_person_default_on_file_N- cb_person_default_on_file_Y<jupyter_code>log_clf = linear_model.LogisticRegression()

log_clf.fit(X_train, np.ravel(y_train))
col_effect = pd.DataFrame()
col_effect['col_names'] = X.columns
col_effect['col_coef'] = log_clf.coef_[0]
col_effect
initial_accuracy = round(log_clf.score(X_test,  y_test),2)
print("The initial accuracy is {}".format(initial_accuracy))<jupyter_output>The initial accuracy is 0.81<jupyter_text>Feature importance<jupyter_code>importance = log_clf.coef_[0]
for i,v in enumerate(importance):
    print('Feature: %0d, Score: %.10f' % (i,v*1000000))<jupyter_output>Feature: 0, Score: -0.2707894328
Feature: 1, Score: -40.4227336273
Feature: 2, Score: -0.0804849427
Feature: 3, Score: 107.2347161645
Feature: 4, Score: 0.1817228916
Feature: 5, Score: 0.0027262560
Feature: 6, Score: -0.0511671303
Feature: 7, Score: -0.0183176564
Feature: 8, Score: 0.0000216921
Feature: 9, Score: -0.0128950610
Feature: 10, Score: 0.0209016855
Feature: 11, Score: 0.0067181895
Feature: 12, Score: -0.0093947598
Feature: 13, Score: 0.0049759403
Feature: 14, Score: 0.0032304423
Feature: 15, Score: -0.0045865852
Feature: 16, Score: -0.0112325670
Feature: 17, Score: -0.0295468957
Feature: 18, Score: -0.0194554447
Feature: 19, Score: -0.0048033720
Feature: 20, Score: 0.0298503778
Feature: 21, Score: 0.0097519684
Feature: 22, Score: 0.0026591243
Feature: 23, Score: 0.0012549021
Feature: 24, Score: -0.0294109546
Feature: 25, Score: 0.0191216147<jupyter_text>Probability of default<jupyter_code>predict_log = pd.DataFrame(log_clf.predict_proba(X_test)[:,1], columns=['prob_default'])

pred_df = pd.concat([y_test.reset_index(drop=True), predict_log],axis=1)
pred_df

# First column logisitic regression value, second column represents the probability of default (== 1)<jupyter_output><empty_output><jupyter_text>Two fictional characters<jupyter_code>df_clean2.tail(5)
Andy_Ilse = [{'person_age': 30, 'person_income': 65000, 'person_emp_length': 1, 'loan_amnt': 35000, 'loan_int_rate': 3.95, 'loan_status': 1, 'loan_percent_income': 0.53, 'cb_person_cred_hist_length': 3, 'person_home_ownership_MORTGAGE': 0, 'person_home_ownership_OTHER': 0, 'person_home_ownership_OWN': 0, 'person_home_ownership_RENT': 1, 'loan_intent_DEBTCONSOLIDATION': 0, 'loan_intent_EDUCATION': 0, 'loan_intent_HOMEIMPROVEMENT': 0, 'loan_intent_MEDICAL': 0, 'loan_intent_PERSONAL': 0, 'loan_intent_VENTURE': 1, 'loan_grade_A': 0, 'loan_grade_B': 1, 'loan_grade_C': 0, 'loan_grade_D': 0, 'loan_grade_E': 0, 'loan_grade_F': 0, 'loan_grade_G': 0, 'cb_person_default_on_file_N': 0, 'cb_person_default_on_file_Y': 1}, {'person_age': 29, 'person_income': 55000, 'person_emp_length': 0, 'loan_amnt': 15000, 'loan_int_rate': 2.75, 'loan_status': 1, 'loan_percent_income': 0.27, 'cb_person_cred_hist_length': 1, 'person_home_ownership_MORTGAGE': 0, 'person_home_ownership_OTHER': 0, 'person_home_ownership_OWN': 0, 'person_home_ownership_RENT': 1, 'loan_intent_DEBTCONSOLIDATION': 0, 'loan_intent_EDUCATION': 0, 'loan_intent_HOMEIMPROVEMENT': 1, 'loan_intent_MEDICAL': 0, 'loan_intent_PERSONAL': 0, 'loan_intent_VENTURE': 1, 'loan_grade_A': 0, 'loan_grade_B': 0, 'loan_grade_C': 1, 'loan_grade_D': 0, 'loan_grade_E': 0, 'loan_grade_F': 0, 'loan_grade_G': 0, 'cb_person_default_on_file_N': 1, 'cb_person_default_on_file_Y': 0}]
Ilse = [{'person_age': 29, 'person_income': 55000, 'person_emp_length': 0, 'loan_amnt': 15000, 'loan_int_rate': 2.75, 'loan_status': 1, 'loan_percent_income': 0.27, 'cb_person_cred_hist_length': 1, 'person_home_ownership_MORTGAGE': 0, 'person_home_ownership_OTHER': 0, 'person_home_ownership_OWN': 0, 'person_home_ownership_RENT': 1, 'loan_intent_DEBTCONSOLIDATION': 0, 'loan_intent_EDUCATION': 0, 'loan_intent_HOMEIMPROVEMENT': 1, 'loan_intent_MEDICAL': 0, 'loan_intent_PERSONAL': 0, 'loan_intent_VENTURE': 1, 'loan_grade_A': 0, 'loan_grade_B': 0, 'loan_grade_C': 1, 'loan_grade_D': 0, 'loan_grade_E': 0, 'loan_grade_F': 0, 'loan_grade_G': 0, 'cb_person_default_on_file_N': 1, 'cb_person_default_on_file_Y': 0}]
df_characters = pd.DataFrame(Andy_Ilse)
df_characters
X = df_characters.drop('loan_status',axis=1)
y_pred = log_clf.predict(df_characters.drop('loan_status',axis=1))
print(df_characters)
print(y_pred)<jupyter_output>person_age  person_income  person_emp_length  loan_amnt  loan_int_rate  \
0          30          65000                  1      35000           3.95   
1          29          55000                  0      15000           2.75   

   loan_status  loan_percent_income  cb_person_cred_hist_length  \
0            1                 0.53                           3   
1            1                 0.27                           1   

   person_home_ownership_MORTGAGE  person_home_ownership_OTHER  ...  \
0                               0                            0  ...   
1                               0                            0  ...   

   loan_intent_VENTURE  loan_grade_A  loan_grade_B  loan_grade_C  \
0                    1             0             1             0   
1                    1             0             0             1   

   loan_grade_D  loan_grade_E  loan_grade_F  loan_grade_G  \
0             0             0             0             0   
1             0          [...]<jupyter_text>Prediction Andy defaults == 1, Ilse doesn't == 0.  Confusion Matrix<jupyter_code>from sklearn.metrics import confusion_matrix
from collections import Counter

y_pred = log_clf.predict(X_test)
confusion_matrix = confusion_matrix(y_test, y_pred)
print(confusion_matrix)
netMat = (y_pred == y_test)
log_clf.coef_
ind = np.where(y_test == 1)
Counter(y_pred[ind])
pd.crosstab(y_test, y_pred, rownames=['True'], colnames=['Predicted'], margins=True)
confusion_matrix = pd.crosstab(y_test, y_pred, rownames=['True'], colnames=['Predicted'])
sns.heatmap(confusion_matrix, annot=False)
plt.show()<jupyter_output><empty_output><jupyter_text>98% true positive, 83% false negative  !!!Attempt to improve true negative prediction  Random Forrest<jupyter_code># Building the Random Forest Classifier (RANDOM FOREST)
from sklearn.ensemble import RandomForestClassifier
# random forest model creation
rfc = RandomForestClassifier()
rfc.fit(X_train,y_train)
# predictions
y_pred = rfc.predict(X_test)
#Evaluating the classifier
#printing every score of the classifier
#scoring in any thing
from sklearn.metrics import classification_report, accuracy_score,precision_score,recall_score,f1_score,matthews_corrcoef
from sklearn.metrics import confusion_matrix
Default = df_clean2[df_clean2['loan_status'] == 1]
n_outliers = len(Default)
n_errors = (y_pred != y_test).sum()
print("The model used is Random Forest classifier")
acc= accuracy_score(y_test,y_pred)
print("The accuracy is {}".format(acc))
prec= precision_score(y_test,y_pred)
print("The precision is {}".format(prec))
rec= recall_score(y_test,y_pred)
print("The recall is {}".format(rec))
f1= f1_score(y_test,y_pred)
print("The F1-Score is {}".format(f1))
MCC=matthews_corrcoef(y_test,y_pred)
print("The Matthews correlation coefficient is {}".format(MCC))
# Feature importance
importance = rfc.feature_importances_
for i,v in enumerate(importance):
    print('Feature: %0d, Score: %.5f' % (i,v))
plt.bar([x for x in range(len(importance))], importance)
plt.show()
Y_pred = rfc.predict(X_test)
pd.crosstab(y_test, Y_pred, rownames=['True'], colnames=['Predicted'], margins=True)<jupyter_output><empty_output><jupyter_text>99% true positive, Random Forrest model decreased the False Negatives from 83% (LogisticsRegression) to 29%.<jupyter_code>confusion_matrix = pd.crosstab(y_test, y_pred, rownames=['True'], colnames=['Predicted'])
sns.heatmap(confusion_matrix, annot=False)
plt.show()
# Andy or Ilse to default?
X = df_characters.drop('loan_status',axis=1)
y_pred = rfc.predict(df_characters.drop('loan_status',axis=1))
print(df_characters)
print(y_pred)<jupyter_output>person_age  person_income  person_emp_length  loan_amnt  loan_int_rate  \
0          30          65000                  1      35000           3.95   
1          29          55000                  0      15000           2.75   

   loan_status  loan_percent_income  cb_person_cred_hist_length  \
0            1                 0.53                           3   
1            1                 0.27                           1   

   person_home_ownership_MORTGAGE  person_home_ownership_OTHER  ...  \
0                               0                            0  ...   
1                               0                            0  ...   

   loan_intent_VENTURE  loan_grade_A  loan_grade_B  loan_grade_C  \
0                    1             0             1             0   
1                    1             0             0             1   

   loan_grade_D  loan_grade_E  loan_grade_F  loan_grade_G  \
0             0             0             0             0   
1             0          [...]<jupyter_text>Principal Component Analysis<jupyter_code>from sklearn.decomposition import PCA
from sklearn.preprocessing import MinMaxScaler

# normalization for hyperparameter tunning
scaler = MinMaxScaler(feature_range=[0, 1])
data_rescaled = scaler.fit_transform(df_clean2)

#Fitting the PCA algorithm with our Data
pca = PCA().fit(data_rescaled)
#Plotting the Cumulative Summation of the Explained Variance
plt.figure()
plt.plot(np.cumsum(pca.explained_variance_ratio_))
plt.xlabel('Number of Components')
plt.ylabel('Variance (%)') #for each component
plt.title('Dataset Explained Variance')
plt.show()
# normalize data
from sklearn import preprocessing
from sklearn.decomposition import PCA

pie = df_clean2.drop('loan_status',axis=1)

data_scaled = pd.DataFrame(preprocessing.scale(pie),columns = pie.columns) 

# PCA
pca = PCA(n_components=14)
pca_val = pca.fit_transform(data_scaled)
pca_dataset = pd.DataFrame(pca_val)
x_train, x_test, y_train, y_test = model_selection.train_test_split(pca_dataset, Y, random_state=2020, test_size=.32)

#Start of Classification Logistics Regression

log_clf = linear_model.LogisticRegression()

log_clf.fit(x_train, np.ravel(y_train))
pca_predict_log = pd.DataFrame(log_clf.predict_proba(x_test)[:,1], columns=['prob_default'])
pca_pred_df = pd.concat([y_test.reset_index(drop=True), pca_predict_log],axis=1)
pca_pred_df<jupyter_output><empty_output><jupyter_text>In the first column the logistic regression value for the dependent variabe is given, second value is the predicted probability of default.<jupyter_code>pca_accuracy = round(log_clf.score(x_test,  y_test),2)
print("The accuracy of the Logisitic Regression Model upon PCA optimization is {}".format(pca_accuracy))<jupyter_output>The accuracy of the Logisitic Regression Model upon PCA optimization is 0.86
{'fraction_non_alphanumeric': 0.11038322961021946, 'fraction_numerical': 0.04893547330494596, 'mean_word_length': 4.215579091219679, 'pattern_counts': {'":': 0, '<': 44, '<?xml version=': 0, '>': 45, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 24, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '12', 'dir': 'jupyter-structured-clean-dedup', 'id': '435077', 'license': 'Unlicense', 'n_tokens_mistral': 5872, 'n_tokens_neox': 5203, 'n_words': 1142, 'path': 'Credit_Risk_Analysis.ipynb', 'repo_name': 'Silviu2020/Credit-Scoring-Algorithm', 'size': '15265'}