python自动分箱,计算woe,iv的实例代码
作者:kidxu 发布时间:2022-10-13 22:51:50
笔者之前用R开发评分卡时,需要进行分箱计算woe及iv值,采用的R包是smbinning,它可以自动进行分箱。近期换用python开发, 也想实现自动分箱功能,找到了一个woe包,地址https://pypi.org/project/woe/,可以直接 pip install woe安装。
由于此woe包官网介绍及给的例子不是很好理解,关于每个函数的使用也没有很详细的说明,经过一番仔细探究后以此文记录一下该woe包的使用及其计算原理。
例子
官方给的例子不是很好理解,以下是我写的一个使用示例。以此例来说明各主要函数的使用方法。计算woe的各相关函数主要在feature_process.py中定义。
import woe.feature_process as fp
import woe.eval as eval
#%% woe分箱, iv and transform
data_woe = data #用于存储所有数据的woe值
civ_list = []
n_positive = sum(data['target'])
n_negtive = len(data) - n_positive
for column in list(data.columns[1:]):
if data[column].dtypes == 'object':
civ = fp.proc_woe_discrete(data, column, n_positive, n_negtive, 0.05*len(data), alpha=0.05)
else:
civ = fp.proc_woe_continuous(data, column, n_positive, n_negtive, 0.05*len(data), alpha=0.05)
civ_list.append(civ)
data_woe[column] = fp.woe_trans(data[column], civ)
civ_df = eval.eval_feature_detail(civ_list,'output_feature_detail_0315.csv')
#删除iv值过小的变量
iv_thre = 0.001
iv = civ_df[['var_name','iv']].drop_duplicates()
x_columns = iv.var_name[iv.iv > iv_thre]
计算分箱,woe,iv
核心函数主要是freature_process.proc_woe_discrete()与freature_process.proc_woe_continuous(),分别用于计算连续变量与离散变量的woe。它们的输入形式相同:
proc_woe_discrete(df,var,global_bt,global_gt,min_sample,alpha=0.01)
proc_woe_continuous(df,var,global_bt,global_gt,min_sample,alpha=0.01)
输入:
df: DataFrame,要计算woe的数据,必须包含'target'变量,且变量取值为{0,1}
var:要计算woe的变量名
global_bt:全局变量bad total。df的正样本数量
global_gt:全局变量good total。df的负样本数量
min_sample:指定每个bin中最小样本量,一般设为样本总量的5%。
alpha:用于自动计算分箱时的一个标准,默认0.01.如果iv_划分>iv_不划分*(1+alpha)则划分。
输出:一个自定义的InfoValue类的object,包含了分箱的一切结果信息。
该类定义见以下一段代码。
class InfoValue(object):
'''
InfoValue Class
'''
def __init__(self):
self.var_name = []
self.split_list = []
self.iv = 0
self.woe_list = []
self.iv_list = []
self.is_discrete = 0
self.sub_total_sample_num = []
self.positive_sample_num = []
self.negative_sample_num = []
self.sub_total_num_percentage = []
self.positive_rate_in_sub_total = []
self.negative_rate_in_sub_total = []
def init(self,civ):
self.var_name = civ.var_name
self.split_list = civ.split_list
self.iv = civ.iv
self.woe_list = civ.woe_list
self.iv_list = civ.iv_list
self.is_discrete = civ.is_discrete
self.sub_total_sample_num = civ.sub_total_sample_num
self.positive_sample_num = civ.positive_sample_num
self.negative_sample_num = civ.negative_sample_num
self.sub_total_num_percentage = civ.sub_total_num_percentage
self.positive_rate_in_sub_total = civ.positive_rate_in_sub_total
self.negative_rate_in_sub_total = civ.negative_rate_in_sub_total
打印分箱结果
eval.eval_feature_detail(Info_Value_list,out_path=False)
输入:
Info_Value_list:存储各变量分箱结果(proc_woe_continuous/discrete的返回值)的List.
out_path:指定的分箱结果存储路径,输出为csv文件
输出:
各变量分箱结果的DataFrame。各列分别包含如下信息:
var_name | 变量名 |
split_list | 划分区间 |
sub_total_sample_num | 该区间总样本数 |
positive_sample_num | 该区间正样本数 |
negative_sample_num | 该区间负样本数 |
sub_total_num_percentage | 该区间总占比 |
positive_rate_in_sub_total | 该区间正样本占总正样本比例 |
woe_list | woe |
iv_list | 该区间iv |
iv | 该变量iv(各区间iv之和) |
输出结果一个示例(截取部分):
woe转换
得到分箱及woe,iv结果后,对原数据进行woe转换,主要用以下函数
woe_trans(dvar,civ): replace the var value with the given woe value
输入:
dvar: 要转换的变量,Series
civ: proc_woe_discrete或proc_woe_discrete输出的分箱woe结果,自定义的InfoValue类
输出:
var: woe转换后的变量,Series
分箱原理
该包中对变量进行分箱的原理类似于二叉决策树,只是决定如何划分的目标函数是iv值。
1)连续变量分箱
首先简要描述分箱主要思想:
1.初始化数据集D =D0为全量数据。转步骤2
2.对于D,将数据按从小到大排序并按数量等分为10份,记录各划分点。计算不进行仍何划分时的iv0,转步骤3.
3.遍历各划分点,计算利用各点进行二分时的iv。
如果最大iv>iv0*(1+alpha)(用户给定,默认0.01): 则进行划分,且最大iv对应的即确定为此次划分点。它将D划分为左右两个结点,数据集分别为DL, DR.转步骤4.
否则:停止。
4.分别令D=DL,D=DR,重复步骤2.
为了便于理解,上面简化了一些条件。实际划分时还设计到一些限制条件,如不满足会进行区间合并。
主要限制条件有以下2个:
a.每个bin的数量占比>min_sample(用户给定)
b.每个bin的target取值个数>1,即每个bin必须同时包含正负样本。
2)连续变量分箱
对于离散变量分箱后续补充 to be continued...
来源:https://blog.csdn.net/KIDxu/article/details/88647080
猜你喜欢
- 问题的起源早些时候使用with实现了一版全局进程锁,希望实现以下效果:with CacheLock("test_lock"
- 呵呵,先说明一下下面的程序大部分收集自网络,因为本人在asp编程中经常使用到随机函数,所以收集了一些这类的函数,并做了些注释,方便使用。首发
- 本文实例为大家分享了PyQt5单行文本框展示的具体代码,供大家参考,具体内容如下QLineEdit 是一个允许输入和编辑纯文本的单行控件。系
- XML的嵌套处理 一般情况下,我们从数据库中查询得到的结果集可能很大,所以从服务器返回到客户端时,数据会被分成若干个页面分别进行传递。此时,
- 前段时间我通过观察韩国网站和其他作品发现了普遍存在黄金分割这样一个规律,不过只跟色相有关,明度、纯度还没做研究,今天看到论坛一篇“网页配色之
- 前言前面已经讲述了如何获取股票的k线数据,今天我们来分析一下股票的资金流入情况,股票的上涨和下跌都是由资金推动的,这其中的北上资金就是一个风
- 如下所示:import requestsurl='http://####'proxy={'http':
- * 对子查询和Join进行了优化,包括对MyISAD和InnoB存储引擎分散范围内的批量索引访问。* 增加了 BACKUP DATABASE
- 算法是计算机科学中一个重要的研究方向,是解决复杂问题的关键。在计算机世界中,算法无处不在。数据库是存储数据和执行大批量计算的场所,在数据库中
- PHP5.4才支持JSON_UNESCAPED_UNICODE这个参数,此参数是让中文字符在json_encode的时候不用转义,减少数据传
- { hide_text } CSS文字隐藏总结报告最近整理的一份CSS文字隐藏的demo,总结了几种方法,希望得出一种最完美的方案放进自己的
- 停止mysql服务(以管理员身份,在cmd命令行下运行) net stop mysql或者在服务中停止mysql服务。使用 mysqld –
- 我们现在回到函数上。记得我们用 SUM 这个指令来算出所有的 Sales (营业额)吧!如果我们的需求变成是要算出每一间店 (store_n
- 前言通常在读写文件之前,我们需要先判断文件或者目录是否存在。不然在接下来的处理中可能会报错。所以在做任何操作之前,最好还是先判断文件、目录是
- strIn 为 输入的Email地址字符串变量 返回为true或falsereturn Regex.IsMatch(strIn, @&quo
- 页面自动刷新代码大全,基本上所有要求自动刷新页面的代码都有,大家可以自由发挥做出完美的页面。 1)10表示间隔10秒刷 ...页面自动刷新代
- 1.intersect为取多个查询结果的交集;2.查询两个基本时间段内表记录的SQL语句;select * from shengjibiao
- 前言激活函数在机器学习中常常用在神经网络隐含层节点与神经网络的输出层节点上,激活函数的作用是赋予神经网络更多的非线性因素,如果不用激励函数,
- MapPathMapPath 方法将指定的相对或虚拟路径映射到服务器上相应的物理目录上。语法Server.MapPath( Path ) 参
- 4款JavaScript放大镜特效脚本。准确的说,Anythingzoomer和Bezoom才是正宗的放大镜特效,当鼠标悬浮在图片上时,能放