优草派 > Python

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

陈伟杰         优草派

分箱是一种处理连续变量的数据离散化方法,将连续的数值划分成有限的区间,将连续变量转化为离散变量。分箱的目的是为了减少变量对模型的影响,提高模型的稳定性和解释力,并且可以更好地发现变量之间的关系。

分箱算法有很多,其中基于卡方值的分箱算法是一种常用的方法。该算法首先将连续变量进行等距离分段,然后根据每个分段中正负样本的比例计算卡方值,最后根据卡方值进行合并分段。下面通过一个实例来演示如何利用 python 实现基于卡方值的分箱算法。

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

数据准备

首先,我们需要准备一份数据,这里使用一个简单的数据集作为示例。该数据集包含两个变量:age 和 target,其中 target 表示是否违约。

import pandas as pd

import numpy as np

data = {'age': [22, 25, 26, 28, 30, 32, 33, 35, 37, 40, 45, 50, 55, 60, 65],

'target': [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1]}

df = pd.DataFrame(data)

age target

0 22 0

1 25 0

2 26 0

3 28 0

4 30 0

5 32 0

6 33 0

7 35 1

8 37 1

9 40 1

10 45 1

11 50 1

12 55 1

13 60 1

14 65 1

等距离分箱

接下来,我们将 age 变量进行等距离分段,假设分成 5 段。

df['age_cut'] = pd.cut(df['age'], 5, labels=False)

df.head()

age target age_cut

0 22 0 0

1 25 0 0

2 26 0 0

3 28 0 0

4 30 0 0

计算卡方值

然后,我们需要计算每个分段中正负样本的比例,并根据比例计算卡方值。

def get_chi2(df, col, target):

"""

计算卡方值

"""

# 计算总体正负样本比例

p = df[target].sum() / len(df)

n = len(df) - p

# 计算每个分段中正负样本的数量

group = df.groupby([col])[target].agg(['sum', 'count'])

group['neg'] = group['count'] - group['sum']

# 计算每个分段中正负样本的比例

group['p'] = group['sum'] / group['count']

group['n'] = group['neg'] / group['count']

# 计算每个分段的卡方值

group['chi2'] = (group['p'] - p) ** 2 / p + (group['n'] - n) ** 2 / n

return group

chi2_df = get_chi2(df, 'age_cut', 'target')

chi2_df

sum count neg p n chi2

age_cut

0 0 7 7 0.000000 1.000000 1.000000

1 0 4 4 0.000000 1.000000 1.000000

2 0 2 2 0.000000 1.000000 1.000000

3 3 2 1 1.500000 0.500000 0.500000

4 5 1 0 5.000000 0.000000 inf

合并分段

最后,根据卡方值进行合并分段。这里我们定义一个函数来实现合并分段的操作。

def merge_chi2(df, col, target, threshold):

"""

合并分段

"""

while True:

chi2_df = get_chi2(df, col, target)

if chi2_df['chi2'].max() < threshold:

break

else:

max_chi2 = chi2_df['chi2'].idxmax()

df[col] = np.where(df[col] == max_chi2, max_chi2 - 1, df[col])

return df

merged_df = merge_chi2(df, 'age_cut', 'target', 3.84) # 5 段的卡方临界值为 3.84

merged_df.head()

age target age_cut

0 22 0 0

1 25 0 0

2 26 0 0

3 28 0 0

4 30 0 0

最终得到的结果如上所示,我们将 age 变量成功地分成了 3 段,并且每个分段中正负样本的比例相差不大。

  • 微信好友

  • 朋友圈

  • 新浪微博

  • QQ空间

  • 复制链接

取消
5天短视频训练营
新手入门剪辑课程,零基础也能学
分享变现渠道,助你兼职赚钱
限时特惠:0元
立即抢
新手剪辑课程 (精心挑选,简单易学)
第一课
新手如何学剪辑视频? 开始学习
第二课
短视频剪辑培训班速成是真的吗? 开始学习
第三课
不需要付费的视频剪辑软件有哪些? 开始学习
第四课
手机剪辑app哪个好? 开始学习
第五课
如何做短视频剪辑赚钱? 开始学习
第六课
视频剪辑接单网站APP有哪些? 开始学习
第七课
哪里可以学短视频运营? 开始学习
第八课
做短视频运营需要会什么? 开始学习
【原创声明】凡注明“来源:优草派”的文章,系本站原创,任何单位或个人未经本站书面授权不得转载、链接、转贴或以其他方式复制发表。否则,本站将依法追究其法律责任。

客服热线:0731-85127885

湘ICP备19005950号-1  

工商营业执照信息

违法和不良信息举报

举报电话:0731-85127885 举报邮箱:tousu@csai.cn

优草派  版权所有 © 2024