36 0

[作业] 离散化解释:为初学者提供的带代码示例的可视化指南 [推广有奖]

  • 0关注
  • 0粉丝

等待验证会员

学前班

40%

还不是VIP/贵宾

-

威望
0
论坛币
0 个
通用积分
0
学术水平
0 点
热心指数
0 点
信用等级
0 点
经验
20 点
帖子
1
精华
0
在线时间
0 小时
注册时间
2018-2-26
最后登录
2018-2-26

楼主
小蜜蜂我爱你 发表于 2025-12-3 21:46:23 |AI写论文

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币

数据预处理

6 种有趣的方法将数字分类到区间中!

towardsdatascience.com/discretization-explained-a-visual-guide-with-code-examples-for-beginners-f056af9102fa?source=collection_archive---------5-----------------------#2024-10-22

机器学习任务中,大多数模型要求输入数据为数值型格式——这意味着所有类别或对象类型的数据都需要先转换为数字。然而,在某些情况下,将数值数据反过来转化为分类形式反而更具优势。这种转化过程被称为“离散化”或“分箱”,它能帮助我们将连续的数值划分为有意义的区间类别,从而提升模型表现或增强数据可读性。

本文将介绍六种不同的分箱方法,并通过一个简单的人工数据集进行演示。从等宽划分到基于聚类的技术,我们将展示如何有效地将连续变量转换为离散区间。

?? 更多 [数据预处理](https://medium.com/@samybaladram/list/data-preprocessing-17a2c49b44e4) 解释:· 缺失值插补 · 分类编码 · 数据缩放 ? 离散化 · 过采样与欠采样 · 数据泄露与预处理

什么是离散化?

离散化(又称分箱)是指将连续的数值变量划分为若干个离散区间(即“箱”),并将原始值替换为其所属区间的标签。这一过程使得原本精确的数值被归入更宽泛但更具解释性的类别中。

为什么需要进行分箱?

  • 处理异常值: 分箱可以弱化极端值对模型的影响,而无需直接删除这些数据点。
  • 提高模型性能: 某些算法(如伯努利朴素贝叶斯)更适合处理类别型输入,因此分箱有助于提升其准确率。
  • 简化可视化: 离散化的数据更容易用柱状图、热力图等方式呈现和理解。
  • 减少过拟合: 通过对数值进行粗粒度划分,避免模型过度依赖细微的数据波动,从而降低过拟合风险。

哪些数据适合分箱?

以下类型的变量通常可以从分箱操作中获益:

  • 范围较广的连续变量: 当数值跨度大时,分组有助于提取趋势信息。
  • 偏态分布的数据: 对高度右偏或左偏的数据进行分箱,有助于平衡各类别之间的分布。
  • 包含异常值的变量: 极端值可被纳入边界箱中,减少其对整体分析的干扰。
  • 高基数数值特征: 具有大量唯一值的变量可通过分箱降低复杂度。

哪些数据一般不需要分箱?

  • 已为类别型的数据: 如性别、城市名称等,本身已是离散类别,无需再处理。
  • 取值较少的离散数值: 若某变量仅有几个可能值(如评分1–5),进一步分箱意义不大。
  • 数字ID或编码: 这些用于标识而非分析的字段不应参与分箱。
  • 时间序列数据: 虽然时间可以被切分为小时、日、周等,但需使用专门的时间处理技术,常规分箱并不适用。

数据集说明

为了直观展示各种分箱方法的应用效果,我们构建了一个模拟数据集,代表某高尔夫球场在连续15天内记录的天气状况。数据包括以下字段:

  • 紫外线指数: 范围0–11
  • 湿度: 百分比表示(%)
  • 风速: 单位为英里每小时(mph)
  • 降水量: 单位为毫米(mm)
  • 温度: 华氏度(°F)
  • 拥挤度: 数值介于0(空)到1(满)之间
import pandas as pd
import numpy as np

# 创建数据字典
data = {
'UVIndex': [2, 10, 1, 7, 3, 9, 5, 11, 1, 8, 3, 9, 11, 5, 7],
'Humidity': [15, 95, 10, 98, 18, 90, 25, 80, 95, 40, 20, 30, 85, 92, 12],
'WindSpeed': [2, 90, 1, 30, 3, 10, 40, 5, 60, 15, 20, 45, 25, 35, 50],
'RainfallAmount': [5,2,7,3,18,3,0,1,25,0,9,0,18,7,0],
[此处为图片3]
{
'Temperature': [68, 60, 63, 55, 50, 56, 57, 65, 66, 68, 71, 72, 79, 83, 81],
'Crowdedness': [0.15, 0.98, 0.1, 0.85, 0.2, 0.9, 0.92, 0.25, 0.12, 0.99, 0.2, 0.8, 0.05, 0.3, 0.95]
}

基于上述数据集,我们将探讨多种分箱技术在不同变量上的应用方式。

方法 1:等宽分箱

等宽分箱通过将变量的取值范围划分为若干个宽度相等的区间来实现离散化处理。每个箱子覆盖相同的数值跨度。

适用场景:当数据分布较为均匀,并且极值具有实际意义时,该方法表现良好。

本例应用:我们对“紫外线指数(UVIndex)”采用等宽分箱策略,设定四个类别——低、适中、高、非常高。这种划分方式有助于清晰理解不同强度的紫外线如何影响高尔夫运动决策。

towardsdatascience.com/discretization-explained-a-visual-guide-with-code-examples-for-beginners-f056af9102fa?source=collection_archive---------5-----------------------#2024-10-22

# 等宽分箱代码示例:

df['UVIndexBinned'] = pd.cut(df['UVIndex'], bins=4,
labels=['Low', 'Moderate', 'High', 'Very High'])

方法 2:等频分箱(分位数分箱)

等频分箱确保每个箱子中包含大致相同数量的样本点,即每个区间的观测数接近一致。

适用场景:适用于偏态分布的数据,或需要平衡各类别样本量的情况。

本例应用:针对湿度(Humidity)变量,我们使用三分位法进行分箱,生成“低”、“中”、“高”三个等级。此方法能有效应对湿度值在整体范围内不均匀分布的问题。

?? 更多 [数据预处理](https://medium.com/@samybaladram/list/data-preprocessing-17a2c49b44e4) 解释:· 缺失值插补 · 分类编码 · 数据缩放 ? 离散化 · 过采样与欠采样 · 数据泄露与预处理

# 等频分箱代码示例:

df['HumidityBinned'] = pd.qcut(df['Humidity'], q=3,
labels=['Low', 'Medium', 'High'])

方法 3:自定义分箱

自定义分箱允许用户根据专业领域知识或业务规则手动设定分箱边界,灵活性最高。

适用场景:当存在公认的分类标准或特定关注区间时尤为适用。

本例应用:对于降雨量(RainfallAmount),我们依据气象学中的通用分类标准设置区间:无雨、毛毛雨、降雨、大雨。相比随机划分,这种方式更具现实解释力。

[此处为图片3]

# 自定义分箱代码示例:

df['RainfallAmountBinned'] = pd.cut(df['RainfallAmount'], 
bins=[-np.inf, 2, 4, 12, np.inf],
labels=['No Rain', 'Drizzle', 'Rain', 'Heavy Rain'])

方法 4:对数分箱

对数分箱先对原始数据进行对数变换,再执行等宽分箱,从而形成指数增长型的区间宽度。

适用场景:适合跨越多个数量级或符合幂律分布的数据类型。

本例应用:风速(WindSpeed)对高尔夫球飞行轨迹的影响并非线性。例如,从0到5英里/小时的变化可能比20到25英里/小时带来更显著的影响。因此,采用对数分箱更能反映其非线性效应。

[此处为图片4]

# 对数分箱代码示例:

df['WindSpeedBinned'] = pd.cut(np.log1p(df['WindSpeed']), bins=3)

方法 5:基于标准差的分箱策略

该方法通过数据值与均值之间的标准差距离来划分区间,适用于数据近似正态分布的情形,或当分析目标是评估数值偏离集中趋势程度时尤为有效。

变化特点:

  • 可根据实际分析需求调整用于划分区间的标准差倍数。
  • 通常设置为奇数个区间,以便保留一个以均值为中心的中间区间。
  • 部分实现方式会采用非等宽区间设计,即靠近均值区域的区间较窄,而尾部区间更宽,以适应分布特征。

适用数据类型:

此方法特别适合处理符合正态分布的数据,有助于识别异常值并深入理解整体分布形态。但对于严重偏斜的分布则可能效果不佳。

在本例中的应用:

我们将这一技术应用于“温度”变量。选择它的原因是能够依据温度相对于平均值的偏离程度进行分类,这对分析天气模式或长期气候趋势具有重要意义。

towardsdatascience.com/discretization-explained-a-visual-guide-with-code-examples-for-beginners-f056af9102fa?source=collection_archive---------5-----------------------#2024-10-22
# 5. 基于标准差的温度分箱
mean_temp, std_dev = df['Temperature'].mean(), df['Temperature'].std()
bin_edges = [
    float('-inf'),
    mean_temp - 2.5 * std_dev,
    mean_temp - 1.5 * std_dev,
    mean_temp - 0.5 * std_dev,
    mean_temp + 0.5 * std_dev,
    mean_temp + 1.5 * std_dev,
    mean_temp + 2.5 * std_dev,
    float('inf')
]
df['TemperatureBinned'] = pd.cut(df['Temperature'], bins=bin_edges,
                                 labels=['Very Low', 'Low', 'Below Avg', 'Average',
                                         'Above Avg', 'High', 'Very High'])

方法 6:利用 K 均值聚类进行分箱

K 均值分箱借助 K 均值聚类算法自动识别数据中的自然簇群,并将每个簇作为一个独立的分箱单元。这种方法不依赖预设阈值,而是根据数据本身的相似性结构进行分组。

适用数据类型:

适用于探索潜在的隐含分组结构,尤其在数据呈现单峰或多峰分布时表现良好。它能灵活响应复杂的数据组织模式,发现传统固定阈值难以捕捉的规律。

在当前场景中的使用:

我们将其应用于“拥挤度”变量。之所以选用该方法,是因为它有望揭示出高尔夫球场人流密集程度中存在的自然层级,这些层级可能由多种未显式建模的因素共同作用形成,而简单分割无法充分反映这种复杂性。

?? 更多 [数据预处理](https://medium.com/@samybaladram/list/data-preprocessing-17a2c49b44e4) 解释:· 缺失值插补 · 分类编码 · 数据缩放 ? 离散化 · 过采样与欠采样 · 数据泄露与预处理
# 6. 使用K均值对拥挤度进行分箱
kmeans = KMeans(n_clusters=3, random_state=42).fit(df[['Crowdedness']])
df['CrowdednessBinned'] = pd.Categorical.from_codes(kmeans.labels_, categories=['Low', 'Medium', 'High'])

总结

本文共探讨了六种不同的数值离散化方法,应用于高尔夫相关数据集中的连续变量处理。经过处理后,最终的数据集呈现出如下结构:

[此处为图片3]
# 仅输出已完成分箱的列
binned_columns = [col for col in df.columns if col.endswith('Binned')]
print(df[binned_columns])

以下是对各分箱技术在天气数据中应用效果的简要回顾:

  • 等宽分箱(紫外线指数):将紫外线指数范围均匀划分为四个区间,并按强度等级标注为“低”至“非常高”,提供直观的风险解读。
  • 等频分箱(湿度):确保每个区间包含大致相等数量的观测值,从而平衡各类别的样本分布,适用于强调代表性而非区间跨度的场景。

在数据预处理中,分箱(Binning)是一种常见的离散化技术。合理选择分箱策略有助于更好地理解变量分布并提升模型表现力。以下是针对不同变量所采用的多种分箱方法及其背后的逻辑。

等频分箱(湿度)

将湿度数据划分为“低”、“中”、“高”三个类别,确保每个区间包含相同数量的数据点。这种策略保证了各类别在样本中的均衡分布,避免某一区间因数据集中而主导分析结果。

towardsdatascience.com/discretization-explained-a-visual-guide-with-code-examples-for-beginners-f056af9102fa?source=collection_archive---------5-----------------------#2024-10-22

对数变换分箱(风速)

风速通常对天气影响呈现非线性特征。为此,我们先对原始风速取自然对数加一(log(1+x)),再进行等宽划分,最终归类为“轻微”、“适中”或“强烈”。该方式更贴合风速变化的实际效应。

?? 更多 [数据预处理](https://medium.com/@samybaladram/list/data-preprocessing-17a2c49b44e4) 解释:· 缺失值插补 · 分类编码 · 数据缩放 ? 离散化 · 过采样与欠采样 · 数据泄露与预处理

基于领域知识的自定义分箱(降水量)

根据气象学常识,将降水量划分为“无雨”、“毛毛雨”、“降雨”和“暴雨”等具有实际意义的等级。这种方法不仅提升了可解释性,也便于与业务场景对接。

[此处为图片3]

基于标准差的温度分段(温度)

利用温度数据的整体分布特性,结合均值与标准差设定区间边界,将其划分为从“非常低”到“非常高”的多个层级。这种方式突出的是温度偏离常态的程度,适用于异常气候识别。

[此处为图片4]

K均值聚类分箱(拥挤度)

通过对拥挤度数据应用K-means聚类算法,识别出内在的自然分组结构。这种方法无需依赖固定阈值,能够揭示潜在的行为模式或人群聚集趋势。

[此处为图片5]

分箱的风险与注意事项

尽管分箱操作看似简单直接,但其背后隐藏着若干风险,需谨慎对待:

  • 信息损失:分箱过程会抹平箱内细节,虽然有助于宏观趋势发现,但也可能掩盖重要的局部变化或细微关系。
  • 边界设定的主观性:分箱边界的选取有时缺乏严格依据,微小调整可能导致截然不同的结论,存在一定的任意性。
  • 对模型性能的影响:某些机器学习模型(如决策树类算法)本身具备自动分割能力,人为分箱反而可能削弱其优势,导致性能下降。
  • 产生虚假的安全感:分箱后数据显得规整有序,容易让人误以为复杂性已被解决,实则只是被隐藏。
  • 解释难度增加:“高”或“低”等标签在不同上下文中含义可能差异巨大,影响结果的普适性和沟通效率。

实践建议

面对上述挑战,以下几点建议可供参考:

  1. 始终保留一份未经过分箱处理的原始数据副本,以备后续验证或重新分析之用。
  2. 尝试多种分箱方法(如等宽、等频、聚类、自定义等),并通过对比结果来判断哪种策略更适合当前任务。
  3. 优先考察所在领域是否存在公认的分类标准(例如气象行业对降水的分级),尽可能遵循已有规范以增强结果的可信度。

代码实现示例:离散化流程汇总

import pandas as pd
import numpy as np
from sklearn.cluster import KMeans

# 创建数据集
data = {
    'UVIndex': [2, 10, 1, 7, 3, 9, 5, 11, 1, 8, 3, 9, 11, 5, 7],
    'Humidity': [15, 95, 10, 98, 18, 90, 25, 80, 95, 40, 20, 30, 85, 92, 12],
    'WindSpeed': [2, 90, 1, 30, 3, 10, 40, 5, 60, 15, 20, 45, 25, 35, 50],
    'RainfallAmount': [5,2,7,3,18,3,0,1,25,0,9,0,18,7,0],
    'Temperature': [68, 60, 63, 55, 50, 56, 57, 65, 66, 68, 71, 72, 79, 83, 81],
    'Crowdedness': [0.15, 0.98, 0.1, 0.85, 0.2, 0.9, 0.92, 0.25, 0.12, 0.99, 0.2, 0.8, 0.05, 0.3, 0.95]
}

# 转换为DataFrame
df = pd.DataFrame(data)

# 1. 紫外线指数:等宽分箱(4个区间)
df['UVIndexBinned'] = pd.cut(df['UVIndex'], bins=4,
                             labels=['Low', 'Moderate', 'High', 'Very High'])

# 2. 湿度:等频分箱(3个类别)
df['HumidityBinned'] = pd.qcut(df['Humidity'], q=3,
                                labels=['Low', 'Medium', 'High'])

# 3. 降水量:自定义区间分箱
df['RainfallAmountBinned'] = pd.cut(df['RainfallAmount'], 
                                    bins=[-np.inf, 2, 4, 12, np.inf],
                                    labels=['No Rain', 'Drizzle', 'Rain', 'Heavy Rain'])

# 4. 风速:对数变换后等宽分箱
df['WindSpeedBinned'] = pd.cut(np.log1p(df['WindSpeed']), bins=3,
                               labels=['Light', 'Moderate', 'Strong'])

基于标准差的温度分箱与KMeans拥挤度分箱

在数据预处理阶段,特征工程中的分箱(Binning)技术常用于将连续变量转换为分类变量,以提升模型解释性或适应特定算法需求。本文介绍两种不同的分箱方法:基于标准差的温度分箱和基于KMeans聚类的拥挤度分箱。

towardsdatascience.com/discretization-explained-a-visual-guide-with-code-examples-for-beginners-f056af9102fa?source=collection_archive---------5-----------------------#2024-10-22

1. 基于标准差的温度分箱

该方法利用温度数据的均值与标准差构建动态分箱边界,确保分组具有统计意义。具体步骤如下:

  • 计算温度列的均值(mean_temp)和标准差(std_dev);
  • 设定多个以均值为中心、按标准差倍数扩展的分界点;
  • 使用 pd.cut() 函数将连续温度值划分为七个类别:'Very Low'、'Low'、'Below Avg'、'Average'、'Above Avg'、'High'、'Very High';
  • 首尾分别用负无穷和正无穷保证所有数据均可被归类。
mean_temp, std_dev = df['Temperature'].mean(), df['Temperature'].std()
bin_edges = [
    float('-inf'),
    mean_temp - 2.5 * std_dev,
    mean_temp - 1.5 * std_dev,
    mean_temp - 0.5 * std_dev,
    mean_temp + 0.5 * std_dev,
    mean_temp + 1.5 * std_dev,
    mean_temp + 2.5 * std_dev,
    float('inf')
]
df['TemperatureBinned'] = pd.cut(df['Temperature'], bins=bin_edges,
                                 labels=['Very Low', 'Low', 'Below Avg', 'Average',
                                         'Above Avg', 'High', 'Very High'])
    
?? 更多 [数据预处理](https://medium.com/@samybaladram/list/data-preprocessing-17a2c49b44e4) 解释:· 缺失值插补 · 分类编码 · 数据缩放 ? 离散化 · 过采样与欠采样 · 数据泄露与预处理

2. 基于KMeans的拥挤度分箱

对于“Crowdedness”这一特征,采用无监督学习中的KMeans聚类进行分箱。这种方法能自动识别数据中的自然聚集模式,无需依赖固定阈值。

  • 选取 Crowdedness 列作为输入特征;
  • 设置聚类数量为3,对应低、中、高三类;
  • 通过 KMeans(n_clusters=3, random_state=42) 拟合并生成标签;
  • 使用 pd.Categorical.from_codes() 将聚类结果映射为有意义的类别名称。
kmeans = KMeans(n_clusters=3, random_state=42).fit(df[['Crowdedness']])
df['CrowdednessBinned'] = pd.Categorical.from_codes(kmeans.labels_, 
                                                    categories=['Low', 'Medium', 'High'])
    
[此处为图片3]

输出处理后的分箱列

仅展示新生成的分箱字段,便于检查结果:

binned_columns = [col for col in df.columns if col.endswith('Binned')]
print(df[binned_columns])
    
[此处为图片4]

技术环境说明

本示例基于 Python 3.7 和 scikit-learn 1.5 版本实现。尽管所讨论的方法具有通用性,但不同版本之间可能存在API差异,建议根据实际运行环境调整代码。

插图版权信息

除非特别注明,所有图像均由作者原创制作,设计元素来源于 Canva Pro 的授权资源。

Samy Baladram

回归算法

5 篇故事

towardsdatascience.com/discretization-explained-a-visual-guide-with-code-examples-for-beginners-f056af9102fa?source=collection_archive---------5-----------------------#2024-10-22

?? 更多 [数据预处理](https://medium.com/@samybaladram/list/data-preprocessing-17a2c49b44e4) 解释:· 缺失值插补 · 分类编码 · 数据缩放 ? 离散化 · 过采样与欠采样 · 数据泄露与预处理

[此处为图片3]

[此处为图片4]

[此处为图片5]

[此处为图片6]

二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:代码示例 离散化 可视化 初学者 scikit-learn

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
加好友,备注cda
拉您进交流群
GMT+8, 2025-12-6 04:51