Python机器学习数据预处理详解:标准化、归一化、正则化、离散化与白化

慢慢来
慢慢来
发布时间:2026-10-12 | 4人浏览过
原创

本文深入解析Python机器学习中的数据预处理技术,涵盖标准化、归一化、正则化、离散化和白化五大核心方法。通过Scikit-learn库的实战代码示例,详细阐述各方法的原理、适用场景及参数设置,帮助开发者优化模型输入特征,提升算法精度与训练效率。

机器学习的核心在于从数据集中挖掘内在特征,但这些内在规律常被样本的规格、分布范围等外在表象所遮蔽。数据预处理旨在通过一系列操作最大限度地凸显数据的内在特征,主要手段包括标准化、归一化、正则化、离散化和白化。

1 标准化

假设样本集分布在二维平面上,横坐标 x 位于 [0,100] 区间,纵坐标 y 位于 [0,1] 区间。由于 x 和 y 的动态范围差异巨大,这会对 k-近邻或 k-means 聚类等机器学习模型产生显著影响。标准化处理旨在消除动态范围过大的特征列对计算结果的干扰,从而提升模型精度其实质是将每个特征列减去均值以实现中心化,再除以标准差进行缩放。 Scikit-learn的预处理子模块preprocessing提供了快速标准化函数scale(),可直接返回标准化后的数据集,代码如下。

>>> import numpy as np
>>> from sklearn import preprocessing as pp
>>> d = np.array([[ 1., -5., 8.], [ 2., -3., 0.], [ 0., -1., 1.]])
>>> d_scaled = pp.scale(d) # 对数据集d做标准化
>>> d_scaled
array([[ 0. , -1.22474487, 1.40487872],
 [ 1.22474487, 0. , -0.84292723],
 [-1.22474487, 1.22474487, -0.56195149]])
>>> d_scaled.mean(axis=0) # 标准化以后的数据集,各特征列的均值为0
array([0., 0., 0.])
>>> d_scaled.std(axis=0) # 标准化以后的数据集,各特征列的标准差为1
array([1., 1., 1.])

预处理子模块 preprocessing 还提供了实用类 StandardScaler,该类保存了训练集各特征列的平均值和标准差,便于在测试集上应用相同的变换。此外,StandardScaler 可通过 with_mean 和 with_std 参数指定是否进行中心化和按标准差缩放,代码如下。

>>> import numpy as np
>>> from sklearn import preprocessing as pp
>>> X_train = np.array([[ 1., -5., 8.], [ 2., -3., 0.], [ 0., -1., 1.]])
>>> scaler = pp.StandardScaler().fit(X_train)
>>> scaler
StandardScaler(copy=True, with_mean=True, with_std=True)
>>> scaler.mean_ # 训练集各特征列的均值
array([ 1., -3., 3.])
>>> scaler.scale_ # 训练集各特征列的标准差
array([0.81649658, 1.63299316, 3.55902608])
>>> scaler.transform(X_train) # 标准化训练集
array([[ 0. , -1.22474487, 1.40487872],
 [ 1.22474487, 0. , -0.84292723],
 [-1.22474487, 1.22474487, -0.56195149]])
>>> X_test = [[-1., 1., 0.]] # 使用训练集的缩放标准来标准化测试集
>>> scaler.transform(X_test)
array([[-2.44948974, 2.44948974, -0.84292723]])

2 归一化

标准化利用特征列的均值进行中心化,用标准差进行缩放。若将数据集各特征列的最小值作为中心点进行中心化,再按极差(最大值减最小值)进行缩放,即数据减去特征列的最小值并收敛至 [0,1] 区间,此过程称为数据归一化。 Scikit-learn的预处理子模块 preprocessing 提供 MinMaxScaler 类来实现归一化。MinMaxScaler 类有一个重要参数 feature_range,用于设置数据压缩的范围,默认为 [0,1]。

>>> import numpy as np
>>> from sklearn import preprocessing as pp
>>> X_train = np.array([[ 1., -5., 8.], [ 2., -3., 0.], [ 0., -1., 1.]])
>>> scaler = pp.MinMaxScaler().fit(X_train) # 默认数据压缩范围为[0,1]
>>> scaler
MinMaxScaler(copy=True, feature_range=(0, 1))
>>> scaler.transform(X_train)
array([[0.5 , 0. , 1. ],
 [1. , 0.5 , 0. ],
 [0. , 1. , 0.125]])
>>> scaler = pp.MinMaxScaler(feature_range=(-2, 2)) # 设置数据压缩范围为[-2,2]
>>> scaler = scaler.fit(X_train)
>>> scaler.transform(X_train)
array([[ 0. , -2. , 2. ],
 [ 2. , 0. , -2. ],
 [-2. , 2. , -1.5]])

由于归一化对异常值极为敏感,大多数机器学习算法倾向于选择标准化进行特征缩放。在主成分分析(Principal Components Analysis,PCA)、聚类、逻辑回归、支持向量机、神经网络等算法中,标准化通常是最佳选择。归一化则广泛应用于不涉及距离度量、梯度、协方差计算,且需将数据压缩至特定区间的场景,例如在数字图像处理中量化像素强度时,常使用归一化将数据压缩在 [0,1] 内。

3 正则化

归一化针对数据集的特征列进行操作,而正则化则是将每个数据样本的范数单位化,属于对数据集的行操作。若计划使用点积等运算来量化样本间的相似度,正则化将极具价值。

Scikit-learn的预处理子模块preprocessing提供了快速正则化函数normalize(),可直接返回正则化后的数据集。normalize()函数使用参数norm指定I1范式或I2范式,默认采用I2范式。I1 范式指单个样本各元素的绝对值之和为 1;I2 范式指单个样本各元素的平方和的算术根为 1,即样本向量的模(长度)。

>>> import numpy as np
>>> from sklearn import preprocessing as pp
>>> X_train = np.array([[ 1., -5., 8.], [ 2., -3., 0.], [ 0., -1., 1.]])
>>> pp.normalize(X_train) # 使用I2范式正则化,每行的范数为1
array([[ 0.10540926, -0.52704628, 0.84327404],
 [ 0.5547002 , -0.83205029, 0. ],
 [ 0. , -0.70710678, 0.70710678]])
>>> pp.normalize(X_train, norm='I1') # 使用I1范式正则化,每行的范数为1
array([[ 0.07142857, -0.35714286, 0.57142857],
 [ 0.4 , -0.6 , 0. ],
 [ 0. , -0.5 , 0.5 ]])

4 离散化

离散化(Discretization)是将连续特征划分为离散特征值,典型应用包括灰度图像的二值化。若使用等宽区间对连续特征进行离散化,则称为 K-bins 离散化。Scikit-learn的预处理子模块preprocessing提供了Binarizer类和KbinsDiscretizer类来进行离散化,前者用于二值化,后者用于 K-bins 离散化。

>>> import numpy as np
>>> from sklearn import preprocessing as pp
>>> X = np.array([[-2,5,11],[7,-1,9],[4,3,7]])
>>> bina = pp.Binarizer(threshold=5) # 指定二值化阈值为5
>>> bina.transform(X)
array([[0, 0, 1],
 [1, 0, 1],
 [0, 0, 1]])
>>> est = pp.KBinsDiscretizer(n_bins=[2, 2, 3], encode='ordinal').fit(X)
>>> est.transform(X) # 三个特征列离散化为2段、2段、3段
array([[0., 1., 2.],
 [1., 0., 1.],
 [1., 1., 0.]])

5 白化

白化(Whitening)一词源于翻译,难以望文生义,需从白化后的效果来理解。数据白化有两个目的:一是去除或降低特征列之间的相关性;二是使每个特征列的方差为1。显然,白化的第一个目标对应主成分分析(PCA),通过PCA降维以消除方差占比较小的特征维度;白化的第二个目标则对应标准化。

白化分为PCA白化和ZCA白化两种。PCA 白化将原数据各个特征维变换到主成分轴上,消除特征间的相关性,并使各个主成分的方差为1。ZCA白化则是将PCA 白化的结果反变换回原数据的各个特征维轴上,因ZCA白化过程中通常不进行降维。

Scikit-learn未提供专用的白化方法,但借助成分分析子模块decomposition提供的PCA 类可轻松实现PCA白化。PCA类的参数whiten用于设置是否移除特征间的线性关联,默认值为False。

假设一位姑娘手头有一堆相亲资料,每位帅哥的信息由年龄、身高、体重、年薪、房产数量、汽车数量等多个特征项组成。通过白化操作,能够生成一个特征维度较小、且可直接比较样本间差距的数据集。

>>> import numpy as np
>>> from sklearn import preprocessing as pp
>>> from sklearn.decomposition import PCA
>>> ds = np.array([
    [25, 1.85, 70, 50, 2, 1], 
    [22, 1.78, 72, 22, 0, 1], 
    [26, 1.80, 85, 25, 1, 0],
    [28, 1.70, 82, 100, 5, 2]
]) # 4个样本,6个特征列
>>> m = PCA(whiten=True) # 实例化主成分分析类,指定白化参数
>>> m.fit(ds) # 主成分分析
PCA(whiten=True)
>>> d = m.transform(ds) # 返回主成分分析结果
>>> d # 特征列从6个降至4个
array([[ 0.01001541, -0.99099492, -1.12597902, -0.03748764],
       [-0.76359767, -0.5681715 ,  1.15935316,  0.67477757],
       [-0.65589352,  1.26928222, -0.45686577, -1.8639689 ],
       [ 1.40947578,  0.28988421,  0.42349164,  1.2724972 ]])
>>> d.std(axis=0) # 显示各特征列方差
array([0.8660254 , 0.8660254 , 0.8660254 , 1.17790433])
>>> d = pp.scale(d) # 标准化
>>> d.std(axis=0) # 标准化后的各特征列方差均为1
array([1., 1., 1., 1.])

GitHub上有人提供了ZCA白化的代码,如需使用,请访问(https://github.com/mwv/zca)。

以上就是聊聊python 机器学习的标准化、归一化、正则化、离散化和白化的详细内容,更多关于python 机器学习的资料请关注本站其它相关文章!

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表