数据分箱4——卡方最优分箱 ChiMerge算法使用(有监督)

论文地址:https://sci2s.ugr.es/keel/pdf/algorithm/congreso/1992-Kerber-ChimErge-AAAI92.pdf

Kerber, Randy. “Chimerge: Discretization of numeric attributes.” Proceedings of the tenth national conference on Artificial intelligence. 1992.

ChiMerge算法详解(英文):https://medium.com/@nithin_rajan/data-discretization-using-chimerge-55c8ade3cfda

ChiMerge算法借助卡方检验,算法思路是:

  1. 首先把每个值都当做一个独立的区间
  2. 循环地合并区间,如果卡方值小于4.6,则合并区间(90%置信度/10%显著性水平下,卡方的值为4.6)
  3. 直到满足所需的区间数或是全部的卡方都大于4.6为止

ChiMerge算法使用

为了方便与高效,我们借助第三方工具scorecardbundle

首先安装:

pip install -i https://pypi.org/project --upgrade scorecardbundle

Scorecard-Bundle github主页:https://github.com/Lantianzz/Scorecard-Bundle

示例代码

from scorecardbundle.feature_discretization.ChiMerge import ChiMerge
from sklearn.datasets import make_classification
import pandas as pd

if __name__ == '__main__':
    data_x, data_y = make_classification(n_samples=100, n_classes=4, n_features=10, n_informative=8, random_state=0)
    x_value = data_x[:, 0]
    y_value = data_y
    trans_cm = ChiMerge(max_intervals=10, min_intervals=2, decimal=3, output_dataframe=True)
    result_cm = trans_cm.fit_transform(pd.DataFrame(x_value), y_value)
    print("阈值:", trans_cm.boundaries_[0])
    print("分箱结果:", pd.cut(x_value, trans_cm.boundaries_[0]).codes)

算法python实现(可参考以下文章)

ChiMerge (Ker92):https://gist.github.com/alanzchen/17d0c4a45d59b79052b1cd07f531689e

ChiMerge算法:卡方检验+ChiMerge+Python:https://www.yanxishe.com/blogDetail/25070

注意:目前博主测试了四种复现方式,没有一个是能正常跑通的,很奇怪…而且复现的思路都有部分不同。如果有跑通的请在评论区发一下,相互学习

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
以下是一个简单的Python代码示例,用于将含有缺失值的数据进行卡方分箱: ```python import pandas as pd import numpy as np from scipy.stats import chi2_contingency def chisq_bin(data, col, target, max_bins=5, iv_min=0.02): """ 卡方分箱函数 :param data: 数据集 :param col: 需要分箱的变量 :param target: 目标变量 :param max_bins: 最大分箱数 :param iv_min: 最小IV值 :return: 分箱结果 """ data = data[[col, target]].copy() data['missing'] = data[col].isnull().astype(int) data = data.groupby(['missing', target]).size().unstack().fillna(0) data.columns = ['neg', 'pos'] data['tot'] = data['neg'] + data['pos'] data['neg_prop'] = data['neg'] / data['neg'].sum() data['pos_prop'] = data['pos'] / data['pos'].sum() data['tot_prop'] = data['tot'] / data['tot'].sum() data['woe'] = np.log((data['neg'] / data['neg'].sum()) / (data['pos'] / data['pos'].sum())) data['iv'] = (data['neg_prop'] - data['pos_prop']) * data['woe'] iv = data['iv'].sum() if iv < iv_min: return None cut_points = [np.nan] while len(cut_points) < max_bins: data = data.sort_values('woe') x = np.array(data['neg']) y = np.array(data['pos']) xy = np.array([x, y]) chisq = chi2_contingency(xy)[0] p = chi2_contingency(xy)[1] if p < 0.05: cut_point = data.index[0] cut_points.append(cut_point) data = data.loc[cut_point:].copy() data['woe'] = np.log((data['neg'] / data['neg'].sum()) / (data['pos'] / data['pos'].sum())) data['iv'] = (data['neg_prop'] - data['pos_prop']) * data['woe'] iv = data['iv'].sum() if iv < iv_min: break else: break cut_points.append(np.inf) labels = range(len(cut_points) - 1) result = pd.cut(data[col], cut_points, labels=labels, include_lowest=True) return result ``` 这个函数将缺失值视为一个单独的类别,并根据卡方检验的结果将数据分成多个箱子,返回一个Pandas Series对象,其中每个值表示变量的分箱编号。您可以使用此结果来替换原始数据中的变量,然后使用OneHot编码或WOE编码等其他技术进一步处理。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

呆萌的代Ma

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值