Python机器学习数据预处理详解:标准化、归一化、正则化、离散化与白化
本文深入解析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 机器学习的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













