评分卡

【代码】评分卡-如何用bbbrisk实现评分卡

作者 : 老饼 发表日期 : 2022-06-26 10:20:56 更新日期 : 2025-03-05 15:20:57
本站原创文章,转载请说明来自《老饼讲解-机器学习》www.bbbdata.com




制作评分卡需要先对变量进行分箱,再使用逻辑回归模型进行建模,并将模型转为评分卡表

本文展示一个用bbbrisk实现评分卡的具体例子,包括变量分箱、建模等,并解说代码的运行结果

通过本文,可以了解如何使用bbbrisk来实现一个评分卡,包括分箱、建模、以及相关注意事项






    01.评分卡实例-数据介绍    





本节介绍本文评分卡案例中使用的数据




     bbbrisk简介    


bbbrisk是python的一个风控包,目前提供的功能主要是构建评分卡
bbbrisk的优点是,不仅仅是单纯的提供评分卡模型,而是实际构建评分卡时一切可能用到的功能 
例如,变量的分析、分箱,模型的训练,评分卡表的构建,最终的报告等等 
 
   在使用bbbrisk时,直接pip安装就可以了,如下:
           pip install bbbrisk              
  bbbrisk依赖于numpy、pandas和sklearn包,最好尽可能保障已经安装了这三个包





    评分卡案例-数据介绍     


bbbrisk自带的小贷数据共包含10个变量与客户好坏标签
 数据包含的10变量和标签如下:
 

数据共2万条,示例如下:

 








    02.评分卡实例-变量分箱与选择     





本节讲解如何对变量进行分箱,以及代码实现





     变量分析与分箱(自动)    


在构建评分卡之前,需要先对变量进行分析与分箱,并选择出有效的变量作为建模变量
如果只是粗糙地看一下评分卡的效果,变量的分箱可以使用算法进行自动分箱
bbbrisk包提供了bins.autoBin函数来对多个变量进行自动分箱
 具体代码如下:
import  bbbrisk  as br

# 加载数据                                                                     
data = br.datasets.load_bloan()                                      # 加载数据
x = data.iloc[:,:-1]                                                 # 变量数据
y = data['is_bad']                                                   # 标签数据

# 自动分箱
bin_sets  = br.bins.batch.autoBins(x, y,enum_var=['city','marital']) # 自动分箱,如果有枚举变量,必须指出哪些是枚举变量
bin_stats = br.bins.batch.bin_stats(x,y,bin_sets)                    # 统计各个变量的分箱情况
br.display.pd.set(width=300,max_colwidth=30,max_rows=30)             # 美化pandas的显示方式
for var in bin_stats:                                                # 逐个变量打印分箱结果
    print('\n变量'+var+'的分箱结果:\n',bin_stats[var])               # 打印当前变量的分箱统计结果

# 选择iv足够大的变量
select_bin_set = {}                                                  # 初始化选择的变量的分箱
for var,stat in bin_stats.items():                                   # 逐个变量循环
    if (stat['iv'].iloc[-1]>0.1):                                    # 当前变量的iv值是否满足要求
        select_bin_set[var] =  bin_sets[var]                         # 如果满足,则添加到选择池
print('\n iv > 0.1 的变量与分箱结果:\n',select_bin_set)              # 最终选择的变量的分箱
在代码中,先用binning.autoBin函数对变量进行分箱,分箱结果如下:
  
进一步使用bins.bin_stat函数,统计出样本在各个分箱的分布、iv值与badrate
 结果如下:
 
 
...
 
自动分箱是为了快捷地、自动地完成分箱,所以一般会简单地借助iv值来判断变量的有效性
由于在iv<0.02时,变量普遍被认为无效,在这里我们不妨把条件加严,筛选出iv>0.1的变量
 最终选择出的变量以及分箱如下:
 








     变量分析与分箱    


在实际项目中,一般都使用手动分箱,来确保评分卡更具解释性、稳定、合理
手动分箱一般是指用badrate分析法来进行分箱,并根据badrate来选择出趋势较强的变量
 笔者通过手动分箱后的结果如下:
 
 
....
 
在本例中,10个变量最终的badrate都有非常明显的趋势,它们都是有效的
 所有变量的分箱代码如下:
import  bbbrisk  as br

# 加载数据                                                                     
data = br.datasets.load_bloan()                                       # 加载数据
x = data.iloc[:,:-1]                                                  # 变量数据
y = data['is_bad']                                                    # 标签数据

# 变量的分箱
bin_sets = {
    'rev'     :[[0,0.1],(['-',0],[0.1,0.37]),[0.37,0.64],([0.64,1.2],[2,'+']),[1.2,2],]
    ,'age'    :[[80,'+'],[60,80],[45,60],['-',45]]
    ,'city'   :[('J','E','I'),'_other',('D','N','S'),('F','P')]
    ,'income' :[[1000,5000],[5000,9000],(['-',1000],[20000,'+'],None),[9000,16000],[16000,20000]]
    ,'marital':[1,0,2]
    ,'debrate':[([0,0.1],[850,'+']),([0.1,0.5],[5,850]),([0.5,0.8],0),[0.8,5]]
    ,'due30'  :[0,1,2,(3,4),[4,'+']]
    ,'due60'  :[0,1,2,[2,'+']]
    ,'due90'  :[0,1,[1,'+']]
    ,'loan_num':[[3,'+'],(2,3),1,0]
    }
bin_stats  = br.bins.batch.bin_stats(x,y,bin_sets)                     # 统计各个变量的分箱情况
br.display.pd.set(width=300,max_colwidth=30,max_rows=30)               # 美化pandas的显示方式
for var in bin_stats:                                                  # 逐个变量打印分箱结果
    print('\n变量'+var+'的分箱结果:\n',bin_stats[var])                 # 打印当前变量的分箱统计结果
✍️关于bbb的分箱格式
在bbbrisk中,约定每个变量的分箱都以list来表示,list中第i个元素代表第i个分箱
其中,单个箱体的表示方法如下:
 
 简单来说,主要就三种情况:
1. 如果是范围分箱,就用[a,b]格式                                                      
              它遵循左开右闭,即它实际代表的范围是(a,b],如果要左闭,就把a取小一点
2. 如果是枚举值就直接填上枚举值a                                                    
3. 如果要合并,就用小括号()括起来,例如([a,b],[c,d],e)                      
 举例:代表0作为一个分箱,(0,2]作为一个分箱,>2作为一个分箱          
             
代表0与>2作为一个分箱,(0,2]作为一个分箱,其它作为一个分箱











    03. 评分卡-实现代码与结果    





本节讲解如何用代码实现评分卡,以及计算阈值表、分数分布图等





     评分卡-实现代码     


在完成变量分箱后,就可以直接使用bbb的评分卡包来构建评分卡,以及打印相关报告
 具体代码如下:
import bbbrisk as br

#加载数据                                                                     
data = br.datasets.load_bloan()                                                    # 加载数据
x = data.iloc[:,:-1]                                                               # 变量数据
y = data['is_bad']                                                                 # 标签数据

# 变量的分箱
bin_sets = {
    'rev'     :[[0,0.1],(['-',0],[0.1,0.37]),[0.37,0.64],([0.64,1.2],[2,'+']),[1.2,2],]
    ,'age'    :[[80,'+'],[60,80],[45,60],['-',45]]
    ,'city'   :[('J','E','I'),'_other',('D','N','S'),('F','P')]
    ,'income' :[[1000,5000],[5000,9000],(['-',1000],[20000,'+'],None),[9000,16000],[16000,20000]]
    ,'marital':[1,0,2]
    ,'debrate':[([0,0.1],[850,'+']),([0.1,0.5],[5,850]),([0.5,0.8],0),[0.8,5]]
    ,'due30'  :[0,1,2,(3,4),[4,'+']]
    ,'due60'  :[0,1,2,[2,'+']]
    ,'due90'  :[0,1,[1,'+']]
    ,'loan_num':[[3,'+'],(2,3),1,0]
    }

# 构建评分卡
model,card = br.model.scoreCard(x,y,bin_sets,train_param={'random_state':0})   # 构建评分卡,为了使结果能重现,笔者设置了固定的随机种子 
score      = card.predict(x[card.var])                                         # 用评分卡进行评分
card.featureScore                                                              # 评分卡-特征得分表
card.baseScore                                                                 # 评分卡-基础分

# 打印结果
print('\n-----【 模型性能评估 】----')
print('* 模型训练AUC:',model.train_auc)                                        # 打印模型训练数据集的AUC
print('* 模型测试AUC:',model.test_auc)                                         # 打印模型测试数据集的AUC
print('* 模型训练KS:',model.train_ks)                                          # 打印模型训练数据集的KS
print('* 模型测试KS:',model.test_ks)                                           # 打印模型测试数据集的KS
													                           
print('\n--------【 模型 】---------')                                         
print('* 模型使用的变量:',model.var)                                           # 模型最终使用的变量
print('* 模型权重:',model.w)                                                   # 模型的变量权重
print('* 模型阈值:',model.b)                                                   # 模型的阈值


# 计算阈值表与分数分布图
thd_tb    = br.report.get_threshold_tb(score,y,bin_step=10)                    # 阈值表
br.report.draw_score_disb(score,y,bin_step=10,figsize=(14, 4))                 # 分数分布






     评分卡建模结果     


代码运行结果如下:
  
在评分卡建模时,会先用逐步回归筛选变量,减少最终模型使用的变量个数
 如图所示,当添加marital变量时,AUC提升不明显,因此不再添加变量,最终只选择5个变量
建模完成后,可以看到模型的训练、测试数据的AUC和KS,以及模型的参数
 根据模型的参数,可知最终的逻辑回归模型表达式为:
 
 备注:这里各个变量的值指的是变量的woe,即上式中的rev变量指的是rev变量对应的woe值
评分卡结果
card.featureScore和card.baseScore里分别存放了特征得分与基础分
 两者合并后就是最终的评分卡表,如下:
   
使用上述卡表进行评分,只需计算出每个特征的得分,再加上基础分,就是总评分
 如果使用公式进行评分,需先通过card.factor和card.offset得到factor=-28.85,offset=712.87
 从而得到评分公式如下:
 
  这里各个变量的值指的是变量的woe,即上式中的rev变量指的是rev变量对应的woe值
阈值表与分数分布图
代码中的report.get_threshold_tb用于计算阈值表,report.draw_score_disb则用于绘制分数分布图
 阈值表计算结果如下: 
  
根据阈值表,就可以选择一个合适的阈值,用于判断样本是否能通过,具体方法见《阈值表与评分阈值》
所有样本的分数分布图如下:
 
 
这里的横轴代表的是分数起始值,例如610代表[610,620)之间的样本个数,其中绿色是好样本、红色是坏样本







好了,以上就是如何使用bbbrisk来实现一个评分卡的步骤与代码了~








 End 








联系老饼