In [1]:
# Loading Packages

import pandas as pd 
import numpy as np                     # For mathematical calculations 
import seaborn as sns                  # For data visualization 
import matplotlib.pyplot as plt        # For plotting graphs 
%matplotlib inline 
import warnings                        # To ignore any warnings warnings.filterwarnings("ignore")
In [2]:
pd.set_option('display.max_rows', 100)
pd.set_option('display.max_columns', 50)
In [3]:
# Reading data

df_train=pd.read_csv("train_ctrUa4K.csv") 
df_test=pd.read_csv("test_lAUu6dG.csv")
In [4]:
train_original=df_train.copy() 
test_original=df_test.copy()
In [5]:
df_train.columns
Out[5]:
Index(['Loan_ID', 'Gender', 'Married', 'Dependents', 'Education',
       'Self_Employed', 'ApplicantIncome', 'CoapplicantIncome', 'LoanAmount',
       'Loan_Amount_Term', 'Credit_History', 'Property_Area', 'Loan_Status'],
      dtype='object')
In [6]:
df_test.columns
Out[6]:
Index(['Loan_ID', 'Gender', 'Married', 'Dependents', 'Education',
       'Self_Employed', 'ApplicantIncome', 'CoapplicantIncome', 'LoanAmount',
       'Loan_Amount_Term', 'Credit_History', 'Property_Area'],
      dtype='object')
In [7]:
df_train.shape
Out[7]:
(614, 13)
In [8]:
df_test.shape
Out[8]:
(367, 12)
In [9]:
df_train['Loan_Status'].value_counts()
Out[9]:
Y    422
N    192
Name: Loan_Status, dtype: int64
In [10]:
df_train.dtypes
Out[10]:
Loan_ID               object
Gender                object
Married               object
Dependents            object
Education             object
Self_Employed         object
ApplicantIncome        int64
CoapplicantIncome    float64
LoanAmount           float64
Loan_Amount_Term     float64
Credit_History       float64
Property_Area         object
Loan_Status           object
dtype: object
In [11]:
df_train.describe(include=object)
Out[11]:
Loan_ID Gender Married Dependents Education Self_Employed Property_Area Loan_Status
count 614 601 611 599 614 582 614 614
unique 614 2 2 4 2 2 3 2
top LP002729 Male Yes 0 Graduate No Semiurban Y
freq 1 489 398 345 480 500 233 422
In [12]:
df_train.describe(include=float)
Out[12]:
CoapplicantIncome LoanAmount Loan_Amount_Term Credit_History
count 614.000000 592.000000 600.00000 564.000000
mean 1621.245798 146.412162 342.00000 0.842199
std 2926.248369 85.587325 65.12041 0.364878
min 0.000000 9.000000 12.00000 0.000000
25% 0.000000 100.000000 360.00000 1.000000
50% 1188.500000 128.000000 360.00000 1.000000
75% 2297.250000 168.000000 360.00000 1.000000
max 41667.000000 700.000000 480.00000 1.000000
In [13]:
#Apply Function
#Create a new function:
def num_missing(x):
  return sum(x.isnull())
#Applying per column:
print("Missing values per column:")
print(df_train.apply(num_missing, axis=0)) #axis=0 defines that function is to be applied on each column
Missing values per column:
Loan_ID               0
Gender               13
Married               3
Dependents           15
Education             0
Self_Employed        32
ApplicantIncome       0
CoapplicantIncome     0
LoanAmount           22
Loan_Amount_Term     14
Credit_History       50
Property_Area         0
Loan_Status           0
dtype: int64
gender, married, dependents, self_employed have missing value
In [14]:
df_train['Dependents'].value_counts()
Out[14]:
0     345
1     102
2     101
3+     51
Name: Dependents, dtype: int64
In [15]:
df_train.isnull().sum()
Out[15]:
Loan_ID               0
Gender               13
Married               3
Dependents           15
Education             0
Self_Employed        32
ApplicantIncome       0
CoapplicantIncome     0
LoanAmount           22
Loan_Amount_Term     14
Credit_History       50
Property_Area         0
Loan_Status           0
dtype: int64
In [16]:
df_train[df_train['Gender'].isnull() | df_train['Married'].isnull()]
Out[16]:
Loan_ID Gender Married Dependents Education Self_Employed ApplicantIncome CoapplicantIncome LoanAmount Loan_Amount_Term Credit_History Property_Area Loan_Status
23 LP001050 NaN Yes 2 Not Graduate No 3365 1917.0 112.0 360.0 0.0 Rural N
104 LP001357 Male NaN NaN Graduate No 3816 754.0 160.0 360.0 1.0 Urban Y
126 LP001448 NaN Yes 3+ Graduate No 23803 0.0 370.0 360.0 1.0 Rural Y
171 LP001585 NaN Yes 3+ Graduate No 51763 0.0 700.0 300.0 1.0 Urban Y
188 LP001644 NaN Yes 0 Graduate Yes 674 5296.0 168.0 360.0 1.0 Rural Y
228 LP001760 Male NaN NaN Graduate No 4758 0.0 158.0 480.0 1.0 Semiurban Y
314 LP002024 NaN Yes 0 Graduate No 2473 1843.0 159.0 360.0 1.0 Rural N
334 LP002103 NaN Yes 1 Graduate Yes 9833 1833.0 182.0 180.0 1.0 Urban Y
435 LP002393 Female NaN NaN Graduate No 10047 0.0 NaN 240.0 1.0 Semiurban Y
460 LP002478 NaN Yes 0 Graduate Yes 2083 4083.0 160.0 360.0 NaN Semiurban Y
467 LP002501 NaN Yes 0 Graduate No 16692 0.0 110.0 360.0 1.0 Semiurban Y
477 LP002530 NaN Yes 2 Graduate No 2873 1872.0 132.0 360.0 0.0 Semiurban N
507 LP002625 NaN No 0 Graduate No 3583 0.0 96.0 360.0 1.0 Urban N
576 LP002872 NaN Yes 0 Graduate No 3087 2210.0 136.0 360.0 0.0 Semiurban N
588 LP002925 NaN No 0 Graduate No 4750 0.0 94.0 360.0 1.0 Semiurban Y
592 LP002933 NaN No 3+ Graduate Yes 9357 0.0 292.0 360.0 1.0 Semiurban Y
In [17]:
# For numerical variables: imputation using mean or median
# For categorical variables: imputation using mode
In [18]:
df_train['Gender'].fillna(df_train['Gender'].mode()[0], inplace=True) 
df_train['Married'].fillna(df_train['Married'].mode()[0], inplace=True) 
df_train['Dependents'].fillna(df_train['Dependents'].mode()[0], inplace=True) 
df_train['Self_Employed'].fillna(df_train['Self_Employed'].mode()[0], inplace=True) 
df_train['Credit_History'].fillna(df_train['Credit_History'].mode()[0], inplace=True)
In [19]:
df_train['Loan_Amount_Term'].fillna(df_train['Loan_Amount_Term'].mode()[0], inplace=True)
In [20]:
df_train['LoanAmount'].fillna(df_train['LoanAmount'].median(), inplace=True)
In [21]:
df_train.isnull().sum()
Out[21]:
Loan_ID              0
Gender               0
Married              0
Dependents           0
Education            0
Self_Employed        0
ApplicantIncome      0
CoapplicantIncome    0
LoanAmount           0
Loan_Amount_Term     0
Credit_History       0
Property_Area        0
Loan_Status          0
dtype: int64
In [22]:
df_train['LoanAmount'].hist()
Out[22]:
<matplotlib.axes._subplots.AxesSubplot at 0x7fef0c803198>
In [23]:
temp1 = df_train['Credit_History'].value_counts(ascending=True) 
temp2 = df_train.pivot_table(values='Loan_Status',index=['Credit_History'],aggfunc=lambda x: x.map({'Y':1,'N':0}).mean()) 
print('Frequency Table for Credit History:\n %s' %(temp1))
# print temp1 
print('\nProbility of getting loan for each Credit History class:')
print(temp2)
Frequency Table for Credit History:
 0.0     89
1.0    525
Name: Credit_History, dtype: int64

Probility of getting loan for each Credit History class:
                Loan_Status
Credit_History             
0.0                0.078652
1.0                0.790476
In [24]:
df_train['LoanAmount_log'] = np.log(df_train['LoanAmount']) 
df_train['LoanAmount_log'].hist(bins=20) 
df_test['LoanAmount_log'] = np.log(df_test['LoanAmount'])
In [25]:
df_train['ApplicantIncome'].idxmax()
Out[25]:
409
In [26]:
df_train['ApplicantIncome'].idxmin()
Out[26]:
216
In [27]:
bins=[0,1000,3000,42000]
In [28]:
def test(number):
    if 0<number<1000:
       return "Low"
    elif 1000<=number<=3000:
        return "Medium"
    else:
        return "High"
In [29]:
df_train['incomestatus'] = df_train['ApplicantIncome'].apply(test)
In [30]:
df_train.drop('incomestatus',axis=1)
Out[30]:
Loan_ID Gender Married Dependents Education Self_Employed ApplicantIncome CoapplicantIncome LoanAmount Loan_Amount_Term Credit_History Property_Area Loan_Status LoanAmount_log
0 LP001002 Male No 0 Graduate No 5849 0.0 128.0 360.0 1.0 Urban Y 4.852030
1 LP001003 Male Yes 1 Graduate No 4583 1508.0 128.0 360.0 1.0 Rural N 4.852030
2 LP001005 Male Yes 0 Graduate Yes 3000 0.0 66.0 360.0 1.0 Urban Y 4.189655
3 LP001006 Male Yes 0 Not Graduate No 2583 2358.0 120.0 360.0 1.0 Urban Y 4.787492
4 LP001008 Male No 0 Graduate No 6000 0.0 141.0 360.0 1.0 Urban Y 4.948760
... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
609 LP002978 Female No 0 Graduate No 2900 0.0 71.0 360.0 1.0 Rural Y 4.262680
610 LP002979 Male Yes 3+ Graduate No 4106 0.0 40.0 180.0 1.0 Rural Y 3.688879
611 LP002983 Male Yes 1 Graduate No 8072 240.0 253.0 360.0 1.0 Urban Y 5.533389
612 LP002984 Male Yes 2 Graduate No 7583 0.0 187.0 360.0 1.0 Urban Y 5.231109
613 LP002990 Female No 0 Graduate Yes 4583 0.0 133.0 360.0 0.0 Semiurban N 4.890349

614 rows × 14 columns

In [31]:
df_train['Gender'].mode()[0]
Out[31]:
'Male'
In [32]:
df_train=df_train.drop('Loan_ID',axis=1) 
df_test=df_test.drop('Loan_ID',axis=1)
In [33]:
X = df_train.drop('Loan_Status',1) 
y = df_train.Loan_Status
In [34]:
X.head()
Out[34]:
Gender Married Dependents Education Self_Employed ApplicantIncome CoapplicantIncome LoanAmount Loan_Amount_Term Credit_History Property_Area LoanAmount_log incomestatus
0 Male No 0 Graduate No 5849 0.0 128.0 360.0 1.0 Urban 4.852030 High
1 Male Yes 1 Graduate No 4583 1508.0 128.0 360.0 1.0 Rural 4.852030 High
2 Male Yes 0 Graduate Yes 3000 0.0 66.0 360.0 1.0 Urban 4.189655 Medium
3 Male Yes 0 Not Graduate No 2583 2358.0 120.0 360.0 1.0 Urban 4.787492 Medium
4 Male No 0 Graduate No 6000 0.0 141.0 360.0 1.0 Urban 4.948760 High
In [35]:
X=pd.get_dummies(X) 
X
Out[35]:
ApplicantIncome CoapplicantIncome LoanAmount Loan_Amount_Term Credit_History LoanAmount_log Gender_Female Gender_Male Married_No Married_Yes Dependents_0 Dependents_1 Dependents_2 Dependents_3+ Education_Graduate Education_Not Graduate Self_Employed_No Self_Employed_Yes Property_Area_Rural Property_Area_Semiurban Property_Area_Urban incomestatus_High incomestatus_Low incomestatus_Medium
0 5849 0.0 128.0 360.0 1.0 4.852030 0 1 1 0 1 0 0 0 1 0 1 0 0 0 1 1 0 0
1 4583 1508.0 128.0 360.0 1.0 4.852030 0 1 0 1 0 1 0 0 1 0 1 0 1 0 0 1 0 0
2 3000 0.0 66.0 360.0 1.0 4.189655 0 1 0 1 1 0 0 0 1 0 0 1 0 0 1 0 0 1
3 2583 2358.0 120.0 360.0 1.0 4.787492 0 1 0 1 1 0 0 0 0 1 1 0 0 0 1 0 0 1
4 6000 0.0 141.0 360.0 1.0 4.948760 0 1 1 0 1 0 0 0 1 0 1 0 0 0 1 1 0 0
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
609 2900 0.0 71.0 360.0 1.0 4.262680 1 0 1 0 1 0 0 0 1 0 1 0 1 0 0 0 0 1
610 4106 0.0 40.0 180.0 1.0 3.688879 0 1 0 1 0 0 0 1 1 0 1 0 1 0 0 1 0 0
611 8072 240.0 253.0 360.0 1.0 5.533389 0 1 0 1 0 1 0 0 1 0 1 0 0 0 1 1 0 0
612 7583 0.0 187.0 360.0 1.0 5.231109 0 1 0 1 0 0 1 0 1 0 1 0 0 0 1 1 0 0
613 4583 0.0 133.0 360.0 0.0 4.890349 1 0 1 0 1 0 0 0 1 0 0 1 0 1 0 1 0 0

614 rows × 24 columns

In [36]:
df_train=pd.get_dummies(df_train) 
df_test=pd.get_dummies(df_test)
In [37]:
from sklearn.model_selection import train_test_split
x_train, x_cv, y_train, y_cv = train_test_split(X,y, test_size =0.3)
In [38]:
from sklearn.linear_model import LogisticRegression 
from sklearn.metrics import accuracy_score
In [39]:
model = LogisticRegression() 
model.fit(x_train, y_train)
/home/khanhp/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/_logistic.py:764: ConvergenceWarning: lbfgs failed to converge (status=1):
STOP: TOTAL NO. of ITERATIONS REACHED LIMIT.

Increase the number of iterations (max_iter) or scale the data as shown in:
    https://scikit-learn.org/stable/modules/preprocessing.html
Please also refer to the documentation for alternative solver options:
    https://scikit-learn.org/stable/modules/linear_model.html#logistic-regression
  extra_warning_msg=_LOGISTIC_SOLVER_CONVERGENCE_MSG)
Out[39]:
LogisticRegression()
In [40]:
pred_cv = model.predict(x_cv)
In [41]:
pred_cv
Out[41]:
array(['Y', 'N', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'N', 'Y', 'Y', 'Y', 'N',
       'N', 'Y', 'N', 'Y', 'Y', 'Y', 'N', 'N', 'Y', 'Y', 'Y', 'Y', 'Y',
       'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'N', 'N', 'N', 'Y', 'Y', 'Y',
       'N', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'N', 'Y', 'Y', 'Y',
       'N', 'Y', 'Y', 'N', 'Y', 'Y', 'Y', 'N', 'Y', 'Y', 'Y', 'Y', 'Y',
       'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'N', 'Y', 'Y', 'N', 'Y', 'N', 'Y',
       'N', 'Y', 'N', 'Y', 'Y', 'Y', 'Y', 'N', 'Y', 'Y', 'Y', 'Y', 'N',
       'Y', 'Y', 'Y', 'N', 'Y', 'Y', 'N', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y',
       'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y',
       'N', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'N', 'Y', 'N', 'Y', 'Y', 'Y',
       'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'N', 'N', 'Y', 'Y', 'Y', 'Y',
       'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'N', 'Y', 'Y', 'N',
       'Y', 'Y', 'Y', 'N', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y',
       'Y', 'N', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y',
       'Y', 'Y', 'Y'], dtype=object)
In [42]:
model.intercept_
Out[42]:
array([-0.02840378])
In [43]:
accuracy_score(y_cv,pred_cv)
Out[43]:
0.7837837837837838