Python银行信贷风控实战2

AI助手已提取文章相关产品:

        

目录

一、数据介绍及逾期标签处理

1、数据介绍

2、标签定义及生成

二、模型构建及评估

三、划重点

少走10年弯路


        之前写过一篇银行信贷风控实战了,但是包括之前其它信贷风控的实战内容在内,实际上和工作中完整项目之间还存在很多差距,这篇银行信贷风控实战2所使用数据更接近工作中的真实数据,需要自行从原始借贷还款记录中提取逾期标签用于分析建模、而不是简简单单地直接给你处理好的Y标签(实际工作时需要自行处理的)。所以重点推荐本文原始数据、以及逾期标签的打标方法。

一、数据介绍及逾期标签处理

1、数据介绍

(1)订单信息及特征表

        第一部分数据集中包含银行借贷订单的金额、利息、账期等信息,还有年龄、性别等个人基本信息,历史借款、还款信息,以及户口、学历、视频等认证审核结果,但是不包括逾期信息。文末获取数据集

图片

(2)还款记录表

           还款记录表包括订单ID、不同期数、还款金额、到期日、还款时间等信息,这也基本是实际工作中真实数据的样子了。可以看到每笔订单分12期,每一期都有对应的还款行为/是否逾期,所以需要我们自行定义标签、以及确定相应的标签逻辑,如dpd30_mob3为前三期最大逾期天数是否超过30天。

2、标签定义及生成

        还款记录表中提供了还款状态字段(分布见下图),其中1代表准时还款、2代表逾期、0中既有未到期又有逾期、3代表提前还款、4也代表逾期,还款状态字段含义混乱、且无法确定逾期程度(订单到底逾期了多少天),所以我们需要自己根据到期日期、还款日期、观测日期来计算每一期的逾期天数,然后再计算每笔订单的逾期标签(如dpd30_mob3)。

图片

(1)计算每期逾期天数

        首先剔除观测时间尚未到期的数据,然后计算每一期的逾期天数:有还款日期(实际发生了还款行为才会有还款日期数据,没有还款日期的代表一直未还款)的期数用还款日减去到期日,一直未还款的用观测日减去到期日;同时还要把逾期天数小于0(提前还款)的逾期天数置为0。

        计算得到结果如下

图片

def df_lp_pred(df_lp):
    df=df_lp[df_lp['recorddate']>df_lp['到期日期']].reset_index(drop=True)
    df.loc[df['还款日期']!='\\N','due_date']=df['还款日期']
    df.loc[df['还款日期']=='\\N','due_date']=df['recorddate']
    df['duedays']=(pd.to_datetime(df['due_date'])-pd.to_datetime(df['到期日期'])).dt.days
    df['duedays']=np.where(df['duedays']>=0,df['duedays'],0)
    return df

df_lp_copy=df_lp_pred(df_lp)
df_lp_copy.head(20)

(2)计算订单下各观测周期的最大逾期天数

        对订单的各期数据做聚合、计算不同观测周期下的最大逾期天数,分别得到mob1-mob12的最大逾期天数。

图片

        mob1-mob12的最大逾期天数分布情况如下,可见大部分是未逾期的,为了控制逾期标签比例,本文使用dpd1_mob(n)作为标签

图片

def get_mob_k_maxduedays(df_lp_copy,k):
    return (
        df_lp_copy
        [df_lp_copy.ListingId.isin(list(df_lp_copy[df_lp_copy['期数']==k].ListingId))]
        [df_lp_copy['期数']<=k]
        .groupby(['ListingId'])
        .duedays
        .max()
    )

mob_k_list=[1,2,3,4,5,6,7,8,9,10,11,12]
df_maxduedays=pd.concat([get_mob_k_maxduedays(df_lp_copy,k) for k in mob_k_list],axis=1)
df_maxduedays.columns=['mob{}_duedays'.format(k) for k in mob_k_list]
df_maxduedays

(3)计算dpd1_mob(n)标签

        根据mob1-mob12的最大逾期天数计算dpd1_mob(n)标签,如mob1逾期天数大于0则dpd1_mob1的值为1,计算完成后统计各标签的样本量和逾期率情况如下,本文使用dpd1_mob3建模、其他标签也可尝试。注意这里的样本量递减是在观测日时,订单还没到相应的期数

图片


def get_label(value):
    if value==0:
        return 0
    if value>0:
        return 1
    return np.nan

for i in mob_k_list:
    df_maxduedays['dpd1_mob{}'.format(i)]=df_maxduedays['mob{}_duedays'.format(i)].apply(get_label)
df_maxduedays

二、模型构建及评估

        使用lightGBM构建二分类模型,按照8:2的比例划分训练集、测试集,然后使用ks、auc进行效果评估,结果如下、auc达到0.66

图片

def init_params():
    params_lgb={
        'boosting_type': 'gbdt',
        'objective': 'binary',
        'metric':'auc',
        'n_jobs': 8,
        'n_estimators':150,
        'learning_rate': 0.03,
        'max_depth':4,
        'num_leaves': 12,
        'max_bin':255, 
        'subsample_for_bin':100000, 
        'min_split_gain':0,
        'min_child_samples':300,
        'colsample_bytree': 0.8,
        'subsample': 0.8,
        'subsample_freq': 1,   
        'feature_fraction_seed':2,
        'bagging_seed': 1,
        'reg_alpha':1,
        'reg_lambda':1,
        'scale_pos_weight':1,
        'silent':True,
        'random_state':1,
        'verbose':-1, # 控制模型训练过程的输出信息,-1为不输出信息
    }
    return params_lgb

def ks_auc_value(y_true,df,model):
    y_pred=model.predict_proba(df)[:,1]
    fpr,tpr,thresholds= roc_curve(list(y_true),list(y_pred))
    ks=max(tpr-fpr)
    auc= roc_auc_score(list(y_true),list(y_pred))
    return ks,auc

def model_train_sklearn(train,y_name,fea_list):
    
    params=init_params()
    x_train,x_test, y_train, y_test =train_test_split(train[fea_list],train[y_name],test_size=0.2, random_state=123)

    model=lgb.LGBMClassifier(**params)
    
    model.fit(x_train,y_train,eval_set=[(x_train, y_train),(x_test, y_test)])
    train_ks,train_auc=ks_auc_value(y_train,x_train,model)
    test_ks,test_auc=ks_auc_value(y_test,x_test,model)
    
    dic={
        'train_good':(y_train.count()-y_train.sum()),
        'train_bad':y_train.sum(),
        'test_good':(y_test.count()-y_test.sum()),
        'test_bad':y_test.sum(),
        'train_ks':train_ks,
        'train_auc':train_auc,
        'test_ks':test_ks,
        'test_auc':test_auc,
    }
    return dic,model

y='dpd1_mob3'
df_lc_copy[cate_fea]=df_lc_copy[cate_fea].astype('category')
model_result,model=model_train_sklearn(df_lc_copy[df_lc_copy[y].isin([0,1])],y,fea_list)
model_result

三、划重点

少走10年弯路

        关注威信公众号 Python风控模型与数据分析,回复 银行风控实战2 获取本篇数据及代码

        还有更多理论、代码分享等你来拿

您可能感兴趣的与本文相关内容

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值