分箱

本文主要探讨了等频分箱方法,详细介绍了如何通过函数选择最佳的分箱数量,以优化数据预处理步骤。
摘要由CSDN通过智能技术生成

等频分箱

#按照等频对需要分箱的列进行分箱
model_data["qcut"], updown = pd.qcut(model_data["age"], retbins=True, q=20)
"""
pd.qcut,基于分位数的分箱函数,本质是将连续型变量离散化
只能够处理一维数据。返回箱子的上限和下限
参数q:要分箱的个数
参数retbins=True来要求同时返回结构为索引为样本索引,元素为分到的箱子的Series
现在返回两个值:每个样本属于哪个箱子,以及所有箱子的上限和下限
"""

#在这里时让model_data新添加一列叫做“分箱”,这一列其实就是每个样本所对应的箱子
model_data["qcut"]
#所有箱子的上限和下限
updown
# 统计每个分箱中0和1的数量
# 这里使用了数据透视表的功能groupby
coount_y0 = model_data[model_data["SeriousDlqin2yrs"] == 0].groupby(by="qcut").count()
["SeriousDlqin2yrs"]
coount_y1 = model_data[model_data["SeriousDlqin2yrs"] == 1].groupby(by="qcut").count()
["SeriousDlqin2yrs"]
#num_bins值分别为每个区间的上界,下界,0出现的次数,1出现的次数
num_bins = [*zip(updown,updown[1:],coount_y0,coount_y1)]
#注意zip会按照最短列来进行结合
num_bins

#确保每个箱中都有0和1
for i in range(20):  
    #如果第一个组没有包含正样本或负样本,向后合并
    if 0 in num_bins[0][2:]:
        num_bins[0:2] = [(
            num_bins[0][0],
            num_bins[1][1],
            num_bins[0][2]+num_bins[1][2],
            num_bins[0][3]+num_bins[1][3])]
        continue
        
    """
   合并了之后,第一行的组是否一定有两种样本了呢?不一定
   如果原本的第一组和第二组都没有包含正样本,或者都没有包含负样本,那即便合并之后,第一行的组也还是没有
包含两种样本
   所以我们在每次合并完毕之后,还需要再检查,第一组是否已经包含了两种样本
   这里使用continue跳出了本次循环,开始下一次循环,所以回到了最开始的for i in range(20), 让i+1
   这就跳过了下面的代码,又从头开始检查,第一组是否包含了两种样本
   如果第一组中依然没有包含两种样本,则if通过,继续合并,每合并一次就会循环检查一次,最多合并20次
   如果第一组中已经包含两种样本,则if不通过,就开始执行下面的代码
   """
    #已经确认第一组中肯定包含两种样本了,如果其他组没有包含两种样本,就向前合并
    #此时的num_bins已经被上面的代码处理过,可能被合并过,也可能没有被合并
    #但无论如何,我们要在num_bins中遍历,所以写成in range(len(num_bins))
    for i in range(len(num_bins)):
        if 0 in num_bins[i][2:]:
            num_bins[i-1:i+1] = [(
                num_bins[i-1][0],
                num_bins[i][1],
                num_bins[i-1][2]+num_bins[i][2],
   				num_bins[i-1][3]+num_bins[i][3])]
            break
        #如果对第一组和对后面所有组的判断中,都没有进入if去合并,则提前结束所有的循环
    else:
        break
    
    """
   这个break,只有在if被满足的条件下才会被触发
   也就是说,只有发生了合并,才会打断for i in range(len(num_bins))这个循环
   为什么要打断这个循环?因为我们是在range(len(num_bins))中遍历
   但合并发生后,len(num_bins)发生了改变,但循环却不会重新开始
   举个例子,本来num_bins是5组,for i in range(len(num_bins))在第一次运行的时候就等于for i in
range(5)
   range中输入的变量会被转换为数字,不会跟着num_bins的变化而变化,所以i会永远在[0,1,2,3,4]中遍历
   进行合并后,num_bins变成了4组,已经不存在=4的索引了,但i却依然会取到4,循环就会报错
   因此在这里,一旦if被触发,即一旦合并发生,我们就让循环被破坏,使用break跳出当前循环
   循环就会回到最开始的for i in range(20)中
   此时判断第一组是否有两种标签的代码不会被触发,但for i in range(len(num_bins))却会被重新运行
   这样就更新了i的取值,循环就不会报错了
   """
***#计算WOE和BAD RATE***
#BAD RATE与bad%不是一个东西
#BAD RATE是一个箱中,坏的样本所占的比例 (bad/total)
#而bad%是一个箱中的坏样本占整个特征中的坏样本的比例
def get_woe(num_bins):
    # 通过 num_bins 数据计算 woe
    columns = ["min"
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值