KBinsDiscretizer 是scikit-learn中一个强大的预处理工具,用于将连续数值特征 离散化( 分箱)。
将其转 换为有序的、类别型的特征,本质上是将连续空间划分为区间。
这在特征工程中很常见,之前也介绍了变量转woe分箱,感兴趣的可以看下:风控建模中的IV和WOE、【干货】风控建模中把原始变量转成WOE实现。
接下来详细了解一下KBinsDiscretizer。
本文目录
- 为什么要对连续特征进行分箱?
- KBinsDiscretizer参数详解
- 应用KBinsDiscretizer分箱
3.1 应用等频分箱分割变量
3.2 应用等宽分箱分割变量
3.3 应用K-means分箱分割变量
一、为什么要对连续特征进行分箱?
在特征工程中,连续特征分箱很常见,主要原因有:
1.处理非线性关系: 线性模型(如线性回归、逻辑回归)只能捕捉线性关系。离散化可以将非线性关系转化为线性模型更容易处理的阶梯状关系。减少异常值影响:异常值会被归入边界箱中,减少它们对模型训练的过度影响。
2.满足算法要求: 某些算法(如朴素贝叶斯)天生处理类别型特征,或者在某些场景下离散特征更符合业务逻辑。
3.特征交互: 离散化后的特征更容易进行特征交叉(如笛卡尔积)。
4.提升模型鲁棒性: 对输入数据的微小变化不那么敏感。
二、KBinsDiscretizer参数详解
KBinsDiscretizer的核心参数有3个,具体如下:
KBinsDiscretizer(n\_bins=5, *, encode='onehot', strategy='quantile')
1.n\_bins
(int or array-like of shape (n_features,), default=5):
-
最重要的参数,决定每个特征要分成多少个箱。
-
如果是
int
,则所有特征都使用这个数量的箱。 -
如果是
array-like
,则每个元素指定对应特征(按输入特征顺序)的箱数。例如n\_bins=[3, 10, 5]
表示第一个特征分3箱,第二个分10箱,第三个分5箱。2.encode
({'onehot', 'onehot-dense', 'ordinal'}, default='onehot'): -
指定离散化后结果的编码方式:
-
'onehot'
: 使用scipy稀疏矩阵返回 One-Hot编码 。每个原始特征离散化后生成n\_bins
个二进制特征,只有对应箱的特征为1,其余为0 。(默认) -
'onehot-dense'
: 使用密集numpy数组返回 One-Hot编码 。与'onehot'
类似,但结果是密集矩阵。 -
'ordinal'
: 返回 序数编码 。每个原始特征被替换为一个整数数组(0
到n\_bins-1
),表示样本属于哪个箱。箱是有序的(例如,0表示最低区间,n\_bins-1
表示最高区间)。3.strategy
({'uniform', 'quantile', 'kmeans'}, default='quantile'): -
定义如何计算箱的边界(分箱策略):
-
'uniform'
(等宽分箱): 所有箱的 宽度 (在特征值范围内)相等。例如,特征范围是[0, 100],n\_bins=4
,则箱边界为[0, 25), [25, 50), [50, 75), [75, 100]。 对异常值敏感 ,可能导致某些箱样本极少或极多。 -
'quantile'
(等频分箱): 所有箱包含 大致相同数量 的样本。例如,n\_bins=4
会尝试使用数据的4个分位数(25%, 50%, 75%)作为边界点。 对异常值鲁棒 ,能更好地反映数据分布。但如果数据在某个区域非常密集,边界点可能非常接近;如果数据稀疏,边界点可能相距很远。 -
'kmeans'
(K均值分箱): 使用 K-means聚类 算法确定箱边界。算法将特征值视为一维数据,尝试找到n\_bins
个聚类中心,然后将样本分配到最近的聚类中心。箱边界位于聚类中心的中点。旨在使箱内方差最小化,箱间方差最大化。结果依赖于K-means的初始化(random\_state
控制)。
三、应用KBinsDiscretizer分箱****
接下来详细介绍应用KBinsDiscretizer分箱实战。
1 应用等频分箱分割变量
首先导入KBinsDiscretizer库,应用等频分箱把每个特征分成3箱,代码如下:
import numpy as np
from sklearn.preprocessing import KBinsDiscretizer
# 示例数据
X = np.array([[ -3., 5., 15 ],
[ -1., 6., 14 ],
[ 1., 7., 13 ],
[ 4., 8., 12 ],
[ 7., 9., 11 ]])
# 1. 等频分箱 (3箱),序数编码
est_quantile_ord = KBinsDiscretizer(n_bins=3, encode='ordinal', strategy='quantile')
Xt_quantile_ord = est_quantile_ord.fit_transform(X)
print("Bin edges (Quantile):", est_quantile_ord.bin_edges_)
得到结果:
Bin edges (Quantile): [array([-3. , -0.33333333, 3. , 7. ])
array([5. , 6.33333333, 7.66666667, 9. ])
array([11. , 12.33333333, 13.66666667, 15. ])]
为了大家更清晰地理解切割结果,以特征[-3, -1, 1, 4, 7]为例进行说明,其余特征类似。
应用等频分箱分成3箱,得到的边界点为[-3, -0.33333333, 3, 7],说明-3和-1分成了一箱,1分成了一箱,4和7分成了一箱。
********2 ******应用等宽分箱分割变量**************
接着应用等宽分箱分割变量,代码如下:
# 2. 等宽分箱 (2箱),One-Hot编码 (密集)
est_uniform_ohd = KBinsDiscretizer(n_bins=2, encode='onehot-dense', strategy='uniform')
Xt_uniform_ohd = est_uniform_ohd.fit_transform(X)
print("Bin edges (Uniform):", est_uniform_ohd.bin_edges_)
得到结果:
`Bin edges (Uniform): [array([-3., 2., 7.]) array([5., 7., 9.]) array([11., 13., 15.])]`
同样以特征[-3, -1, 1, 4, 7]为例进行说明,其余特征类似。
应用等宽分箱分成2箱,得到的边界点为[-3, 2, 7],说明-3、-1和1分成了一箱,4和7分成了一箱。
3 应用K-means分箱分割变量 最后应用K-means分箱分割变量,代码如下:
# 3. K-means分箱 (2箱),One-Hot编码 (稀疏)
est_kmeans_oh = KBinsDiscretizer(n_bins=2, encode='onehot', strategy='kmeans')
Xt_kmeans_oh = est_kmeans_oh.fit_transform(X) # 返回稀疏矩阵
print("\nK-means (OneHot - sparse):")
print("Bin edges (K-means):", est_kmeans_oh.bin_edges_)
得到结果:
K-means (OneHot - sparse):
Bin edges (K-means): [array([-3. , 2.25, 7. ]) array([5. , 7.25, 9. ])
array([11. , 13.25, 15. ])]
同样以特征1[-3, -1, 1, 4, 7]为例进行说明,其余特征类似。
应用K-means分箱分成2箱,得到的边界点为[-3, 2.25, 7],说明-3、-1和1 分成了一箱,4和7分成了一箱。
至此,应用KBinsDiscretizer分箱已讲解完毕,对风控建模感兴趣的小伙伴欢迎加群讨论。
【部分群限时免费进** 】** 分群讨论学习Python、玩转Python、风控建模【29.9元进】、人工智能、数据分析相关问题,还提供招聘内推信息、优秀文章、学习视频、公众号文章答疑,也可交流工作中遇到的难题。如需添加微信号19967879837,加时备注想进的群,比如风控建模。
往期回顾:
一文囊括风控模型搭建(原理+Python实现),持续更新。。。
不同工作年限风控建模岗薪资水平如何?招聘最看重面试者什么能力?
100天精通风控建模(原理+Python实现)——第32天:集成学习是什么?在风控建模中有哪些应用?
限时免费加群
19967879837
添加 微信号、手机号