实战案例!风控实战催收评分卡(附 Python 源码)

2024-01-09 15:55:56

在风控环节中,传统观念A卡为主、B卡C卡为辅,但是在市场逐步饱和、政策利率要求越来越低的背景下,B卡和C卡也越来越重要。

本文以简易贷后数据实战催收评分模型,预测在用户逾期后、未来能否催回。

一、数据读取

数据来源某比赛网站,包括逾期用户的年龄、收入情况、家庭人员数、债务情况、历史逾期情况等等,预测变量为订单是否会逾期90天+,数据集中均为数值型变量、且字段较少,所以适合零基础、初学者上手练习。 文末获取数据集

在这里插入图片描述
在这里插入图片描述

二、变量统计

计算iv及特征缺失率,可以看到仅有两个变量存在少部分缺失,其中历史的逾期变量iv整体偏高。

在这里插入图片描述

import toad
def iv_miss(df,var_list,y):
    df_tmp=df[df[y].notnull()].copy()
    
    iv_all=toad.quality(df_tmp[var_list+[y]], target=y, indicators = ['iv','unique'])[['unique','iv']]

    miss_per=pd.DataFrame(df[var_list].isnull().sum()/(df.shape[0]))
    miss_per.columns=['缺失率']
    result=pd.concat([miss_per,iv_all],axis=1)
    return result.sort_values(['iv'],ascending=False)

df_iv=iv_miss(df_sample,fea_list,y)
df_iv

?

三、模型构建

这里使用xgb构建二分类模型,使用ks、auc进行评估

在这里插入图片描述

查看特征重要性,如下三列分别为分裂次数、平均信息增益、样本覆盖度

在这里插入图片描述

def init_params():
    params_xgb={
        'objective':'binary:logistic',
        'eval_metric':'auc',
        'silent':0,
        'nthread':4,
        'n_estimators':1000,
        'eta':0.01,
        'num_leaves':10,
        'max_depth':4,
        'min_child_weight':500,
        'scale_pos_weight':1,
        'gamma':0,
        'reg_alpha':2,
        'reg_lambda':2,
        'subsample':0.8,
        'colsample_bytree':0.8,
        'grow_policy':'lossguide',
        'early_stopping_rounds':50,
        'seed':123
    }

    return params_xgb

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

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

    clf=XGBClassifier(**params)
    
    model_sklearn=clf.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,clf)
    test_ks,test_auc=ks_auc_value(y_test,x_test,clf)

    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,clf

model_result,model=model_train_sklearn(df_sample,y,fea_list)
model_result

?

四、评分使用

C卡用于催收策略,使用预测概率/评分做分箱,如下图,催收策略比如对于bad_rate较低的前2箱可以短信催收、对于中间3-6箱短信催收和点催结合、最后4箱持续电催。

在这里插入图片描述

def ks_bins(y_true,y_pred,cut='cut',bins=10,pred='pred'):
    
    '''
        cut 分箱方法:cut等距分箱,qcut等频分箱
        输出:分箱ks结果
    '''

    df=pd.DataFrame({
        'true':list(y_true),
        'pred':list(y_pred),  # proba、score都可以
    })
    if cut=='cut':
        df['pred_bin']=pd.cut(df['pred'],bins=bins)
    elif cut=='qcut':
        df['pred_bin']=pd.qcut(df['pred'],q=bins,duplicates='drop')
    df_bin=df.groupby(['pred_bin'])['true'].agg(['count','sum','mean'])
    df_bin.columns=['cnt','bad','bad_rate']

    df_bin.fillna(0,inplace=True)
    df_bin['good']=df_bin['cnt']-df_bin['bad']
    df_bin['cum_count']=df_bin['cnt'].cumsum()
    df_bin['cum_good']=df_bin['good'].cumsum()
    df_bin['cum_bad']=df_bin['bad'].cumsum()
    df_bin['cum_bad_rate']=df_bin['cum_bad']/df_bin['cum_count']
    if pred=='pred':
        df_bin['ks']=df_bin['cum_good']/df_bin['good'].sum()-df_bin['cum_bad']/df_bin['bad'].sum()
    elif pred=='score':
        df_bin['ks']=df_bin['cum_bad']/df_bin['bad'].sum()-df_bin['cum_good']/df_bin['good'].sum()
    return df_bin[['cnt','bad_rate','cum_count','cum_bad_rate','ks']]

round(ks_bins(df_sample[y],df_sample.pred,cut='cut',bins=10,pred='pred'),4)

代码与数据获取

独学而无优则孤陋而寡闻,技术要学会交流、分享,不建议闭门造车。

技术交流与答疑、源码获取,均可加交流群获取,群友已超过2000人,添加时最好的备注方式为:来源+兴趣方向,方便找到志同道合的朋友。

方式①、微信搜索公众号:Python学习与数据挖掘,后台回复:催收评分卡
方式②、添加微信号:dkl88194,备注:催收评分卡

资料1
在这里插入图片描述
资料2
我们打造了《数据分析实战案例宝典》,特点:从0到1轻松学习,方法论及原理、代码、案例应有尽有,所有案例都是按照这样的节奏进行表述。

在这里插入图片描述

文章来源:https://blog.csdn.net/qq_34160248/article/details/135479954
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。