python分箱_python 基于卡方值分箱算法的实现示例

原理很简单,初始分20箱或更多,先确保每箱中都含有0,1标签,对不包含0,1标签的箱向前合并,计算各箱卡方值,对卡方值最小的箱向后合并,代码如下

import pandas as pd

import numpy as np

import scipy

from scipy import stats

def chi_bin(DF,var,target,binnum=5,maxcut=20):

'''

DF:data

var:variable

target:target / label

binnum: the number of bins output

maxcut: initial bins number

'''

data=DF[[var,target]]

#equifrequent cut the var into maxcut bins

data["cut"],breaks=pd.qcut(data[var],q=maxcut,duplicates="drop",retbins=True)

#count 1,0 in each bin

count_1=data.loc[data[target]==1].groupby("cut")[target].count()

count_0=data.loc[data[target]==0].groupby("cut")[target].count()

#get bins value: min,max,count 0,count 1

bins_value=[*zip(breaks[:maxcut-1],breaks[1:],count_0,count_1)]

#define woe

def woe_value(bins_value):

df_woe=pd.DataFrame(bins_value)

df_woe.columns=["min","max","count_0","count_1"]

df_woe["total"]=df_woe.count_1+df_woe.count_0

df_woe["bad_rate"]=df_woe.count_1/df_woe.total

df_woe["woe"]=np.log((df_woe.count_0/df_woe.count_0.sum())/(df_woe.count_1/df_woe.count_1.sum()))

return df_woe

#define iv

def iv_value(df_woe):

rate=(df_woe.count_0/df_woe.count_0.sum())-(df_woe.count_1/df_woe.count_1.sum())

iv=np.sum(rate * df_woe.woe)

return iv

#make sure every bin contain 1 and 0

##first bin merge backwards

for i in range(len(bins_value)):

if 0 in bins_value[0][2:]:

bins_value[0:2]=[(

bins_value[0][0],

bins_value[1][1],

bins_value[0][2]+bins_value[1][2],

bins_value[0][3]+bins_value[1][3])]

continue

##bins merge forwards

if 0 in bins_value[i][2:]:

bins_value[i-1:i+1]=[(

bins_value[i-1][0],

bins_value[i][1],

bins_value[i-1][2]+bins_value[i][2],

bins_value[i-1][3]+bins_value[i][3])]

break

else:

break

#calculate chi-square merge the minimum chisquare

while len(bins_value)>binnum:

chi_squares=[]

for i in range(len(bins_value)-1):

a=bins_value[i][2:]

b=bins_value[i+1][2:]

chi_square=scipy.stats.chi2_contingency([a,b])[0]

chi_squares.append(chi_square)

#merge the minimum chisquare backwards

i = chi_squares.index(min(chi_squares))

bins_value[i:i+2]=[(

bins_value[i][0],

bins_value[i+1][1],

bins_value[i][2]+bins_value[i+1][2],

bins_value[i][3]+bins_value[i+1][3])]

df_woe=woe_value(bins_value)

#print bin number and iv

print("箱数:{},iv:{:.6f}".format(len(bins_value),iv_value(df_woe)))

#return bins and woe information

return woe_value(bins_value)

以下是效果:

初始分成10箱,目标为3箱

chi_bin(data,"age","SeriousDlqin2yrs",binnum=3,maxcut=10)

箱数:8,iv:0.184862

箱数:7,iv:0.184128

箱数:6,iv:0.179518

箱数:5,iv:0.176980

箱数:4,iv:0.172406

箱数:3,iv:0.160015

min max count_0 count_1 total bad_rate woe

0 0.0 52.0 70293 7077 77370 0.091470 -0.266233

1 52.0 61.0 29318 1774 31092 0.057056 0.242909

2 61.0 72.0 26332 865 27197 0.031805 0.853755

到此这篇关于python 基于卡方值分箱算法的实现示例的文章就介绍到这了,更多相关python 卡方值分箱算法内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

本文标题: python 基于卡方值分箱算法的实现示例

本文地址: http://www.cppcns.com/jiaoben/python/325430.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值