python实现卡方分箱Chi-Merge

卡方分箱是依赖于卡方检验的分箱方法,在统计指标上选择卡方统计量(chi-Square)进行判别,分箱的基本思想是判断相邻的两个区间是否有分布差异,基于卡方统计量的结果进行自下而上的合并,直到满足分箱的限制条件为止。

卡方分箱的实现步骤:

这里写图分箱述

卡方统计量衡量了区间内样本的频数分布与整体样本的频数分布的差异性,在做分箱处理时可以使用两种限制条件:

(1)分箱个数:限制最终的分箱个数结果,每次将样本中具有最小卡方值的区间与相邻的最小卡方区间进行合并,直到分箱个数达到限制条件为止。

(2)卡方阈值:根据自由度和显著性水平得到对应的卡方阈值,如果分箱的各区间最小卡方值小于卡方阈值,则继续合并,直到最小卡方值超过设定阈值为止。

在铺上代码前再补充两点,

1、由于卡方分箱是思想是相邻区间合并,在初始化时对变量属性需先进行排序,要注意名义变量的排序顺序

2、卡方阈值的自由度为 分箱数-1,显著性水平可以取10%,5%或1%

python代码实现:举例:卡方对二分类问题进行变量分箱

import pandas as pd
import numpy as np
from scipy.stats import chi2
def calc_chiSquare(sampleSet, feature, target):
    '''
    计算某个特征每种属性值的卡方统计量
    params: 
        sampleSet: 样本集
        feature: 目标特征
        target: 目标Y值 (0或1) Y值为二分类变量
    return:
        卡方统计量dataframe
        feature: 特征名称
        act_target_cnt: 实际坏样本数
        expected_target_cnt:期望坏样本数
        chi_square:卡方统计量
    '''
    # 计算样本期望频率
    target_cnt = sampleSet[target].sum()
    sample_cnt = len(sampleSet[target])
    expected_ratio = target_cnt * 1.0/sample_cnt 
    # 对变量按属性值从大到小排序
    df = sampleSe
  • 11
    点赞
  • 82
    收藏
    觉得还不错? 一键收藏
  • 21
    评论
方分箱是一种离散化方法,目的是将连续变量离散化为若干个分段,使得每个分段内变量的分布差异较小,不同分段之间的分布差异较大。在python中可以使用以下步骤实现: 1. 导入需要的库 ```python import pandas as pd import numpy as np import scipy.stats as ss ``` 2. 读入数据 ```python data = pd.read_csv('data.csv') ``` 3. 确定分箱个数 可以通过经验法则、等频分箱或等距分箱等方法确定分箱个数。 ```python # 等频分箱 data['rank'] = pd.qcut(data['feature'], 10, labels=False) ``` 4. 计算方值 方值可以衡量变量在不同分箱之间的差异程度。 ```python def chi2(df, total_col, bad_col, overall_rate): df2 = df.copy() df2['expected'] = df[total_col].apply(lambda x: x * overall_rate) combined = zip(df2['expected'], df2[bad_col]) chi = [(i[0]-i[1])**2/i[0] for i in combined] return sum(chi) total = data.groupby('rank').count()['feature'] bad = data.groupby('rank').sum()['target'] overall_rate = np.sum(bad) / np.sum(total) chi2_value = chi2(pd.concat([total, bad], axis=1), 'feature', 'target', overall_rate) ``` 5. 合并分箱 根据方值,将相邻的分箱合并,直到满足预设的最小方值。 ```python def merge(data, col, target, max_interval, min_chi2): total = data.groupby(col).count()[target] bad = data.groupby(col).sum()[target] overall_rate = np.sum(bad) / np.sum(total) group_intervals = [[i] for i in total.index] while len(group_intervals) > max_interval: chi2_values = [] for i in range(len(group_intervals)-1): new_interval = group_intervals[i] + group_intervals[i+1] df1 = pd.concat([total.loc[new_interval], bad.loc[new_interval]], axis=1) df2 = pd.concat([total.loc[group_intervals[i]], bad.loc[group_intervals[i]]], axis=1) df3 = pd.concat([total.loc[group_intervals[i+1]], bad.loc[group_intervals[i+1]]], axis=1) chi2_values.append(chi2(df1, 'feature', 'target', overall_rate) - chi2(df2, 'feature', 'target', overall_rate) - chi2(df3, 'feature', 'target', overall_rate)) if min(chi2_values) < min_chi2: merge_index = chi2_values.index(min(chi2_values)) group_intervals[merge_index] = group_intervals[merge_index] + group_intervals.pop(merge_index+1) else: break return group_intervals intervals = merge(data, 'rank', 'target', 10, 3.841) ``` 6. 将分箱结果应用到数据中 ```python def apply_intervals(x, intervals): for i in range(len(intervals)): if x in intervals[i]: return i data['rank_new'] = data['rank'].apply(lambda x: apply_intervals(x, intervals)) ``` 以上就是使用python实现方分箱的步骤。需要注意的是,方分箱并不是一种万能的离散化方法,应根据具体情况选择合适的方法。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值