<jupyter_start><jupyter_text>Explore data and creted a helper function to get feature description<jupyter_code>import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
info_df = pd.read_csv('lending_club_info.csv',index_col='LoanStatNew')
info_df
def get_features_info(feature_name):
    print(info_df.loc[feature_name]['Description'])
get_features_info('loan_amnt')<jupyter_output>The listed amount of the loan applied for by the borrower. If at some point in time, the credit department reduces the loan amount, then it will be reflected in this value.<jupyter_text>Importing Data<jupyter_code>df = pd.read_csv('lending_club_loan_two.csv')
df.head()
df.info()<jupyter_output><class 'pandas.core.frame.DataFrame'>
RangeIndex: 396030 entries, 0 to 396029
Data columns (total 27 columns):
 #   Column                Non-Null Count   Dtype  
---  ------                --------------   -----  
 0   loan_amnt             396030 non-null  float64
 1   term                  396030 non-null  object 
 2   int_rate              396030 non-null  float64
 3   installment           396030 non-null  float64
 4   grade                 396030 non-null  object 
 5   sub_grade             396030 non-null  object 
 6   emp_title             373103 non-null  object 
 7   emp_length            377729 non-null  object 
 8   home_ownership        396030 non-null  object 
 9   annual_inc            396030 non-null  float64
 10  verification_status   396030 non-null  object 
 11  issue_d               396030 non-null  object 
 12  loan_status           396030 non-null  object 
 13  purpose               396030 non-null  object 
 14  title                 394275 non-null  object 
 15  [...]<jupyter_text>EDA<jupyter_code>sns.countplot(x='loan_status',data=df)
df.corr()
plt.figure(figsize=(10,10))
sns.heatmap(df.corr(),cmap='viridis',annot=True)
plt.figure(figsize=(10,5))
sns.scatterplot(x='loan_amnt',y='installment',data=df)
plt.figure(figsize=(10,5))
sns.distplot(df['loan_amnt'],bins=50,kde=False)
plt.figure(figsize=(10,5))
sns.distplot(df['installment'],bins=35,kde=True)
plt.figure(figsize=(10,5))
sns.distplot(df['int_rate'],bins=35,kde=False)
sns.boxplot(x='loan_status',y='loan_amnt',data=df)
df.groupby('loan_status')['loan_amnt'].describe()<jupyter_output><empty_output><jupyter_text>**Transforming target**<jupyter_code>df['loan_repaid'] = df['loan_status'].map({'Fully Paid':1,'Charged Off':0})
df.drop('loan_status',axis=1,inplace=True)
df.corr()['loan_repaid'].sort_values(ascending=False)
df.corr()['loan_repaid'].sort_values().drop('loan_repaid').plot(kind='bar')<jupyter_output><empty_output><jupyter_text>Checking Null values and transforming text values into dummy variables<jupyter_code>#plt.figure(figsize=(12,10))
#sns.heatmap(df.isnull(),cbar=False)
df.isnull().sum()
df['term'].unique()
df['term'] = df['term'].str.rstrip('months')
df['term']
df['term'] = pd.to_numeric(df['term'])
df.info()
df[['grade','sub_grade']]
sns.countplot(x='grade',data=df.sort_values('grade'),hue='loan_repaid')
plt.figure(figsize=(12,6))
sns.countplot(x='sub_grade',data=df.sort_values('grade'),hue='loan_repaid')<jupyter_output><empty_output><jupyter_text>**Grade and subgrade are representing similar data points so one of the columns can be dropped and converting other column to dummy columns**<jupyter_code>df.drop('grade',axis=1,inplace=True)
df = pd.concat([df,pd.get_dummies(df['sub_grade'],drop_first=True)],axis=1)
df.drop('sub_grade',axis=1,inplace=True)
df.info()
df['emp_title'].isnull().sum()
df['emp_title'].value_counts()<jupyter_output><empty_output><jupyter_text>**There are too many unique values so there is no point converting this variable to dummy variables**<jupyter_code>df.drop('emp_title',axis=1,inplace=True)
df.info()
df.select_dtypes(['object']).columns
df['emp_length'].value_counts()
df['emp_length'].isnull().sum()
df.drop('emp_length',axis=1,inplace=True)
df.info()
df.drop('issue_d',axis=1,inplace=True)
df.select_dtypes(['object']).columns
df.drop('address',axis=1,inplace=True)
df['home_ownership'].unique()
df['home_ownership']=df['home_ownership'].replace(['NONE', 'ANY'], 'OTHER')
df = pd.concat([df,pd.get_dummies(df['home_ownership'],drop_first=True)],axis=1)
df.drop('home_ownership',axis=1,inplace=True)
df.select_dtypes(['object']).columns
df['verification_status'].unique()
df['verification_status'].unique()
df['purpose'].unique()
df['purpose'].nunique()
df['title'].nunique()
df.drop('title',axis=1,inplace=True)
df.select_dtypes(['object']).columns
df['earliest_cr_year'] = df['earliest_cr_line'].apply(lambda date:int(date[-4:]))
df.drop('earliest_cr_line',axis=1,inplace=True)
df['initial_list_status'].nunique()
df['application_type'].nunique()
df = pd.concat([df,pd.get_dummies(df[['verification_status','purpose','initial_list_status','application_type']],drop_first=True)],axis=1)
df.drop(['verification_status','purpose','initial_list_status','application_type'],axis=1,inplace=True)
df.info()
df.drop('mort_acc',axis=1,inplace=True)<jupyter_output><empty_output><jupyter_text>Train Test Split<jupyter_code>len(df)
df.isnull().sum().sort_values(ascending=False)
df = df.dropna()
df.isnull().sum().sort_values(ascending=False)
df.info()
X = df.drop('loan_repaid',axis=1).values
y = df['loan_repaid'].values
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=101)
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)<jupyter_output><empty_output><jupyter_text>Model Training<jupyter_code>import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Activation,Dropout
from tensorflow.keras.constraints import max_norm
model =Sequential()
# input layer
model.add(Dense(69,  activation='relu'))
model.add(Dropout(0.2))

# hidden layer
model.add(Dense(35, activation='relu'))
model.add(Dropout(0.2))

# hidden layer
model.add(Dense(17, activation='relu'))
model.add(Dropout(0.2))

# output layer
model.add(Dense(units=1,activation='sigmoid'))

# Compile model
model.compile(loss='binary_crossentropy', optimizer='adam')
from tensorflow.keras.callbacks import EarlyStopping
early_stop = EarlyStopping(monitor='val_loss',mode='min',verbose=1,patience=25)
model.fit(x=X_train,y=y_train,epochs=2,validation_data=(X_test,y_test),callbacks=[early_stop])
from tensorflow.keras.models import load_model
model.save('loan_repayment_prediction_model.h5')  
losses = pd.DataFrame(model.history.history)
losses[['loss','val_loss']].plot()
predictions = model.predict_classes(X_test)
from sklearn.metrics import classification_report,confusion_matrix
print(classification_report(y_test,predictions))<jupyter_output>precision    recall  f1-score   support

           0       0.58      0.03      0.06     15658
           1       0.81      0.99      0.89     63386

    accuracy                           0.80     79044
   macro avg       0.69      0.51      0.48     79044
weighted avg       0.76      0.80      0.73     79044
{'fraction_non_alphanumeric': 0.15034965034965034, 'fraction_numerical': 0.038181818181818185, 'mean_word_length': 5.578656853725851, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 35, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '9', 'dir': 'jupyter-structured-clean-dedup', 'id': '199500', 'license': 'MIT', 'n_tokens_mistral': 2730, 'n_tokens_neox': 2522, 'n_words': 408, 'path': 'Tensorflow Keras Loan Repayment Prediction Project.ipynb', 'repo_name': 'vanandjiwala/datascince_projects', 'size': '7150'}