0%

机器学习之数据预处理:Binning 分箱

数据预处理作为机器学习中的关键一环,这里介绍其中的Binning 分箱

abstract.png

基本原理

Binning分箱指的是将连续的数值型特征转换成离散的类别型特征。一方面,极端的异常数值被转换为类别特征后,降低了异常数值大小的影响,提升模型鲁棒性;另一方面,相比于连续型特征,离散的类别型特征取值范围有限,降低了过拟合风险。例如,我们可以将原始的年龄数值特征转换为童年、青年、中年、老年这种类别特征

事实上,分箱的最大神奇之处在于:可以为模型引入非线性能力,来提升模型表现。例如,使用线性回归模型通过人群年龄来预测年收入。我们知道,一开始,年收入水平会随着年龄的增加而增加;但当过了某个年龄阶段后,年收入水平即会随着年龄的增加而下降。即呈现所谓的倒U形

如果使用原始的年龄数值作为特征输入,则年龄特征对应的就只有1个权重参数。显然这样的一条直线是无论如何也无法去拟合呈倒U形分布的样本点

但当我们通过分箱将其转换为类别特征(少年、中年、老年)并使用独热编码,就会有3个特征输入(少年、中年、老年),相应的就有3个权重参数。此时,即使在线性模型下,模型也可以为每个类别学习到一个独立的权重。具体地:w1、w3参数会获得一个较低的权重,而w2参数会获得一个较高的权重。这样一个线性的模型也可以很好的去贴合现实世界中的非线性现象

常见的分箱方法有:

  • 等频分箱:划分为若干个箱子,使得每个分箱包含的样本数基本一致
  • 等宽分箱:划分为若干个箱子,使得每个分箱区间的宽度基本一致

可使用Sklearn提供的KBinsDiscretizer实现等频/等宽分箱

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import numpy as np
from sklearn.preprocessing import KBinsDiscretizer


# 一个二维数组(行为样本、列为特征)
age = np.array([7, 5, 3, 1, 99, 98]).reshape(-1,1)

# 创建KBinsDiscretizer实例:分箱数量为3、等频分箱(使得每个分箱包含的样本数基本一致)、输出形式为分箱编号
quantile_discretizer = KBinsDiscretizer(n_bins=3, strategy='quantile', encode='ordinal')
# 分箱
quantile_discretizer.fit(age)
age_quantile_binning = quantile_discretizer.transform(age)
# 查看各分箱的边界
edge = quantile_discretizer.bin_edges_[0]
for i in range(len(edge)-1):
print(f"#{i}号 分箱的取值区间: [{edge[i]:.2f}, {edge[i+1]:.2f})" )

print(age_quantile_binning)


print("-"*80)


# 创建KBinsDiscretizer实例:分箱数量为3、等宽分箱(使得每个分箱取值区间宽度基本一致)、输出形式为独热编码
uniform_discretizer = KBinsDiscretizer(n_bins=3, strategy='uniform', encode='onehot-dense')
# 分箱
uniform_discretizer.fit(age)
age_uniform_binning = uniform_discretizer.transform(age)

# 查看各分箱的边界
edge = uniform_discretizer.bin_edges_[0]
for i in range(len(edge)-1):
print(f"#{i}号 分箱的取值区间: [{edge[i]:.2f}, {edge[i+1]:.2f})" )
print(age_uniform_binning)

输出结果如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#0号 分箱的取值区间: [1.00, 4.33)
#1号 分箱的取值区间: [4.33, 37.33)
#2号 分箱的取值区间: [37.33, 99.00)
[[1.]
[1.]
[0.]
[0.]
[2.]
[2.]]
--------------------------------------------------------------------------------
#0号 分箱的取值区间: [1.00, 33.67)
#1号 分箱的取值区间: [33.67, 66.33)
#2号 分箱的取值区间: [66.33, 99.00)
[[1. 0. 0.]
[1. 0. 0.]
[1. 0. 0.]
[1. 0. 0.]
[0. 0. 1.]
[0. 0. 1.]]

参考文献

  • 机器学习 周志华著
  • 机器学习公式详解 谢文睿、秦州著
  • 图解机器学习和深度学习入门 山口达辉、松田洋之著
请我喝杯咖啡捏~
  • 本文作者: Aaron Zhu
  • 本文链接: https://xyzghio.xyz/Binning/
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-ND 许可协议。转载请注明出处!

欢迎关注我的微信公众号:青灯抽丝