import numpy as np
import pandas as pd
# To import the datasetfrom sklearn.datasets import load_iris
# To be used for splitting the dataset into training and test setsfrom sklearn.model_selection import train_test_split
# To be used for min-max normalizationfrom sklearn.preprocessing import MinMaxScaler
# To be used for Z-normalization (standardization)from sklearn.preprocessing import StandardScaler
# Load the iris dataset from Scikit-learn package
iris = load_iris()# This prints a summary of the characteristics, statistics of the datasetprint(iris.DESCR)# Divide the data into features (X) and target (Y)# Data is converted to a panda’s dataframe
X = pd.DataFrame(iris.data)# Separate the target attribute from rest of the data columns
Y = iris.target
# Take a look at the dataframe
X.head()# This prints the shape of the dataframe (150 rows and 4 columns)
X.shape()技术支持
# Good practice to keep original dataframes untouched for reusability
X_train_n = X_train.copy()
X_test_n = X_test.copy()# Fit min-max scaler on training data
norm = MinMaxScaler().fit(X_train_n)# Transform the training data
X_train_norm = norm.transform(X_train_n)# Use the same scaler to transform the testing set
X_test_norm = norm.transform(X_test_n)技术支持
X_train_norm_df = pd.DataFrame(X_train_norm)# Assigning original feature names for ease of read
X_train_norm_df.columns = iris.feature_names
X_train_norm_df.describe()技术支持
X_train_s = X_train.copy()
X_test_s = X_test.copy()# Fit the standardization scaler onto the training data
stan = StandardScaler().fit(X_train_s)# Transform the training data
X_train_stan = stan.transform(X_train_s)# Use the same scaler to transform the testing set
X_test_stan = stan.transform(X_test_s)# Convert the transformed data into pandas dataframe
X_train_stan_df = pd.DataFrame(X_train_stan)# Assigning original feature names for ease of read
X_train_stan_df.columns = iris.feature_names
# Check out the statistical description
X_train_stan_df.describe()技术支持
标准化将得到如下结果:
Z 归一化的目标是将特征值变换为均值为 0、标准差为 1。正如从数据框的描述所见,四个特征的均值都接近于零,标准差为 1。
在机器学习中,成功模型的基础取决于其训练所用数据的质量。尽管人们常把目光投向复杂精巧的算法和模型,但真正的无名英雄往往是数据预处理。数据预处理是一个重要步骤,它将原始数据转化为可用于高效机器学习的特征。
机器学习算法通常是在一个前提下进行训练:所有特征对最终预测的贡献相同。然而,当特征的取值范围和单位不同,这一假设就不再成立,进而影响特征的重要性。
这时就需要归一化——数据预处理中一个关键步骤,用来确保各特征数值量级的一致性。这种一致性可以避免取值较大的特征对其他特征或变量产生“碾压式”的影响。
本文将深入介绍归一化,这是一种特征缩放技术,可用于在各特征之间“拉平”量级差异。
什么是归一化?
归一化是一种特定的特征缩放形式,会将特征的范围转换到一个标准尺度。只有当数据集中包含不同范围的特征时,归一化或任何数据缩放技术才是必要的。归一化涵盖多种技术,可针对不同的数据分布和模型需求进行定制。
归一化并不限于数值型数据。不过,本文将聚焦数值示例。如果您计划对文本数据进行机器学习预处理,务必查看 Datacamp 的Textacy:Python 文本数据清洗与归一化入门教程。
为何要对数据做归一化?
归一化的数据能提升模型性能并提高模型准确性。它对依赖距离度量的算法(如k 近邻或支持向量机)尤其有利,可防止量纲较大的特征在学习过程中占主导地位。
归一化还能增强优化过程的稳定性,促进基于梯度的训练更快收敛。它缓解了梯度消失或爆炸的问题,使模型更高效地逼近最优解。
归一化后的数据也更易于解释,因此更容易理解。当数据集的所有特征都在同一尺度上时,更容易识别和可视化不同特征之间的关系,并进行有意义的比较。
我们用一个简单示例来强调归一化的重要性。假设我们要根据多种特征(如建筑面积、卧室数量、到超市的距离等)来预测房价。该数据集中的特征尺度差异显著,例如:
如果在没有任何预处理的情况下直接将这些数据输入机器学习模型,算法可能会对尺度较大的特征(如建筑面积)赋予更高权重。在训练过程中,算法会假定总建筑面积的变化对房价影响显著,从而忽视相对较小的特征(如卧室数量和到超市的距离)的细微差别。这样的偏斜会导致模型表现不佳并出现有偏预测。
通过对特征进行归一化,我们可以确保每个特征在模型的学习过程中按比例贡献。模型由此能更有效地从所有特征中学习模式,从而更准确地刻画数据中的潜在关系。
归一化技术一览
最小-最大缩放和 Z 分数归一化(标准化)是两种基础归一化技术。除此之外,我们还将讨论小数缩放归一化、对数缩放归一化和稳健缩放,它们可应对数据预处理中的独特挑战。
最小-最大缩放
最小-最大缩放常被直接称为“归一化”。它将特征映射到一个指定范围内,通常是 0 到 1。其公式为:
Xnormalized = X – Xmin / Xmax – Xmin
其中,X 为待归一化的某个特征值,Xmin 为数据集中该特征的最小值,Xmax 为最大值。
以下情形适合采用最小-最大缩放:
Z 分数归一化(标准化)
Z 分数归一化(标准化)假定数据呈高斯(钟形曲线)分布,并将特征转换为均值(μ)为 0、标准差(σ)为 1。其公式为:
Xstandardized = X−μ / σ
该技术在处理假定数据呈正态分布的算法时尤其有用,例如许多线性模型。与最小-最大缩放不同,标准化后的特征值不受限于特定范围。该方法实质上用偏离均值的标准差个数来表示特征值。
在展开其他数据变换技术之前,我们先比较一下归一化(最小-最大缩放)与标准化。
归一化
标准化
目标是将特征值带入一个特定范围,通常为 0 到 1
目标是将特征值变换为均值为 0、标准差为 1
对异常值和数据范围敏感
由于使用均值与标准差,对异常值不那么敏感
当需要保持原始取值范围时有用
在算法假定标准正态分布时效果更好
不对数据分布做假设
假定数据服从或近似正态分布
适用于重视绝对数值及其关系的算法(如 k 近邻、神经网络)
对假定数据正态分布的算法尤为有用,如线性回归和支持向量机
在指定范围内保持原始数值的可解释性
改变了原始数值,因尺度与单位变化而使解释更具挑战
可加速收敛,尤其在依赖梯度下降的算法中
同样有助于更快收敛,尤其在对输入特征尺度敏感的算法中
应用场景:图像处理、神经网络、对特征尺度敏感的算法
应用场景:线性回归、支持向量机、假定正态分布的算法
小数缩放归一化
小数缩放归一化的目标是将特征值按 10 的幂进行缩放,确保每个特征中的最大绝对值小于 1。当已知数据集中各特征的取值范围,但不同特征的范围差异较大时,此方法很有用。其公式为:
Xdecimal = X / 10d
其中 X 是原始特征值,d 是使该特征最大绝对值小于 1 的最小整数。
例如,如果某个特征的最大绝对值为 3500,则 d 为 3,该特征将按 103 进行缩放。
当数据集中绝对量级比具体尺度更重要时,小数缩放归一化更具优势。
对数缩放归一化
对数缩放归一化通过对每个数据点取对数,将数据转换到对数尺度。当数据跨越多个数量级时,该方法尤为有用。其公式为:
Xlog = log(X)
当数据遵循指数增长或衰减模式时,这种归一化大显身手。它压缩数据集的尺度,便于模型捕捉数据中的模式和关系。例如人口规模随年份的变化就是一个存在指数增长特征的数据集。对数缩放归一化可以让这些特征更易于建模。
稳健缩放归一化
在包含异常值的数据集中,稳健缩放归一化非常有用。它使用中位数和四分位距(IQR)而非均值与标准差来处理异常值。其公式为:
Xrobust = X – median/ IQR
由于稳健缩放对异常值不敏感,因此适用于具有偏态或异常值的数据集。
常见归一化陷阱与最佳实践
我们已经讨论了归一化及其在机器学习中的作用。尽管强大,归一化也并非没有挑战。从处理异常值到基于数据集选择最合适的技术,妥善应对这些问题是释放机器学习模型全部潜力的关键。
处理异常值
异常值是与常规模式显著偏离的数据点,会削弱归一化技术的有效性。如果不处理数据中的异常值,可能导致偏斜的变换。您可以采用前文提到的稳健缩放归一化来应对异常值。
另一种策略是应用截尾或温莎化,即识别并将高于(或低于)某个阈值的特征值截断或封顶为固定值。
选择归一化技术
我们讨论了最常用的归一化技术,但可选方法远不止于此。选择合适的技术需要对数据集有细致入微的理解。在数据预处理时,您需要尝试多种归一化方法并评估它们对模型性能的影响。通过实验,您可以观察每种方法如何影响学习过程。
您需要深入理解数据的特性。考虑某种归一化技术的假设是否与数据集中的分布和模式相契合。
稀疏数据的归一化
当处理许多特征值为零的稀疏数据时,归一化会变得具有挑战。直接应用标准归一化可能带来意外后果。我们上文提到的归一化技术也有专为稀疏数据设计的变体,例如“稀疏最小-最大缩放”。
在归一化之前,请考虑对数据集中的缺失值进行插补或处理。这通常是您在探索数据并为机器学习模型清洗数据时的首要步骤之一。
务必查看 DataCamp 的Feature Engineering for Machine Learning 课程,该课程将通过实操教您如何为自己的机器学习模型准备各类数据。在课程中,您将使用 Stack Overflow 开发者调查以及历届美国总统就职演说,来理解如何最佳地对分类型、连续型和非结构化数据进行预处理与特征工程。
归一化与过拟合风险
在机器学习中,过拟合是指模型不仅学习了训练数据中的潜在模式,还捕捉到了噪声和随机波动。这会导致模型在训练数据上表现极佳,但在新的、未见数据上泛化能力不足。
归一化本身未必会导致过拟合。然而,当归一化与其他因素(如模型复杂度过高或正则化不足)叠加时,可能会加剧过拟合。当使用整个数据集(包含验证集或测试集)来计算归一化参数时,会造成数据泄漏。模型可能无意中从验证集或测试集中学到信息,从而削弱其泛化能力。
因此,为降低过拟合风险,应仅基于训练集计算归一化参数,并将同一参数应用于验证集和测试集。这样可确保模型仅从训练数据中学习泛化能力,而不受验证或测试数据的信息影响。
您需要实施恰当的正则化技术,以惩罚过于复杂的模型。正则化有助于防止模型拟合训练数据中的噪声。使用合适的验证方法(如交叉验证)来评估模型在未见数据上的表现。如果在验证过程中检测到过拟合,可以通过降低模型复杂度或增强正则化等方式进行调整。
使用 Scikit-learn 在 Python 中实现归一化
Scikit-learn 是一款多功能的 Python 库,旨在简化机器学习的复杂性。它提供了丰富的工具与功能,可用于数据预处理、特征选择、降维、构建和训练模型、模型评估、超参数调优、模型序列化、流水线构建等。其模块化设计鼓励试验与探索,帮助用户从基础概念顺畅过渡到高级方法。
我们将使用 scikit-learn 来将所学付诸实践。我们会使用经典且广泛使用的“Iris 数据集”。该数据集由英国生物学家和统计学家 Ronald A. Fisher 于 1936 年提出。Iris 数据集包含三种鸢尾花(setosa、versicolor 和 virginica)的四个特征测量值。
每朵花测量四个特征,分别是萼片长度、萼片宽度、花瓣长度和花瓣宽度,单位均为厘米。数据集中共有 150 条样本,每个物种各 50 条。Iris 数据集通常用于分类任务,目标是在三类中预测正确的物种。然而,今天我们将使用该数据集来展示在应用归一化(最小-最大缩放)和标准化时数据的变换。
您可以在 Datacamp 的workspace 中运行下面讨论的 Python 代码,亲自探索该数据集。
先导入我们需要的库……
当您使用
print(iris.DESCR)查看数据的摘要统计时,将会得到如下所示的摘要图像。以“sepal length”(萼片长度)特征为例,范围为 4.3–7.9 厘米;“sepal width”(萼片宽度)范围为 2–4.4 厘米;“petal length”(花瓣长度)范围为 1–6.9 厘米;“petal width”(花瓣宽度)范围为 0.1–2.5 厘米。在应用归一化之前,先将数据集划分为训练集和测试集是一个良好实践。我们将使用
sklearn.model_selection中的train_test_split来完成这一操作。由于本文不进行实际的机器学习建模,我们不会单独划出验证集。我们将按 80/20 划分数据集,即训练集包含 120 行,测试集包含剩余 30 个数据点。通常在加载并划分数据为训练/测试集后,需要执行数据清洗、缺失值插补以及异常值处理。然而,鉴于本文聚焦归一化——我们将跳过这些预处理步骤,直接看看归一化的实际效果。
我们现在使用最小-最大归一化技术,将这些数据缩放到 0–1 厘米的范围。为此,我们将使用 sklearn 库中的
MinMaxScaler功能并将其应用到数据集;所需库已在前文导入。我们可以打印训练数据来查看变换结果。不过,我们先将其转换为 pandas 数据框,然后使用
describe()功能查看其统计描述。归一化将得到如下结果:
此处的最小值和最大值统计显示,所有特征的范围都已被转换到 0–1 厘米。这正是我们想要的变换!接下来,我们将按与归一化相同的步骤执行标准化(Z 分数归一化):
标准化将得到如下结果:
Z 归一化的目标是将特征值变换为均值为 0、标准差为 1。正如从数据框的描述所见,四个特征的均值都接近于零,标准差为 1。
现在我们可以将这些变换后的数据输入某个机器学习算法进行训练。
总结
本文我们依次介绍了最小-最大缩放、Z 归一化、小数缩放以及对数缩放归一化。每种技术都有其独特优势与适用性。您也了解了执行归一化时的一些常见陷阱与最佳实践。最后,我们借助 scikit-learn 将部分新学知识付诸实践。
如需进一步学习相关概念与流程,请查看我们的课程:Feature Engineering for Machine Learning in Python 和 Textacy:Python 文本数据清洗与归一化入门。