【特征工程】特征分箱


  对数据分析、机器学习、数据科学、金融风控等感兴趣的小伙伴,需要数据集、代码、行业报告等各类学习资料,可添加微信:wu805686220(记得要备注喔!),也可关注微信公众号:风控圏子(别打错字,是圏子,不是圈子,算了直接复制吧!)

关注公众号后,可联系圈子助手加入如下社群:

  • 机器学习风控讨论群(微信群)
  • 反欺诈讨论群(微信群)
  • python学习交流群(微信群)
  • 研习社资料(qq群:102755159)(干货、资料、项目、代码、报告、课件)

相互学习,共同成长。


脚本介绍:

  1)一份完整的自动化特征评估脚本

  2)包括数据预处理、特征分箱、特征重要性评估

作者:研习社-正阳

一. 导入相关工具和路径

在这里插入图片描述

二. 数据预处理

1.自定义缺失值处理函数

1.1 缺失值计算

计算特征数据缺失占比
在这里插入图片描述

1.2 按特征(列)删除
  • 若字段数据缺失严重,可先检查字段特性,是业务层面设计需求,或者是数据抓取异常
  • 如无上述问题,建议删除缺失值占比大于设定阈值的字段
  • 常见阈值为90%以上或者40%~50%以上,根据特征是否对应明确的业务含义而决定是否保留
    在这里插入图片描述
1.3 按样本(行)删除
  • 在无数据采集问题的情况下,若单样本数据缺失严重,可认为样本数据无效,建议删除。
    在这里插入图片描述

2. 自定义常变量处理函数

  • 同值化较严重的字段,如无特殊业务含义,某一数据占比超过阈值时,建议删除
    在这里插入图片描述

3. 自定义data_processing函数,执行完整数据预处理步骤:

1、导入数据

2、删除缺失值(自定义函数)

3、删除常变量(自定义函数)

  1)常变量(自定义函数)

  2)方差为0

4、缺失值填充

  1)分类型特征填充(自定义函数)

  2)连续型特征填充(自定义函数)


def data_processing(df, target):
    """
    df:包含了label和特征的宽表

    return:
    df :清洗后的数据集
    """
    # 特征缺失处理
    df = missing_delete_var(df, threshold=0.8)
    # 样本缺失处理
    df = missing_delete_user(df, threshold=int(df.shape[1] * 0.8))
    col_list = [x for x in df.columns if x != target]
    # 常变量处理
    df = const_delete(df, col_list, threshold=0.9)
    desc = df.describe().T
    # 剔除方差为0的特征
    std_0_col = list(desc[desc['std'] == 0].index)
    if len(std_0_col) > 0:
        df = df.drop(std_0_col, axis=1)
    df.reset_index(drop=True, inplace=True)

    # 缺失值计算和填充
    miss_df = missing_cal(df)
    cate_col = list(df.select_dtypes(include=['O']).columns)
    num_col = [x for x in list(df.select_dtypes(include=['int64', 'float64']).columns) if x != 'label']

    # 分类型特征填充
    cate_miss_col1 = [x for x in list(miss_df[miss_df.missing_pct > 0.05]['col']) if x in cate_col]
    cate_miss_col2 = [x for x in list(miss_df[miss_df.missing_pct <= 0.05]['col']) if x in cate_col]
    # 连续型特征填充
    num_miss_col1 = [x for x in list(miss_df[miss_df.missing_pct > 0.05]['col']) if x in num_col]
    num_miss_col2 = [x for x in list(miss_df[miss_df.missing_pct <= 0.05]['col']) if x in num_col]
    for col in cate_miss_col1:
        df[col] = df[col].fillna('未知')
    for col in cate_miss_col2:
        df[col] = df[col].fillna(df[col].mode()[0])
    for col in num_miss_col1:
        df[col] = df[col].fillna(-999)
    for col in num_miss_col2:
        df[col] = df[col].fillna(df[col].median())

    return df, miss_df

三、特征分箱

分箱逻辑:

1、类别型特征

  1)类别数在5个以下,可以直接根据类别来分箱 (binning_cate)

  2)类别数在5个以上,建议做降基处理,再根据降基后的类别做分箱

2、数值型特征

  1)离散型数值特征(特征value的变动幅度较小):

    若特征value的非重复计数在5个以下,可以直接根据非重复计数值来分箱(binning_cate)

    若特征value的非重复计数在5个以上,建议根据业务解释或者数据分布做自定义分箱(binning_self)

  2)连续型数值特征(特征value的变动幅度较大):

    可以用卡方分箱或自定义分箱。(binning_num,binning_self)

    PS:一些特征用卡方分可能会报错,建议这些特征改为手动自定义分箱

3、特征有缺失

  1)缺失率在5%以下,可以先对缺失做填充处理再分箱(binning_num)

  2)缺失率在5%以上,建议将缺失当作一个类别来分箱(binning_sparse_col)

4、稀疏特征分箱

  建议将稀疏值(一般为0)单独分为一箱,剩下的值做卡方或者自定义分箱(binning_sparse_col)

1.自定义指标评估函数

  • KS、precision、 tpr、 fpr
def cal_ks(df, col, target):
    """
    df:数据集
    col:输入的特征
    target:好坏标记的字段名

    return:
    ks: KS值
    precision:准确率
    tpr:召回率
    fpr:打扰率
    """

    bad = df[target].sum()
    good = df[target].count() - bad
    value_list = list(df[col])
    label_list = list(df[target])
    value_count = df[col].nunique()

    items = sorted(zip(value_list, label_list), key=lambda x: x[0])

    value_bin = []
    ks_list = []
    if value_count <= 200:
        for i in sorted(set(value_list)):
            value_bin.append(i)
            label_bin = [x[1] for x in items if x[0] < i]
            badrate = sum(label_bin) / bad
            goodrate = (len(label_bin) - sum(label_bin)) / good
            ks = abs(goodrate - badrate)
            ks_list.append(ks)
    else:
        for i in range(1, 201):
            step = (max(value_list) - min(value_list)) / 200
            idx = min(value_list) + i * step
            value_bin.append(idx)
            label_bin = [x[1] for x in items if x[0] < idx]
            badrate = sum(label_bin) / bad
            goodrate = (len(label_bin) - sum(label_bin)) / good
            ks = abs(goodrate - badrate)
            ks_list.append(ks)
    ks = round(max(ks_list), 3)

    ks_value = [value_bin[i] for i, j in enumerate(ks_list) if j 
  • 8
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值