美文网首页
Home Credit Default Risk EDA

Home Credit Default Risk EDA

作者: LY豪 | 来源:发表于2019-04-17 19:48 被阅读0次

    这部分主要对kaggle的比赛Home Credit Default Risk做的一些探索性数据分析(EDA)

    读入数据

    import numpy as np
    import matplotlib
    import matplotlib.pyplot as plt
    import seaborn as sns
    
    application_train = pd.read_csv('application_train.csv')
    application_test = pd.read_csv('application_test.csv')
    bureau = pd.read_csv('bureau.csv')
    bureau_balance = pd.read_csv('bureau_balance.csv')
    credit_card_balance = pd.read_csv('credit_card_balance.csv')
    installments_payments = pd.read_csv('installments_payments.csv')
    previous_application = pd.read_csv('previous_application.csv')
    POS_CASH_balance = pd.read_csv('POS_CASH_balance.csv')
    
    print('application_train.shape:', application_train.shape)
    print('application_test.shape:', application_test.shape)
    print('bureau.shape:', bureau.shape)
    print('bureau_balance.shape:', bureau_balance.shape)
    print('credit_card_balance.shape:', credit_card_balance.shape)
    print('installments_payments.shape:', installments_payments.shape)
    print('POS_CASH_balance.shape:', POS_CASH_balance.shape)
    
    application_train.shape: (307511, 122)
    application_test.shape: (48744, 121)
    bureau.shape: (1716428, 17)
    bureau_balance.shape: (27299925, 3)
    credit_card_balance.shape: (3840312, 23)
    installments_payments.shape: (13605401, 8)
    POS_CASH_balance.shape: (10001358, 8)
    

    查看数据

    查看缺失的数据

    def missing_data(data):
        total = data.isnull().sum().sort_values(ascending=False)
        percent = (data.isnull().sum()/data.isnull().count()).sort_values(ascending=False)
        return pd.concat([total, percent], axis=1, keys=['total', 'percent'])
    
    print('missing_data(application_train).head(10):')
    print(missing_data(application_train).head(10))
    
    missing_data(application_train).head(10):
                               total   percent
    COMMONAREA_MEDI           214865  0.698723
    COMMONAREA_AVG            214865  0.698723
    COMMONAREA_MODE           214865  0.698723
    NONLIVINGAPARTMENTS_MODE  213514  0.694330
    NONLIVINGAPARTMENTS_MEDI  213514  0.694330
    NONLIVINGAPARTMENTS_AVG   213514  0.694330
    FONDKAPREMONT_MODE        210295  0.683862
    LIVINGAPARTMENTS_MEDI     210199  0.683550
    LIVINGAPARTMENTS_MODE     210199  0.683550
    LIVINGAPARTMENTS_AVG      210199  0.683550
    
    print('missing_data(application_test).head(10):')
    print(missing_data(application_test).head(10))
    
    missing_data(application_test).head(10):
                              total   percent
    COMMONAREA_MEDI           33495  0.687161
    COMMONAREA_AVG            33495  0.687161
    COMMONAREA_MODE           33495  0.687161
    NONLIVINGAPARTMENTS_MODE  33347  0.684125
    NONLIVINGAPARTMENTS_MEDI  33347  0.684125
    NONLIVINGAPARTMENTS_AVG   33347  0.684125
    FONDKAPREMONT_MODE        32797  0.672842
    LIVINGAPARTMENTS_AVG      32780  0.672493
    LIVINGAPARTMENTS_MEDI     32780  0.672493
    LIVINGAPARTMENTS_MODE     32780  0.672493
    
    print('missing_data(bureau).head(10):')
    print(missing_data(bureau).head(10))
    
    missing_data(bureau).head(10):
                              total   percent
    AMT_ANNUITY             1226791  0.714735
    AMT_CREDIT_MAX_OVERDUE  1124488  0.655133
    DAYS_ENDDATE_FACT        633653  0.369170
    AMT_CREDIT_SUM_LIMIT     591780  0.344774
    AMT_CREDIT_SUM_DEBT      257669  0.150119
    DAYS_CREDIT_ENDDATE      105553  0.061496
    AMT_CREDIT_SUM               13  0.000008
    CREDIT_TYPE                   0  0.000000
    AMT_CREDIT_SUM_OVERDUE        0  0.000000
    CNT_CREDIT_PROLONG            0  0.000000
    
    print('missing_data(bureau_balance).head(10):')
    print(missing_data(bureau_balance).head(10))
    
    missing_data(bureau_balance).head(10):
                    total  percent
    STATUS              0      0.0
    MONTHS_BALANCE      0      0.0
    SK_ID_BUREAU        0      0.0
    
    print('missing_data(credit_card_balance).head(10):')
    print(missing_data(credit_card_balance).head(10))
    
    missing_data(credit_card_balance).head(10):
                                 total   percent
    AMT_PAYMENT_CURRENT         767988  0.199981
    AMT_DRAWINGS_OTHER_CURRENT  749816  0.195249
    CNT_DRAWINGS_POS_CURRENT    749816  0.195249
    CNT_DRAWINGS_OTHER_CURRENT  749816  0.195249
    CNT_DRAWINGS_ATM_CURRENT    749816  0.195249
    AMT_DRAWINGS_ATM_CURRENT    749816  0.195249
    AMT_DRAWINGS_POS_CURRENT    749816  0.195249
    CNT_INSTALMENT_MATURE_CUM   305236  0.079482
    AMT_INST_MIN_REGULARITY     305236  0.079482
    SK_DPD_DEF                       0  0.000000
    
    print('missing_data(installments_payments).head(10):')
    print(missing_data(installments_payments).head(10))
    
    missing_data(installments_payments).head(10):
                            total   percent
    AMT_PAYMENT              2905  0.000214
    DAYS_ENTRY_PAYMENT       2905  0.000214
    AMT_INSTALMENT              0  0.000000
    DAYS_INSTALMENT             0  0.000000
    NUM_INSTALMENT_NUMBER       0  0.000000
    NUM_INSTALMENT_VERSION      0  0.000000
    SK_ID_CURR                  0  0.000000
    SK_ID_PREV                  0  0.000000
    
    print('missing_data(POS_CASH_balance).head(10):')
    print(missing_data(POS_CASH_balance).head(10))
    
    missing_data(POS_CASH_balance).head(10):
                           total   percent
    CNT_INSTALMENT_FUTURE  26087  0.002608
    CNT_INSTALMENT         26071  0.002607
    SK_DPD_DEF                 0  0.000000
    SK_DPD                     0  0.000000
    NAME_CONTRACT_STATUS       0  0.000000
    MONTHS_BALANCE             0  0.000000
    SK_ID_CURR                 0  0.000000
    SK_ID_PREV                 0  0.000000
    

    检查TARGET列的分布

    print(application_train['TARGET'].value_counts())
    application_train['TARGET'].astype(int).plot.hist()
    plt.show()
    

    数据分析

    贷款的类型

    让我们看看贷款的类型,以及在另一个的图表上,TARGET目标值为1(贷款未按时偿还)的贷款的百分比(按贷款类型划分)。

    def plot_stats(feature, label_rotation=False, horizontal_layout=True):
        temp = application_train[feature].value_counts()
        df1 = pd.DataFrame({feature: temp.index, 'Number of contracts': temp.values})
    
        cat_perc = application_train[[feature, 'TARGET']].groupby([feature], as_index=False).mean()
        cat_perc.sort_values(by='TARGET', ascending=False, inplace=True)
    
        if (horizontal_layout):
            fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(12, 6))
        else:
            fig, (ax1, ax2) = plt.subplots(nrows=2, figsize=(12, 14))
        sns.set_color_codes("pastel")
        s = sns.barplot(ax=ax1, x=feature, y="Number of contracts", data=df1)
        if (label_rotation):
            s.set_xticklabels(s.get_xticklabels(), rotation=90)
    
        s = sns.barplot(ax=ax2, x=feature, y='TARGET', order=cat_perc[feature], data=cat_perc)
        if (label_rotation):
            s.set_xticklabels(s.get_xticklabels(), rotation=90)
        plt.ylabel('Percent of target with value 1 [%]', fontsize=10)
        plt.tick_params(axis='both', which='major', labelsize=10)
    
        plt.show()
    
    plot_stats('NAME_CONTRACT_TYPE')
    

    循环贷款只是贷款合同的小部分(10%左右)。与此同时,与循环贷款相比,现金贷款会有更大的几率未偿还。

    客户的性别

    让我们看看客户的性别,另外,在另一个图上,TARGET目标值为1(贷款未按时偿还)的贷款的百分比(按客户性别划分)

    plot_stats('CODE_GENDER')
    

    女性客户的数量几乎是男性客户数量的两倍。从违约信贷的比例来看,男性不偿还贷款的几率(约10%)高于女性(约7%)。

    客户有没有车

    让我们看看客户有没有自己的车,另外,在另一个图上,TARGET目标值为1(贷款未按时偿还)的贷款的百分比。

    plot_stats('FLAG_OWN_CAR')
    

    拥有汽车的客户几乎是没有汽车的客户的一半。拥有汽车的客户不太可能不偿还拥有汽车的客户的汽车。没有汽车的客户违约率稍微高点(8%左右)

    客户有没有房

    让我们看看客户有没有自己的房子,另外,在另一个图上,TARGET目标值为1(贷款未按时偿还)的贷款的百分比。

    plot_stats('FLAG_OWN_REALTY')
    

    拥有房产的客户是不拥有房产的两倍多。这两类人(拥有房产或不拥有房产)的违约率都在8%左右。

    客户家庭状况
    plot_stats('NAME_FAMILY_STATUS', True, True)
    

    大多数客户已婚,其次是单身/未婚。
    在不偿还贷款比例方面,民事婚姻不偿还比例最高(10%),寡妇最低。

    儿童的数量
    plot_stats('CNT_CHILDREN')
    

    大多数贷款的客户都没有孩子。从图中我们可以看到孩子越少的客户越会去贷款。
    在还款方面,无子女、1、2、3、5子女的客户平均有10%左右没有还款。对于有9、11个孩子的客户,未偿还贷款的比例为100%。

    客户家庭人数
    plot_stats('CNT_FAM_MEMBERS',True)
    

    家庭成员为2人的客户最多,其次为1人(单身人士)、3人(独生子女家庭)和4人。
    家庭成员分别为11人和13人的客户有100%的违约率。有10或8个成员的家庭有30%左右的违约率。拥有6名或6名以下家庭成员的违约率为10%的左右。

    客户收入类型
    plot_stats('NAME_INCOME_TYPE',False,False)
    

    申请贷款的人大多是工作收入,其次是商业伙伴、养老金领取者和国家公务员。
    产假的有近40%的违约率,其次是失业(约37%)。其他类型的违约率均低于10%。

    客户的职业
    plot_stats('OCCUPATION_TYPE',True, False)
    

    大部分贷款由劳动者承担,其次是销售人员。IT人员的最低。前几天看了一篇推文发现学了IT的罪犯,再犯率为0%。
    违约率最高的是低技能劳动者(17%以上),其次是司机、服务员/酒吧服务员、保安、劳动者和厨师。

    行业类型
    plot_stats('ORGANIZATION_TYPE',True, False)
    

    违约率最高的行业是运输业:第3类(16%)、工业:第13类(13.5%)、工业:第8类(12.5%)和餐饮业(不到12%)。

    客户的教育类型
    plot_stats('NAME_EDUCATION_TYPE',True)
    

    大部分客户接受中等/中等特殊教育,其次是接受高等教育的客户。只有极少数人拥有学位。
    初中毕业的贷款虽然很少见,但不还贷率最高(11%)。拥有学位的人的不偿还率低于2%。

    客户房屋类型
    plot_stats('NAME_HOUSING_TYPE',True)
    

    25万多名申请贷款的人将他们的住房登记为住房/公寓。

    从这些类别来看,租来的公寓和跟父母一起住的高于10%的违约率。

    Bureau数据集

    让我们将application_train与bureau合并。

    application_bureau_train = application_train.merge(bureau, left_on='SK_ID_CURR', right_on='SK_ID_CURR', how='inner')
    print("The resulting dataframe `application_bureau_train` has ",application_bureau_train.shape[0]," rows and ", 
          application_bureau_train.shape[1]," columns.")
    
    The resulting dataframe `application_bureau_train` has  1465325  rows and  138  columns.
    
    现在让我们分析application_bureau_train数据。
    def plot_b_stats(feature,label_rotation=False,horizontal_layout=True):
        temp = application_bureau_train[feature].value_counts()
        df1 = pd.DataFrame({feature: temp.index,'Number of contracts': temp.values})
    
        # Calculate the percentage of target=1 per category value
        cat_perc = application_bureau_train[[feature, 'TARGET']].groupby([feature],as_index=False).mean()
        cat_perc.sort_values(by='TARGET', ascending=False, inplace=True)
        
        if(horizontal_layout):
            fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(12,6))
        else:
            fig, (ax1, ax2) = plt.subplots(nrows=2, figsize=(12,14))
        sns.set_color_codes("pastel")
        s = sns.barplot(ax=ax1, x = feature, y="Number of contracts",data=df1)
        if(label_rotation):
            s.set_xticklabels(s.get_xticklabels(),rotation=90)
        
        s = sns.barplot(ax=ax2, x = feature, y='TARGET', order=cat_perc[feature], data=cat_perc)
        if(label_rotation):
            s.set_xticklabels(s.get_xticklabels(),rotation=90)
        plt.ylabel('Percent of target with value 1 [%]', fontsize=10)
        plt.tick_params(axis='both', which='major', labelsize=10)
    
        plt.show()
    
    信用状态

    让我们看看信用状况分布。我们首先显示每个类别的信贷数量(可以是关闭的、活跃的、出售的和坏账)。

    plot_b_stats('CREDIT_ACTIVE')
    

    我们可以看出大约有900000人的状态是closed,Bad debt的状态是最少的。
    但我们可以看到Bad debt的违约率是最高的,是其他状态的两倍多。

    信用货币
    plot_b_stats('CREDIT_CURRENCY')
    

    从图上我们可以看出,几乎全都是currency_1贷款。
    根据货币的不同,客户违约的比例是不同的。从currency_3开始,然后是currency_1和currency_2,违约的百分比分别是11%、8%和5%。currency_4的违约率约为0%。

    信用类型
    plot_b_stats('CREDIT_TYPE', True, True)
    

    在 Credit Bureau登记的历史信用主要是消费信贷和信用卡。
    购买设备的贷款——违约率超过20%;
    小额贷款——违约率超过20%;
    流动资金补充贷款——违约率超过12%。

    Previous application数据集

    让我们将application_train与previous_application合并。

    application_prev_train = application_train.merge(previous_application, left_on='SK_ID_CURR', right_on='SK_ID_CURR', how='inner')
    print("The resulting dataframe `application_prev_train` has ",application_prev_train.shape[0]," rows and ", 
          application_prev_train.shape[1]," columns.")
    
    The resulting dataframe `application_prev_train` has  1413701  rows and  158  columns.
    
    def plot_p_stats(feature,label_rotation=False,horizontal_layout=True):
        temp = application_prev_train[feature].value_counts()
        df1 = pd.DataFrame({feature: temp.index,'Number of contracts': temp.values})
    
        # Calculate the percentage of target=1 per category value
        cat_perc = application_prev_train[[feature, 'TARGET']].groupby([feature],as_index=False).mean()
        cat_perc.sort_values(by='TARGET', ascending=False, inplace=True)
        
        if(horizontal_layout):
            fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(12,6))
        else:
            fig, (ax1, ax2) = plt.subplots(nrows=2, figsize=(12,14))
        sns.set_color_codes("pastel")
        s = sns.barplot(ax=ax1, x = feature, y="Number of contracts",data=df1)
        if(label_rotation):
            s.set_xticklabels(s.get_xticklabels(),rotation=90)
        
        s = sns.barplot(ax=ax2, x = feature, y='TARGET', order=cat_perc[feature], data=cat_perc)
        if(label_rotation):
            s.set_xticklabels(s.get_xticklabels(),rotation=90)
        plt.ylabel('Percent of target with value 1 [%]', fontsize=10)
        plt.tick_params(axis='both', which='major', labelsize=10)
    
        plt.show()
    
    合同类型
    plot_p_stats('NAME_CONTRACT_TYPE_y')
    

    在之前的申请数据中有三种类型的合同:现金贷款、消费贷款、循环贷款。现金贷款和消费贷款几乎相同(约60万),而循环贷款约15万。
    之前申请过的客户违约率因之前申请合同的类型而异,循环贷款的违约率为10%,现金贷款的违约率为9.5%,消费贷款的违约率为8%。

    现金贷款的目的
    plot_p_stats('NAME_CASH_LOAN_PURPOSE', True, True)
    

    除XAP、XNA、修理、其他以外,购买二手车、建造房屋占合同数量最多。

    合同状态
    plot_p_stats('NAME_CONTRACT_STATUS', True, True)
    

    大部分的合同状态是批准的,其次是取消和拒绝的。
    合同状态为拒绝的违约率最高(约12%),其次是取消的(约9%),违约率最低的是批准的(不到8%)。

    付款类型
    plot_p_stats('NAME_PAYMENT_TYPE', True, True)
    

    大部分的付款类型是通过银行的,其次是XNA。
    除了XNA(违约率最高),其他的违约率约为8%。

    结论

    EDA到此为止,我们可以根据EDA创建一些新的特征、清洗数据等等。

    相关文章

      网友评论

          本文标题:Home Credit Default Risk EDA

          本文链接:https://www.haomeiwen.com/subject/vcdowqtx.html