Python特征工程 — 1.2 特征分箱

news2024/10/7 20:33:33

目录

1 什么是特征分箱

2 分箱的重要性及其优势

3 有监督分箱

3.1卡方分箱原理

3.2 决策树分箱

4 无监督分箱

4.1 等距分箱

4.2 等频分箱

4.3 分位数分箱


实验数据:链接:https://pan.baidu.com/s/1yT1ct_ZM5uFLgcYsaBxnHg?pwd=czum  提取码:czum 

实验数据介绍:参考文章1.2节(数据介绍链接)

1 什么是特征分箱

特征分箱(Feature Binning)是一种数据预处理技术,主要用于将连续特征(或密集离散特征)转换为离散特征,可以提高模型的性能。

目的:特征分箱的目的是将连续(或密集离散)变量的值范围划分为多个区间(或“箱子”),并将这些区间映射到离散的类别或标签上。

原因:连续(或密集离散)变量可能包含非线性关系或复杂的模式,这些模式对于某些机器学习算法来说可能难以捕捉。通过分箱,我们可以将这些复杂的连续变量(或密集离散)简化为更易于模型处理的离散变量。

例如,我们有一组关于人年龄的数据,如下图所示:

现在希望将他们的年龄分组到更少的间隔中,可以通过设置一些条件来实现:

2 分箱的重要性及其优势

一般在建立分类模型时,需要对连续变量离散化,特征离散化后,模型会更稳定,降低了模型过拟合的风险。分箱的有以下重要性及其优势:

  • 易于迭代:离散化特征的增加和减少都很容易,便于模型快速迭代优化。
  • 计算效率:稀疏向量内积乘法运算速度快,计算结果方便存储,容易扩展;
  • 鲁棒性强:离散化后的特征对异常数据有很强的鲁棒性:比如一个特征是年龄>30是1,否则0。如果特征没有离散化,一个少见数据“年龄120岁”会给模型造成很大的干扰;
  • 特征交叉:离散化后可进行特征交叉,进一步增加非线性,提高模型的表达力。
  • 简化模型:降低过拟合风险,同时允许将缺失值视为独立类别,统一变量尺度。

3 有监督分箱

3.1卡方分箱原理

卡方分箱概念

卡方分箱(ChiMerge)是一种基于统计学原理的特征离散化方法,它依赖于卡方检验来评估相邻区间的类分布是否相似。如果两个相邻区间的类分布相似,则可以合并这些区间;如果不同,则应保持分开。卡方分箱的基本思想是在精确的离散化中,一个区间内的相对类频率应当完全一致。

卡方分布

为了更好地理解卡方分箱,我们先来看下卡方分布。卡方分布(Chi-square Distribution)是概率论与统计学中常用的一种概率分布,也是统计推断里应用最广泛的概率分布之一。卡方分布的定义基于标准正态分布,其数学定义如下:

若k个独立的随机变量Z1、Z2、……、Zk满足标准正态分布N(0,1),则这k个随机变量的平方和

服从自由度为k的卡方分布,记作:

卡方检验

卡方检验是以卡方分布为基础的一种假设检验方法。主要用于比较观察值和期望值之间是否存在差异。这种方法特别适用于分类数据,如性别、教育水平等。

其基本思想是根据样本数据推断总体的分布与期望分布是否有显著差异,或者推断两个分类变量是否相关或者独立。一般可以设原假设为:观察频数和期望频数没有差异,或者两个变量相互独立不相关,即该因素不会影响到目标变量。

实际应用中,我们先假设原假设成立,计算出卡方值,卡方值的计算公式为:

其中,A为实际频数,E为期望频数。

该假设计算出卡方值,它表示观察值与理论值之间的偏离程度。根据卡方分布及自由度可以确定在原假设成立的情况下获得当前统计量及更极端情况的概率P。

其中第一列对应自由度,红框中对应P值,不同自由度和P值对应的是卡方值。可以发现相同自由度下,卡方值越大,P值越小。反过来,如果P值越小,则卡方值越大,说明观察值与理论值偏离程度太大,应当拒绝原假设。

卡方分箱的基本思想在于,对于精确的离散化,相对类频率在一个区间内应当完全一致。因此,如果两个相邻的区间具有非常类似的类分布,则这两个区间可以合并,否则,它们应当保持分开。

卡方分箱步骤

(1) 初始分箱:将连续变量的值范围分成多个初始的区间(箱子)。可以基于等宽(每个箱子的值范围相同)或等频(每个箱子的样本数量大致相同)。

(2) 计算卡方统计量:使用以下公式计算卡方统计量,以评估箱子之间的独立性:

其中,A为实际频数,E为期望频数。

(3) 合并箱子:选择具有最小卡方统计量的箱子对进行合并。对于每一对相邻箱子,如果它们的卡方统计量小于某个阈值(基于p值),则认为这两个箱子在目标变量的分布上没有显著差异,可以合并。

(4) 迭代过程:重复步骤2到3,直到满足终止条件,如达到预定的箱子数量或无法进一步合并。

3.2 决策树分箱

决策树分箱通过评估不同的分割点来寻找最优的分箱边界,从而使得每个箱内的数据在目标变量上尽可能地同质。通过这种方式,决策树能够学习到数据中的复杂模式,并在分类或回归任务中提高模型的预测准确性。

在决策树分箱过程中,算法会遍历数据集中的所有特征,并尝试在每个特征上进行分割,以减少节点的不纯度。不纯度的度量可以基于信息熵或基尼不纯度等指标。算法递归地选择最优的分割点,直到满足停止条件,如达到预设的最大树深度或节点中的样本数量低于某个阈值。这种方法不仅提高了模型的泛化能力,还增强了模型的可解释性,因为分箱后的特征更容易被人类理解和解释。

4 无监督分箱

4.1 等距分箱

等距分箱(Equal-width binning)是一种简单的分箱技术,它将数据范围划分为若干个等宽的区间。等距分箱通常用于数据可视化和预处理,尤其是在数据分布比较均匀时。

import pandas as pd

def equal_width_binning(df, column_name, num_bins, print_info=True):
    """
    对指定的列进行等距分箱,并可选择打印分箱信息。
    
    参数:
    df : pd.DataFrame,输入的DataFrame。
    column_name : str,要分箱的列名。
    num_bins : int,箱的数量。
    print_info : bool, optional,是否打印分箱信息,默认为True。
        
    返回:
    pd.DataFrame
        包含原始数据和分箱结果的新DataFrame。
    """
    # 检查列是否存在于DataFrame中
    if column_name not in df.columns:
        raise ValueError(f"Column '{column_name}' does not exist in the DataFrame.")
    
    # 检查箱的数量是否为正数
    if num_bins <= 0:
        raise ValueError("Number of bins must be a positive integer.")
    
    # 计算箱宽
    bin_width = (df[column_name].max() - df[column_name].min()) / num_bins
    
    # 创建箱边界
    bins = [df[column_name].min() + i * bin_width for i in range(num_bins + 1)]
    
    # 打印分箱信息
    if print_info:
        print(f"Column: {column_name}")
        print(f"Number of bins: {num_bins}")
        print(f"Bin width: {bin_width:.2f}")
        print("Bin edges:")
        print(bins)
    
    # 将数据分到箱中
    binned_column_name = f"{column_name}_binned"
    df[binned_column_name] = pd.cut(df[column_name], bins=bins, right=True)
    
    return df
# 示例用法
# 假设df是您的DataFrame,'feature_column'是您要分箱的特征列名
df_binned = equal_width_binning(data, 'Age', num_bins=5)
df_binned

 对数据的‘Age’进行等距分段,运行的结果如下:

4.2 等频分箱

等频分箱(Equal-frequency binning)是一种将数据分为具有相同或几乎相同数据点数量的箱的技术。这种方法确保每个箱内的数据点数量大致相等,而不是箱的大小(宽度或范围)相等。等频分箱对于数据的分布不均匀或有极端值时特别有用。

import pandas as pd

def equal_frequency_binning(df, column_name, num_bins, print_info=True):
    """
    对指定的列进行等频分箱,并可选择打印分箱信息。
    
    参数:
    df : pd.DataFrame,输入的DataFrame。
    column_name : str,要分箱的列名。
    num_bins : int,箱的数量。
    print_info : bool, optional,是否打印分箱信息,默认为True。 
    返回:pd.DataFrame,包含原始数据和分箱结果的新DataFrame。
    """
    # 参数检查
    if column_name not in df.columns:
        raise ValueError(f"Column '{column_name}' does not exist in the DataFrame.")
    if num_bins <= 0:
        raise ValueError("Number of bins must be a positive integer.")
    
    # 对数据进行排序
    df_sorted = df.sort_values(by=column_name)
    
    # 计算每个箱的大致数据点数量
    bin_size = len(df) // num_bins
    
    # 确定箱边界
    bins = [df_sorted[column_name].min()]  # 包括最小值
    for i in range(1, num_bins):
        bin_bound = df_sorted.iloc[i * bin_size - 1][column_name]
        bins.append(bin_bound)  # 包括最大值
    bins.append(df_sorted[column_name].max())  # 包括最大值

    # 打印分箱信息
    if print_info:
        print(f"Column: {column_name}")
        print(f"Number of bins: {num_bins}")
        print("Bin edges:")
        for i, bin_edge in enumerate(bins[:-1]):
            print(f"Bin {i}: x <= {bin_edge}")
        print(f"Bin {num_bins - 1}: x > {bins[-2]}")
        print("Bin centers and counts:")
        for i in range(num_bins):
            center = df_sorted.iloc[(i * bin_size + (i + 1) * bin_size) // 2][column_name]
            count = len(df_sorted[(df_sorted[column_name] > bins[i]) & (df_sorted[column_name] <= bins[i + 1])])
            print(f"Bin {i} center: {center}, count: {count}")
    
    # 将数据分到箱中
    df[f'{column_name}_binned'] = pd.cut(df[column_name], bins=bins, right=True, labels=range(num_bins))

    return df
# 示例用法
# 假设df是您的DataFrame,'feature_column'是要分箱的特征列名
df_binned = equal_frequency_binning(data, 'Age', num_bins=5)
df_binned

 对数据的‘Age’进行等距分段,运行的结果如下,可也看到不同区间有大致相同的数量:

4.3 分位数分箱

分位数分箱(Quantile Binning)是一种基于数据分布的分箱技术,它利用数据的分位数来确定分箱边界。这种方法可以确保每个箱内的数据点具有相似的累积概率,从而使得每个箱在统计上是相似的。分位数分箱对于处理具有偏态分布的数据特别有用。

import pandas as pd

def quantile_binning(df, column_name, num_bins, print_info=True):
    """
    对指定的列进行分位数分箱,并可选择打印分位数信息。
    
    参数:
    df : pd.DataFrame,输入的DataFrame。
    column_name : str,要分箱的列名。
    num_bins : int,箱的数量。
    print_info : bool, optional,是否打印分位数信息,默认为True。
    返回:pd.DataFrame,包含原始数据和分箱结果的新DataFrame。
    """
    # 参数检查
    if column_name not in df.columns:
        raise ValueError(f"Column '{column_name}' does not exist in the DataFrame.")
    if num_bins <= 1:
        raise ValueError("Number of bins must be greater than 1.")

    # 计算分位数
    quantiles = df[column_name].quantile([(i + 1) / num_bins for i in range(num_bins - 1)])
    
    # 确定箱边界
    bins = [df[column_name].min()] + quantiles.tolist() + [df[column_name].max()]

    # 打印分位数信息
    if print_info:
        print(f"Column: {column_name}")
        print(f"Number of bins: {num_bins}")
        print("Quantile cuts:")
        for i, quantile in enumerate(quantiles, start=1):
            print(f"Quantile {i}/{num_bins}: {quantile}")

    # 将数据分到箱中
    df[f'{column_name}_binned'] = pd.cut(df[column_name], bins=bins, right=True, labels=range(num_bins))

    return df
# 示例用法
# 假设df是您的DataFrame,'feature_column'是您要分箱的特征列名
df_binned = quantile_binning(data, 'Age', num_bins=5)

 对数据的‘Age’进行等距分段,运行的结果如下,可也看到不同分位数下的分段点:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1886849.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JAVA期末速成库(11)第十二章

一、习题介绍 第十二章 Check Point&#xff1a;P454 12.1&#xff0c;12.9&#xff0c;12.10&#xff0c;12,12 二、习题及答案 12.1 What is the advantage of using exception handling? 12.1使用异常处理的优势是什么? 答:使用异常处理有以下优势&#xff1a; 1. 提高…

浙江建筑安全员A证2024年最新考试题库练习

46.总承包单位依法将建设工程分包给其他单位的&#xff0c;分包合同中应当明确各自的安全生产方面的权利、义务。总承包单位对分包工程的安全生产承担&#xff08;&#xff09;责任。 A.全部 B.主要 C.部分 D.连带 答案&#xff1a;D 47.实施总承报的建设工程发生事故&…

一首歌的时间 写成永远

大家好&#xff0c;我是秋意零。 就在&#xff0c;2024年6月20日。我本科毕业了&#xff0c;之前专科毕业挺有感触&#xff0c;也写了一篇文章进行记录。如今又毕业了&#xff0c;还是写一篇文章记录吧&#xff01;&#xff01; 专科毕业总结&#xff1a;大学三年总结&#xf…

编译原理1

NFA&DFA 在正规式的等价证明可以借助正规集&#xff0c;也可以通过有限自动机DFA来证明等价&#xff0c;以下例题是针对DFA证明正规式的等价&#xff0c;主要步骤是①NFA&#xff1b;②状态转换表&#xff1b; ③状态转换矩阵&#xff1b; ④化简DFA&#xff1b; 文法和语…

【关于C/C++中的scanf不能使用问题】

方法1&#xff1a;scanf_s 方法2&#xff1a;看见后面的日志了吗 CRT……&#xff1f;在第一行加上#define 日志 方法3&#xff1a;#pragma warning&#xff08;disable&#xff1a;4996&#xff09; 4996是我们的报错序号

B站、小红书崩,原因竟然是...它

B站崩&#xff01;小红书崩&#xff01; 大家好&#xff0c;我是那个在B站和小红书崩溃时&#xff0c;还在试图刷新页面的技术博主。到底是怎么一回事儿&#xff1f;今天&#xff0c;让我们一起来‘挖掘’这场技术‘灾难’的真相。 上午 10 点左右&#xff0c;微信技术群里突…

西南交通大学【算法分析与设计实验1】

实验1.4 有向图拓扑排序 实验目的 &#xff08;1&#xff09;掌握算法的自然语言描述法&#xff0c;流程图绘制方法以及伪代码描述方法。 &#xff08;2&#xff09;理解算法的执行过程。 &#xff08;3&#xff09;掌握算法的编程实现方法、调试方法及测试方法。 实验任务…

JSON JOLT常用示例整理

JSON JOLT常用示例整理 1、什么是jolt Jolt是用Java编写的JSON到JSON转换库&#xff0c;其中指示如何转换的"specification"本身就是一个JSON文档。以下文档中&#xff0c;我统一以 Spec 代替如何转换的"specification"json文档。以LHS(left hand side)代…

【AIGC X UML 落地】从UML语句到UML图形的生成,来看Agent插件的制作

上篇我们讲到如何通过多智能体实现自然语言绘制UML图。 没有看过的,可以去看下原文:《【AIGC X UML 落地】通过多智能体实现自然语言绘制UML图》 其中有一个实现重点,就是如何将 PlantUML 语句生成 UML 图片。在这里笔者是通过自定义 Agent 插件来实现这一流程。 本文,就此…

disql使用

进入bin目录&#xff1a;cd /opt/dmdbms/bin 启动disql&#xff1a;./disql&#xff0c;然后输入用户名、密码 sh文件直接使用disql&#xff1a; 临时添加路径到PATH环境变量&#xff1a;在当前会话中临时使用disql命令而无需每次都写完整路径&#xff0c;可以在执行脚本之前…

在非 antd pro 项目中使用 umi OpenAPI

大家好&#xff0c;我是松柏。自从跟着鱼皮哥使用了ant design pro中的OpenAPI插件之后&#xff0c;我已经无法忍受自己写请求后端接口的方法了&#xff0c;所以这篇文章记录一下如何在非ant design pro项目中使用OpenAPI。 安装依赖 首先我们需要安装包umijs/openapi&#x…

02归并排序——分治递归

02_归并排序_——分治_递归_ #include <stdio.h>void merge(int arr[], int l, int m, int r) {int n1 m -l 1;int n2 r -m;//创建临时数组int L[n1], R[n2];for(int i 0; i < n1; i){L[i] arr[l i];}for(int j 0; j < n2; j){R[j] arr[m 1 j];}int i …

STM32 ADC精度提升方法

STM32 ADC精度提升方法 Fang XS.1452512966qq.com如果有错误&#xff0c;希望被指出&#xff0c;学习技术的路难免会磕磕绊绊量的积累引起质的变化 硬件方法 优化布局布线&#xff0c;尽量减小其他干扰增加电源、Vref去耦电容使用低通滤波器&#xff0c;或加磁珠使用DCDC时尽…

【驱动篇】龙芯LS2K0300之红外驱动

实验目标 编写HX1838红外接收器驱动&#xff0c;根据接收的波形脉冲解码红外按键键值 模块连接 模块连接&#xff1a;VCC接Pin 2&#xff0c;GND接Pin1&#xff0c;DATA接Pin16 驱动代码 HX1838 GPIO初始化&#xff0c;申请中断&#xff0c;注意&#xff1a;GPIO48默认是给…

Spring Boot 中 PGSQL 判断打卡点是否经过轨迹优化代码,循环查询物理表修改生成临时表,向临时表插入数据后再做ST_DWithin判断

记录一下一个业务问题&#xff0c;流程是这样的&#xff0c;我现在有一个定时任务&#xff0c;5分钟执行一次&#xff0c;更新车辆打卡的情况。现在有20俩车&#xff0c;每辆车都分配了路线&#xff0c;每条路线都有打卡点&#xff0c;每个打卡点分配了不同的时间段&#xff0c…

【动态规划 前缀和】2478. 完美分割的方案数

本文涉及知识点 划分型dp 动态规划汇总 C算法&#xff1a;前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频 LeetCode 2478. 完美分割的方案数 给你一个字符串 s &#xff0c;每个字符是数字 ‘1’ 到 ‘9’ &#xff0c;再给你两个整数 k 和 minLength 。 如…

Redis---保证主从节点一致性问题 +与数据库数据保持一致性问题

保证主从节点一致性问题 Redis的同步方式默认是异步的&#xff0c;这种异步的同步方式导致了主从之间的数据存在一定的延迟&#xff0c;因此Redis默认是弱一致性的。 解决&#xff1a; 1.使用Redisson这样的工具&#xff0c;它提供了分布式锁的实现&#xff0c;确保在分布式环…

python自动化运维--DNS处理模块dnspython

1.dnspython介绍 dnspython是Pyhton实现的一个DNS工具包&#xff0c;他几乎支持所有的记录类型&#xff0c;可以用于查询、传输并动态更新ZONE信息&#xff0c;同事支持TSIG&#xff08;事物签名&#xff09;验证消息和EDNS0&#xff08;扩展DNS&#xff09;。在系统管理方面&a…

京东云备案流程图_云主机快速ICP备案_京东云服务器备案问题解答

京东云ICP备案流程&#xff0c;备案包括网站和APP备案&#xff0c;以及备案问题解答FAQ&#xff0c;阿腾云以京东云网站域名备案流程为例&#xff0c;先填写主办单位信息&#xff0c;选择网站备案或APP备案&#xff0c;申请授权码并验证&#xff0c;填写并上传主办单位详细信息…

老挝语翻译成简体中文推荐用什么翻译工具?《老挝语翻译通》App满足你所有翻译需求!

如果你正在找一款支持把老挝语翻译成中文&#xff0c;或者把中文翻译成老挝语的翻译工具&#xff0c;不得不推荐你使用《老挝语翻译通》App&#xff0c;您的随身老挝语翻译官&#xff0c;带您轻松跨越语言障碍。 功能亮点&#xff1a; 实时翻译&#xff1a;中文与老挝语的无缝…