python自动分箱,计算woe,iv的实例代码


Posted in Python onNovember 22, 2019

笔者之前用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之和)

输出结果一个示例(截取部分):

python自动分箱,计算woe,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...

以上这篇python自动分箱,计算woe,iv的实例代码就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python Sleep休眠函数使用简单实例
Feb 02 Python
python数据类型_字符串常用操作(详解)
May 30 Python
python3学习笔记之多进程分布式小例子
Feb 13 Python
python使用udp实现聊天器功能
Dec 10 Python
Python 支付整合开发包的实现
Jan 23 Python
如何通过雪花算法用Python实现一个简单的发号器
Jul 03 Python
Ubuntu下Python+Flask分分钟搭建自己的服务器教程
Nov 19 Python
python 申请内存空间,用于创建多维数组的实例
Dec 02 Python
Python+OpenCV 实现图片无损旋转90°且无黑边
Dec 12 Python
python中图像通道分离与合并实例
Jan 17 Python
浅谈Python xlwings 读取Excel文件的正确姿势
Feb 26 Python
Python 中的 copy()和deepcopy()
Nov 07 Python
python创建学生管理系统
Nov 22 #Python
Python如何计算语句执行时间
Nov 22 #Python
python生成器用法实例详解
Nov 22 #Python
关于pandas的离散化,面元划分详解
Nov 22 #Python
Python协程 yield与协程greenlet简单用法示例
Nov 22 #Python
使用pandas实现连续数据的离散化处理方式(分箱操作)
Nov 22 #Python
在OpenCV里使用Camshift算法的实现
Nov 22 #Python
You might like
对Session和Cookie的区分与解释
2007/03/16 PHP
php获取qq用户昵称和在线状态(实例分析)
2013/10/27 PHP
PHP常用文件操作函数和简单实例分析
2016/06/03 PHP
静态html文件执行php语句的方法(推荐)
2016/11/21 PHP
php实现微信企业付款到个人零钱功能
2018/10/09 PHP
基于jQuery的弹出警告对话框美化插件(警告,确认和提示)
2010/06/10 Javascript
js 遍历对象的属性的代码
2011/12/29 Javascript
同一个网页中实现多个JavaScript特效的方法
2015/02/02 Javascript
Jquery attr()方法 属性赋值和属性获取详解
2016/04/15 Javascript
在AngularJS中使用jQuery的zTree插件的方法
2016/04/21 Javascript
浅谈JavaScript 覆盖原型以及更改原型
2016/08/31 Javascript
深入理解react-router@4.0 使用和源码解析
2017/05/23 Javascript
JavaScript学习笔记之惰性函数示例详解
2017/08/27 Javascript
详解基于mpvue微信小程序下载远程图片到本地解决思路
2019/05/16 Javascript
微信小程序 WXML节点信息查询详解
2019/07/29 Javascript
前端性能优化建议
2020/09/17 Javascript
vue解决跨域问题(推荐)
2020/11/10 Javascript
[50:05]VGJ.S vs OG 2018国际邀请赛淘汰赛BO3 第二场 8.22
2018/08/23 DOTA
关于Python的一些学习总结
2018/05/25 Python
Python读取数据集并消除数据中的空行方法
2018/07/12 Python
对pandas中Series的map函数详解
2018/07/25 Python
使用Python3+PyQT5+Pyserial 实现简单的串口工具方法
2019/02/13 Python
Python多线程及其基本使用方法实例分析
2019/10/29 Python
python的flask框架难学吗
2020/07/31 Python
Python logging模块原理解析及应用
2020/08/13 Python
CSS3实现曲线阴影和翘边阴影
2016/05/03 HTML / CSS
详解WebSocket跨域问题解决
2018/08/06 HTML / CSS
Html+Css+Jquery实现左侧滑动拉伸导航菜单栏的示例代码
2020/03/17 HTML / CSS
菲律宾旅游网站:Expedia菲律宾
2017/10/11 全球购物
什么是serialVersionUID
2016/03/04 面试题
俞敏洪北大演讲稿
2014/05/22 职场文书
高考升学宴答谢词
2015/01/20 职场文书
入党积极分子群众意见
2015/06/01 职场文书
python for循环赋值问题
2021/06/03 Python
SQL 尚未定义空闲 CPU 条件 - OnIdle 作业计划将不起任何作用
2021/06/30 SQL Server
bootstrapv4轮播图去除两侧阴影及线框的方法
2022/02/15 HTML / CSS