原理很简单,初始分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
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件!
如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
白云城资源网 Copyright www.dyhadc.com
暂无“python 基于卡方值分箱算法的实现示例”评论...
更新日志
2024年11月08日
2024年11月08日
- 雨林唱片《赏》新曲+精选集SACD版[ISO][2.3G]
- 罗大佑与OK男女合唱团.1995-再会吧!素兰【音乐工厂】【WAV+CUE】
- 草蜢.1993-宝贝对不起(国)【宝丽金】【WAV+CUE】
- 杨培安.2009-抒·情(EP)【擎天娱乐】【WAV+CUE】
- 周慧敏《EndlessDream》[WAV+CUE]
- 彭芳《纯色角3》2007[WAV+CUE]
- 江志丰2008-今生为你[豪记][WAV+CUE]
- 罗大佑1994《恋曲2000》音乐工厂[WAV+CUE][1G]
- 群星《一首歌一个故事》赵英俊某些作品重唱企划[FLAC分轨][1G]
- 群星《网易云英文歌曲播放量TOP100》[MP3][1G]
- 方大同.2024-梦想家TheDreamer【赋音乐】【FLAC分轨】
- 李慧珍.2007-爱死了【华谊兄弟】【WAV+CUE】
- 王大文.2019-国际太空站【环球】【FLAC分轨】
- 群星《2022超好听的十倍音质网络歌曲(163)》U盘音乐[WAV分轨][1.1G]
- 童丽《啼笑姻缘》头版限量编号24K金碟[低速原抓WAV+CUE][1.1G]