【精选优质专栏推荐】


每个专栏均配有案例与图文讲解,循序渐进,适合新手与进阶学习者,欢迎订阅。

在这里插入图片描述

本文将介绍:

1.为什么标准缩放方法有时不够用,以及何时应使用高级技术。
2.四种高级策略背后的概念:分位数变换、幂变换、稳健缩放和单位向量缩放。
3.如何使用 Python 的 scikit-learn 库逐步实现这些技术。

前言

特征缩放是数据预处理中最常见的技术之一,应用范围包括统计建模、分析、机器学习、数据可视化和数据讲述。在大多数项目和使用场景中,我们通常依赖几种最流行的方法——如归一化和标准化——但在某些情况下,这些基本技术并不足够。例如,当数据偏斜、充满异常值,或不符合高斯分布时。在这些情况下,可能需要使用更高级的缩放技术,将数据转换为更符合下游算法或分析方法假设的形式。这些高级技术的例子包括分位数变换、幂变换、稳健缩放和单位向量缩放。

本文旨在提供高级特征缩放技术的实用概览,描述每种技术的工作原理,并展示其在 Python 中的实现。

四种高级特征缩放策略

我们将通过基于 Python 的示例介绍并展示以下四种特征缩放技术的用法:

  • 分位数变换
  • 幂变换
  • 稳健缩放
  • 单位向量缩放

1. 分位数变换

分位数变换将输入数据(按特征)的分位数映射到目标分布的分位数,通常是均匀分布或正态分布。与其对数据的真实分布做出严格假设,这种方法更关注与观测数据点相关的经验分布。其主要优势之一是对异常值的鲁棒性,特别是在将数据映射到均匀分布时,它能拉开常见值的间距并压缩极端值。

以下示例展示了如何对一个小数据集应用分位数变换,并使用正态分布作为输出分布:

from sklearn.preprocessing import QuantileTransformer
import numpy as np
 
X = np.array([[10], [200], [30], [40], [5000]])
 
qt = QuantileTransformer(output_distribution='normal', random_state=0)
X_trans = qt.fit_transform(X)
 
print("Original Data:\n", X.ravel())
print("Quantile Transformed (Normal):\n", X_trans.ravel())

其机制与大多数 scikit-learn 类似。我们使用 QuantileTransformer 类实现转换,在初始化缩放器时指定所需的输出分布,然后将 fit_transform 方法应用于数据。

输出:

Original Data:
 [  10  200   30   40 5000]
Quantile Transformed (Normal):
 [-5.19933758  0.67448975 -0.67448975  0.          5.19933758]

如果我们希望将数据按分位数映射到均匀分布,只需将 output_distribution='uniform'

2. 幂变换

众所周知,许多机器学习算法、分析技术和假设检验方法都假设数据服从正态分布。幂变换有助于让非正态数据更接近正态分布。具体应用哪种变换取决于参数 𝜆,其值由最大似然估计等优化方法确定,以找到能使原始数据值最接近正态分布的 𝜆。基本方法称为 Box-Cox 幂变换,只适用于处理正数值。另一种替代方法称为 Yeo-Johnson 幂变换,当数据中存在正值、负值以及零时,更适合使用。

from sklearn.preprocessing import PowerTransformer
import numpy as np
 
X = np.array([[1.0], [2.0], [3.0], [4.0], [5.0]])
 
pt = PowerTransformer(method='box-cox', standardize=True)
X_trans = pt.fit_transform(X)
 
print("Original Data:\n", X.ravel())
print("Power Transformed (Box-Cox):\n", X_trans.ravel())

输出:

Original Data:
 [1. 2. 3. 4. 5.]
Power Transformed (Box-Cox):
 [-1.50121999 -0.64662521  0.07922595  0.73236192  1.33625733]

如果数据集中包含零或负值,应使用 Yeo-Johnson 变换,只需设置 method='yeo-johnson'

3. 稳健缩放

当数据包含异常值或不服从正态分布时,稳健缩放是标准化的一个有趣替代方案。标准化是将数据中心化为均值并按标准差缩放,而稳健缩放使用对异常值鲁棒的统计量。具体而言,它通过减去中位数对数据进行中心化,再通过四分位距 (IQR) 进行缩放,公式如下:

X s c a l e d = X − Median ( X ) IQR ( X ) X_{scaled} = \frac{X - \text{Median}(X)}{\text{IQR}(X)} Xscaled=IQR(X)XMedian(X)

Python 实现非常直接:

from sklearn.preprocessing import RobustScaler
import numpy as np
 
X = np.array([[10], [20], [30], [40], [1000]])
 
scaler = RobustScaler()
X_trans = scaler.fit_transform(X)
 
print("Original Data:\n", X.ravel())
print("Robust Scaled:\n", X_trans.ravel())

输出:

Original Data:
 [  10   20   30   40 1000]
Robust Scaled:
 [-1.  -0.5  0.   0.5 48.5]

稳健缩放的优势在于能更可靠地表示数据分布,尤其是在存在极端异常值(如示例中的 1000)时。

4. 单位向量缩放

单位向量缩放(也称为归一化)将每个样本(即数据矩阵中的每一行)缩放为单位范数(长度为 1)。它通过将样本中的每个元素除以该样本的范数来实现。有两种常见的范数:L1 范数(元素绝对值之和)和 L2 范数(平方和的平方根)。选择哪一种取决于你是更关注数据稀疏性(L1)还是几何距离的保持(L2)。

以下示例将单位向量缩放应用于两个样本,并基于 L2 范数将每一行转换为单位向量(若要使用 L1 范数,将参数改为 'l1'):

from sklearn.preprocessing import Normalizer
import numpy as np
 
X = np.array([[1, 2, 3], [4, 5, 6]])
 
normalizer = Normalizer(norm='l2')
X_trans = normalizer.transform(X)
 
print("Original Data:\n", X)
print("L2 Normalized:\n", X_trans)

输出:

Original Data:
 [[1 2 3]
 [4 5 6]]
L2 Normalized:
 [[0.26726124 0.53452248 0.80178373]
 [0.45584231 0.56980288 0.68376346]]

总结

本文介绍了四种高级特征缩放技术,它们在涉及极端异常值、非正态分布数据等情况下非常有用。通过代码示例,我们展示了如何在 Python 中使用这些缩放方法。

最后,总结表如下,突出每种特征缩放技术所针对的数据问题及其可能的实际应用场景:

技术 针对的数据问题 示例应用场景
分位数变换 数据偏斜、异常值 信用评分、风险建模
幂变换 数据不服从正态分布 假设检验、线性模型拟合
稳健缩放 存在极端异常值 金融交易数据、传感器异常检测
单位向量缩放 需要统一长度或比较方向的样本 文本向量化、余弦相似度计算

更多推荐