一个神经网络拒绝收敛、损失停滞不前、梯度不是消失就是爆炸,很多时候并不是架构出了问题。原因往往更简单:输入特征的尺度相差悬殊——一列在 0 到 1 之间,另一列却动辄上万。
根据我的经验,这种情况在实务中屡见不鲜。几分钟的预处理,常常能解决数天的超参数调优都搞不定的问题。
在本教程中,我将向您展示如何进行数据归一化。我会带您了解不同的归一化技术及其适用场景,并附上 Python 实现。此外,您还将了解常见的错误与误解,以及如何规避它们。
如果您希望进一步学习如何为机器学习算法准备数据,推荐参加我们的 Python 机器学习预处理 课程。
什么是数据归一化?
数据归一化是指将数值型特征转换为可比的取值范围或遵循一致的尺度的过程。
该术语在不同语境下含义不同:在机器学习中,通常指对特征值进行重缩放,防止数值大小主导重要性;而在数据库设计中,它指通过组织表结构来消除冗余。
本文将主要聚焦于机器学习语境下的含义,但我们会在后文简要介绍数据库规范化,以澄清术语重叠。
为什么数据归一化很重要
当特征处于不同尺度时,某些算法会对数值更大的特征赋予不成比例的权重。
一个以千为单位的收入特征会压过一个以十年为单位的年龄特征,这并非因为收入对预测更重要,而只是因为数值更大。归一化让特征站在同一起跑线上,使模型可以学习到哪些特征才是真正重要的。
除了模型训练,归一化还有助于:
合并使用不同计量单位的测量值
整合来自多源且约定不一致的数据
设计需要长期保持一致性的数据库模式。
数据归一化 vs. 缩放 vs. 标准化
那么,归一化、缩放和标准化之间有什么区别?这三个术语在文档中经常出现,且常被混用,尽管它们含义不同。
实践中的区别在于您的模型是否需要值落在特定范围内。Min-max 归一化能保证边界,而标准化则不能。下表总结了差异:
术语
作用
输出范围
最适用场景
缩放(Scaling)
对取值范围进行任意变换的统称
不定
上位概念
归一化(min-max)
压缩到固定边界
通常为 0 到 1
有边界的数据、期望特定输入范围的神经网络
标准化(z-score)
以均值 0 为中心、标准差缩放为 1
无上限(可能为负)
无边界数据、假定近似正态分布的算法
若想更深入比较各方法在何时失效,可参阅我们的博文 Normalization vs. Standardization Explained 对边界情形有详尽讨论。
数据归一化的应用场景
明确术语后,我们来看一些经典用例。归一化在不同场景中有不同目的,从改善模型训练动态到让异构数据源之间的比较更有意义。
提升机器学习模型表现
神经网络 与 逻辑回归 通过 梯度下降 更新权重,每个特征对预测误差的贡献决定相应权重的调整幅度。
当特征量级差异巨大时,梯度也会随之差异巨大:大数值特征产生大的梯度,小数值特征产生小的梯度。这种不平衡会导致优化器在某些方向迈出巨步,而在另一些方向几乎不动,造成训练不稳定或完全不收敛。
基于距离的算法,如 kNN 和 K-means 也有类似问题。它们用距离度量(通常为欧式距离)来计算相似度,数值更大的特征仅因更大而对计算贡献更多。一个 0 到 10000 的特征会压过一个 0 到 1 的特征,而不管哪一个对任务更重要。
缩放能确保所有特征按其实际预测价值而不是任意数值范围作出相称贡献。
实现特征间的公平比较
在构建综合评分或合并不同单位的测量时,原始值可能造成误导性的比较。
一个客户健康度指标,若合并以美元计的月消费、计数型的登录频率和以天计的账户年龄,将不可避免地让美元金额权重最高,仅仅因为这些数字更大。
归一化可以让这些测量按实际重要性而非偶然的数值大小进行合并。
这同样适用于探索性分析与可视化。将不同尺度的特征放在一起绘图,会更难发现模式或比较分布。归一化后的数据能更清晰地展示特征之间的关系。
提升数据质量与一致性
生产流水线常常汇集多源数据,约定不一致。某个系统以美元报告收入,另一个系统以“千美元”为单位。某些 API 用 Unix 时间戳表示日期,另一些则是格式化字符串。
在下游处理之前确立一致的尺度与格式,可以防止那些难以在后续排查的隐蔽缺陷。
在数据库语境中,规范化(Normalization)含义不同但相关:通过组织表,使每条信息只出现在唯一位置。
这可以防止更新异常——在一个地方修改了值,却在别处留下矛盾的值。尽管方法不同于特征缩放,底层动机相似:保持数据一致且可预测。
常见的数据归一化技术
每种归一化方法对数据的假设不同,产出的特性也不同。正确选择取决于数据分布、是否存在离群点,以及下游模型的要求。
Min-max 归一化
Min-max 归一化通过减去最小值并除以极差,将值压缩到固定范围(通常为 0 到 1)。该方法在保证所有值落入已知边界的同时,保留原始分布形状。
工作原理: 减最小值、除极差。就是这么简单。
作用:
保证输出落在定义的边界内
保留原分布形状——只是重缩放
零成为下限,一成为上限
最佳用途:
像素强度(按定义总在 0-255)
概率与百分比
考试分数、评分,任何有自然上下限的指标
期望有界输入的神经网络,如图像分类器
注意事项:
离群点可能彻底破坏 min-max 归一化。若大多数数据在 10 到 100 之间,却有一个值为 99,999?这个点会把范围拉得极大,使得所有正常数据都被压缩在接近零的窄区间里。一个坏观测,就毁了一整列特征。
还要考虑新数据超出训练范围时会发生什么。测试值若超过训练最大值,输出会高于 1。是否会出问题取决于您的模型。
Z-score 标准化
Z-score 标准化 将数据变换为均值为 0、标准差为 1,同时不对输出施加固定边界。该方法适用于没有明显自然界限的数据,并被许多算法实现所假定或推荐。
工作原理: 减均值、除标准差。
作用:
将数据重心移到均值为零
缩放到“一标准差等于一个单位”
输出可为负,也可超过任意界限
最佳用途:
没有明显自然界限的数据
近似钟形分布
假定或推荐标准化输入的算法(多数神经网络教程、逻辑回归实现)
当您不确定该用何种方法时(一个合理默认)
权衡:
可解释性会打折扣。“该观测高于平均值 1.7 个标准差”比“该值在范围的 80%”更费脑。若相关方需要直接理解缩放后的值,min-max 或许更易沟通。
离群点仍会抬高均值与标准差,从而扭曲大多数数据的缩放,但问题比 min-max 要小。
稳健缩放(Robust scaling)
稳健缩放通过使用 中位数 与四分位距(IQR)而非均值与标准差,来解决 min-max 与 z-score 方法对离群点的敏感性。这些统计量无论分布尾部有多极端都更稳定。
工作原理: 减中位数、除以 IQR(第 25 百分位到第 75 百分位的差)。
作用:
基于数据中间的大多数样本进行缩放,忽略极端值
尾部如何波动都不会扭曲典型值的变换
当数据存在无法删除的合法离群点时更稳定
最佳用途:
金融交易:大多数购买金额较小,但偶尔会有合法的大额交易
收入数据:通常具有长右尾
传感器读数:尖峰代表真实事件
任何高度偏斜的分布,以及均值驱动的方法会被极端值“拖拽”的情形
为何有助于偏斜数据:
收入分布是个好例子。多数人收入适中,少数人收入极高:典型的右偏分布。标准差会被高收入者抬高,使标准化对大多数观测的效用降低。中位数与 IQR 则始终锚定在分布中部。
单位范数向量归一化
单位范数(L1/L2)归一化与上面的方法不同:它通常对样本(行)而非特征(列)进行缩放。将每个样本向量重缩放,使其在所选范数(常为 L2)下的长度为 1,从而去除整体量级,仅保留方向/成分比例。
不要 把这与 L1/L2 正则化 (Lasso/Ridge)混淆:正则化是通过对模型权重添加惩罚来修改训练目标以减少过拟合,而不是通过重缩放输入向量。
工作原理: 在 L2 归一化中,每一行都除以其欧氏范数,使平方和为 1。L1 则用绝对值之和。
作用:
将量级从等式中剔除
让行与行按比例而非绝对大小可比
向量间夹角成为信号;向量长度则无关紧要
最佳用途:
以词频向量表示的文本数据:5 万字的报告词频自然大于 500 字邮件,但用 L2 可比较内容比例
任何涉及余弦相似度的应用
基于内容的文档分类、信息检索与推荐系统
不适用场景:
量级确实有意义的场景。如果总词数对任务有含义,把它“归一化掉”就丢失了信息。
数据库规范化
数据库规范化指重构关系表以消除冗余、提升数据完整性——例如确保客户的邮箱只存储在一个位置,而不是每条订单记录中都重复。
它与特征缩放没有关联。
术语只是重名而已。在机器学习中,“normalization”几乎总是指对数值进行缩放;在数据工程或 SQL 中,它指组织表结构(常见为 1NF、2NF、3NF)。
关键区别:
特征归一化(ML): 变换数值(如 0–1 缩放)以帮助模型学习。
数据库规范化(SQL): 组织模式以防止数据重复。
如果一位数据工程师让您“规范化数据库”,他们要的是修表结构,而不是运行MinMaxScaler。
要深入了解,请查看这篇 SQL 中的数据库规范化 指南。
如何在实践中进行数据归一化
要正确实现归一化,需特别注意操作顺序,尤其是在训练/测试集划分环节。代码本身并不复杂,但流程先后的一些细微错误会让整个评估失效。
在 Python 中进行归一化
Scikit-learn 为您提供了各种缩放器,但关键规则是流程性的,而非数学性的: 先划分,再只在训练集上拟合,然后在其他任何地方复用这个已拟合的变换器 。
为何如此谨慎?因为缩放会从数据中“学习”数值:最小/最大、均值/标准差、中位数/IQR。如果这些数值用到了测试集,您就悄悄让未来信息泄露进了训练。程序不会报错,但指标已不再是您以为的含义。
一个最小示例:
import pandas as pd
from sklearn. preprocessing import MinMaxScaler, StandardScaler, RobustScaler
from sklearn. model_selection import train_test_split
data = pd. DataFrame( {
'age' : [ 25 , 32 , 47 , 51 , 62 , 28 , 35 , 44 ] ,
'income' : [ 30000 , 45000 , 72000 , 85000 , 120000 , 38000 , 55000 , 67000 ] ,
'score' : [ 0.2 , 0.5 , 0.7 , 0.4 , 0.9 , 0.3 , 0.6 , 0.8 ]
} )
train_data, test_data = train_test_split( data, test_size= 0.25 , random_state= 42 ) 技术支持
此时,您应将训练集视为“我构建模型时世界的样子”,测试集则是“新的、未见过的数据”。缩放器只应从前者学习这个“世界”。
MinMaxScaler
Min-max 标准化很直接:它为每列保存训练集中的最小值与最大值,然后在后续应用相同映射。
scaler = MinMaxScaler( )
scaler. fit( train_data)
train_scaled = scaler. transform( train_data)
test_scaled = scaler. transform( test_data) 技术支持
如果您发现自己在测试集上调用了fit(),请停下来。这违背了保留测试集的初衷。
StandardScaler
StandardScaler会保存训练集的均值与标准差,并用这些值同时变换训练集与测试集。
scaler = StandardScaler( )
scaler. fit( train_data)
train_standardized = scaler. transform( train_data)
test_standardized = scaler. transform( test_data) 技术支持
这就是发生泄露时“悄无声息”出问题的那种,因为均值/标准差很容易因不小心使用了过多数据而被“稳定”。
RobustScaler
RobustScaler依旧是“只拟合一次、反复复用”,但使用中位数与 IQR,因此少量极端点不会决定尺度。
scaler = RobustScaler( )
scaler. fit( train_data)
train_robust = scaler. transform( train_data)
test_robust = scaler. transform( test_data) 技术支持
一个实用信号,提示值得用稳健缩放:您有一个想保留的长尾(支付、理赔、传感器尖峰),且不希望某个奇怪的一天把其余样本挤到接近零。
快速 pandas 计算
用于快速探索,直接在 pandas 中做运算没问题,只要您清楚:这是为了目测分布,而不是用于模型评估。
df_minmax = ( data - data. min ( ) ) / ( data. max ( ) - data. min ( ) )
df_zscore = ( data - data. mean( ) ) / data. std( ) 技术支持
防止数据泄露
这里的风险在于:统计量基于整个数据集。若在划分前这么做,测试值会影响变换。您的评估将失去意义,因为预处理已经偷看了不该看的答案。
泄露的模式通常是这样的:
错误做法:
scaler = MinMaxScaler( )
scaled_all = scaler. fit_transform( full_data)
train, test = split( scaled_all) 技术支持
这种方法在划分前先做了归一化,因此测试数据已经影响了变换。
正确做法:
先划分数据,确保缩放器只从训练集学习统计量,保持测试数据真正“未见”。
scaler = MinMaxScaler( )
scaler. fit( train_data)
train_scaled = scaler. transform( train_data)
test_scaled = scaler. transform( test_data) 技术支持
同样的操作,不同的顺序。而顺序就是关键。
如果您想端到端练习预处理(包括正确标准化与避免泄露),这门课程正合适: Python 机器学习预处理。
在 SQL 中的“规范化”
如前所述,我们有同一词的不同含义。这里的“规范化”不是数值变换,而是一个结构性决策:停止重复事实。
如果您的订单表在每行都存customer_email,数据库会允许这么做。数据库也会在之后欣然接受矛盾:同一客户在不同行有不同邮箱,而且没有显而易见的办法判断哪一个才是“真实”。
规范化之前:
CREATE TABLE orders_denormalized (
order_id INT ,
customer_name VARCHAR ( 100 ) ,
customer_email VARCHAR ( 100 ) ,
product_name VARCHAR ( 100 ) ,
product_price DECIMAL ( 10 , 2 ) ,
quantity INT
) ; 技术支持
客户信息在每行重复。更新邮箱意味着要找到并修改其所有订单。
规范化之后:
CREATE TABLE customers (
customer_id INT PRIMARY KEY ,
name VARCHAR ( 100 ) ,
email VARCHAR ( 100 )
) ;
CREATE TABLE products (
product_id INT PRIMARY KEY ,
name VARCHAR ( 100 ) ,
price DECIMAL ( 10 , 2 )
) ;
CREATE TABLE orders (
order_id INT PRIMARY KEY ,
customer_id INT REFERENCES customers( customer_id) ,
product_id INT REFERENCES products( product_id) ,
quantity INT
) ; 技术支持
客户信息只存一次。查询需要关联,但更新只在一个地方完成。
如何选择合适的归一化技术
最后,我想给您一个决策框架,帮助您在下次需要选择归一化技术时做判断。
当存在边界时用 min-max
当数据具有已知且稳定的边界,且这些边界在训练与部署间不会变化时,min-max 缩放效果最佳。像素值始终在 0 到 255;概率不会超过 1;考试分数有定义好的最小值和最大值。
当模型明确期望有界输入时(一些神经网络架构即如此),这种方法也很合适。但若存在离群点应尽量避免 min-max,因为一个极端值就可能把所有正常观测压到靠近零的狭窄区间。
不确定时用标准化作兜底
当您对数据的边界或分布缺乏强假设时,标准化是一个合理默认。它适合取值范围各异、上限未知或近似钟形分布的特征。
许多算法实现会假定或推荐标准化输入,包括多数神经网络框架与逻辑回归库。若不确定该用哪种方法,且数据没有明显自然边界,标准化通常是安全选择。
真实世界“脏数据”用稳健缩放
当数据包含代表真实值(而非错误)的显著离群点时,稳健缩放成为正确选择。金融交易数据通常具备这一特征:大多数购买金额较小,但偶发大额交易是真实存在且应保留的。
收入分布、带有偶发尖峰的传感器读数,以及任何具有重偏斜或长尾的数据都能从稳健缩放中受益。中位数与四分位距始终锚定在分布主体,无论极端区域如何波动。
何时不必归一化
基于树的模型(随机森林、XGBoost、梯度提升树)通过阈值切分处理特征,从不在特征间计算距离或梯度。尺度对它们而言是“隐形”的,因此归一化只会平添复杂而无益处。
独热编码特征已是二值(0 和 1),对其缩放并无实质意义。仅含类别特征的数据集同理。
有时,领域特定的变换优于通用归一化:
对数缩放能压缩长右尾,同时展开扎堆的低值,常比通用方法更适用于收入或价格数据。
分箱在类别归属比精确数值更重要时更有意义。
幂变换在特定场景下有助于稳定方差。
总结对比表
以下是各技术及其适用情形的概览:
技术
适用情形
避免情形
输出范围
Min-max
数据有已知边界;模型期望有界输入
存在离群点;边界可能变化
固定 0 到 1
标准化
边界未知;近似正态;拿不准用哪种
需要保证边界;离群点很多
无界
稳健缩放
离群点显著;分布偏斜;长尾
数据已干净且对称
无界
L1/L2 归一化
文本数据;余弦相似度;高维空间
量级有意义
单位向量
无
树模型;独热特征;有更合适的领域变换
基于梯度或距离的模型
原始范围
结论
尺度差异会给在意尺度的模型带来真实困扰。距离度量会偏向数值量级大的特征;当梯度跨数个数量级时,梯度下降会吃力。训练停滞或发散的原因未必能从代码或架构上直接看出。
归一化可以解决这些问题。对有界数据用 min-max,对无法移除的真实离群点用稳健缩放,而标准化是一个合理默认。操作机制很简单:在训练集上拟合,并在各处一致应用。
以我的经验,最费时的不是实现缩放,而是没意识到何时需要缩放,结果为模型调试了好几天,而答案其实在预处理。反之亦然,动不动就对不在意尺度的模型做缩放,徒增复杂却无任何收益。
准备升级吗?我们全面的 机器学习工程师 学习路径将教授机器学习工作流所需的一切。
一个神经网络拒绝收敛、损失停滞不前、梯度不是消失就是爆炸,很多时候并不是架构出了问题。原因往往更简单:输入特征的尺度相差悬殊——一列在 0 到 1 之间,另一列却动辄上万。
根据我的经验,这种情况在实务中屡见不鲜。几分钟的预处理,常常能解决数天的超参数调优都搞不定的问题。
在本教程中,我将向您展示如何进行数据归一化。我会带您了解不同的归一化技术及其适用场景,并附上 Python 实现。此外,您还将了解常见的错误与误解,以及如何规避它们。
如果您希望进一步学习如何为机器学习算法准备数据,推荐参加我们的Python 机器学习预处理课程。
什么是数据归一化?
数据归一化是指将数值型特征转换为可比的取值范围或遵循一致的尺度的过程。
该术语在不同语境下含义不同:在机器学习中,通常指对特征值进行重缩放,防止数值大小主导重要性;而在数据库设计中,它指通过组织表结构来消除冗余。
本文将主要聚焦于机器学习语境下的含义,但我们会在后文简要介绍数据库规范化,以澄清术语重叠。
为什么数据归一化很重要
当特征处于不同尺度时,某些算法会对数值更大的特征赋予不成比例的权重。
一个以千为单位的收入特征会压过一个以十年为单位的年龄特征,这并非因为收入对预测更重要,而只是因为数值更大。归一化让特征站在同一起跑线上,使模型可以学习到哪些特征才是真正重要的。
除了模型训练,归一化还有助于:
数据归一化 vs. 缩放 vs. 标准化
那么,归一化、缩放和标准化之间有什么区别?这三个术语在文档中经常出现,且常被混用,尽管它们含义不同。
实践中的区别在于您的模型是否需要值落在特定范围内。Min-max 归一化能保证边界,而标准化则不能。下表总结了差异:
术语
作用
输出范围
最适用场景
缩放(Scaling)
对取值范围进行任意变换的统称
不定
上位概念
归一化(min-max)
压缩到固定边界
通常为 0 到 1
有边界的数据、期望特定输入范围的神经网络
标准化(z-score)
以均值 0 为中心、标准差缩放为 1
无上限(可能为负)
无边界数据、假定近似正态分布的算法
若想更深入比较各方法在何时失效,可参阅我们的博文Normalization vs. Standardization Explained对边界情形有详尽讨论。
数据归一化的应用场景
明确术语后,我们来看一些经典用例。归一化在不同场景中有不同目的,从改善模型训练动态到让异构数据源之间的比较更有意义。
提升机器学习模型表现
神经网络与逻辑回归通过梯度下降更新权重,每个特征对预测误差的贡献决定相应权重的调整幅度。
当特征量级差异巨大时,梯度也会随之差异巨大:大数值特征产生大的梯度,小数值特征产生小的梯度。这种不平衡会导致优化器在某些方向迈出巨步,而在另一些方向几乎不动,造成训练不稳定或完全不收敛。
基于距离的算法,如kNN和K-means也有类似问题。它们用距离度量(通常为欧式距离)来计算相似度,数值更大的特征仅因更大而对计算贡献更多。一个 0 到 10000 的特征会压过一个 0 到 1 的特征,而不管哪一个对任务更重要。
缩放能确保所有特征按其实际预测价值而不是任意数值范围作出相称贡献。
实现特征间的公平比较
在构建综合评分或合并不同单位的测量时,原始值可能造成误导性的比较。
一个客户健康度指标,若合并以美元计的月消费、计数型的登录频率和以天计的账户年龄,将不可避免地让美元金额权重最高,仅仅因为这些数字更大。
归一化可以让这些测量按实际重要性而非偶然的数值大小进行合并。
这同样适用于探索性分析与可视化。将不同尺度的特征放在一起绘图,会更难发现模式或比较分布。归一化后的数据能更清晰地展示特征之间的关系。
提升数据质量与一致性
生产流水线常常汇集多源数据,约定不一致。某个系统以美元报告收入,另一个系统以“千美元”为单位。某些 API 用 Unix 时间戳表示日期,另一些则是格式化字符串。
在下游处理之前确立一致的尺度与格式,可以防止那些难以在后续排查的隐蔽缺陷。
在数据库语境中,规范化(Normalization)含义不同但相关:通过组织表,使每条信息只出现在唯一位置。
这可以防止更新异常——在一个地方修改了值,却在别处留下矛盾的值。尽管方法不同于特征缩放,底层动机相似:保持数据一致且可预测。
常见的数据归一化技术
每种归一化方法对数据的假设不同,产出的特性也不同。正确选择取决于数据分布、是否存在离群点,以及下游模型的要求。
Min-max 归一化
Min-max 归一化通过减去最小值并除以极差,将值压缩到固定范围(通常为 0 到 1)。该方法在保证所有值落入已知边界的同时,保留原始分布形状。
工作原理:减最小值、除极差。就是这么简单。
作用:
最佳用途:
注意事项:
离群点可能彻底破坏 min-max 归一化。若大多数数据在 10 到 100 之间,却有一个值为 99,999?这个点会把范围拉得极大,使得所有正常数据都被压缩在接近零的窄区间里。一个坏观测,就毁了一整列特征。
还要考虑新数据超出训练范围时会发生什么。测试值若超过训练最大值,输出会高于 1。是否会出问题取决于您的模型。
Z-score 标准化
Z-score 标准化将数据变换为均值为 0、标准差为 1,同时不对输出施加固定边界。该方法适用于没有明显自然界限的数据,并被许多算法实现所假定或推荐。
工作原理:减均值、除标准差。
作用:
最佳用途:
权衡:
可解释性会打折扣。“该观测高于平均值 1.7 个标准差”比“该值在范围的 80%”更费脑。若相关方需要直接理解缩放后的值,min-max 或许更易沟通。
离群点仍会抬高均值与标准差,从而扭曲大多数数据的缩放,但问题比 min-max 要小。
稳健缩放(Robust scaling)
稳健缩放通过使用中位数与四分位距(IQR)而非均值与标准差,来解决 min-max 与 z-score 方法对离群点的敏感性。这些统计量无论分布尾部有多极端都更稳定。
工作原理:减中位数、除以 IQR(第 25 百分位到第 75 百分位的差)。
作用:
最佳用途:
为何有助于偏斜数据:
收入分布是个好例子。多数人收入适中,少数人收入极高:典型的右偏分布。标准差会被高收入者抬高,使标准化对大多数观测的效用降低。中位数与 IQR 则始终锚定在分布中部。
单位范数向量归一化
单位范数(L1/L2)归一化与上面的方法不同:它通常对样本(行)而非特征(列)进行缩放。将每个样本向量重缩放,使其在所选范数(常为 L2)下的长度为 1,从而去除整体量级,仅保留方向/成分比例。
不要把这与 L1/L2正则化(Lasso/Ridge)混淆:正则化是通过对模型权重添加惩罚来修改训练目标以减少过拟合,而不是通过重缩放输入向量。
工作原理:在 L2 归一化中,每一行都除以其欧氏范数,使平方和为 1。L1 则用绝对值之和。
作用:
最佳用途:
不适用场景:
量级确实有意义的场景。如果总词数对任务有含义,把它“归一化掉”就丢失了信息。
数据库规范化
数据库规范化指重构关系表以消除冗余、提升数据完整性——例如确保客户的邮箱只存储在一个位置,而不是每条订单记录中都重复。
它与特征缩放没有关联。
术语只是重名而已。在机器学习中,“normalization”几乎总是指对数值进行缩放;在数据工程或 SQL 中,它指组织表结构(常见为 1NF、2NF、3NF)。
关键区别:
如果一位数据工程师让您“规范化数据库”,他们要的是修表结构,而不是运行
MinMaxScaler。要深入了解,请查看这篇SQL 中的数据库规范化指南。
如何在实践中进行数据归一化
要正确实现归一化,需特别注意操作顺序,尤其是在训练/测试集划分环节。代码本身并不复杂,但流程先后的一些细微错误会让整个评估失效。
在 Python 中进行归一化
Scikit-learn 为您提供了各种缩放器,但关键规则是流程性的,而非数学性的:先划分,再只在训练集上拟合,然后在其他任何地方复用这个已拟合的变换器。
为何如此谨慎?因为缩放会从数据中“学习”数值:最小/最大、均值/标准差、中位数/IQR。如果这些数值用到了测试集,您就悄悄让未来信息泄露进了训练。程序不会报错,但指标已不再是您以为的含义。
一个最小示例:
此时,您应将训练集视为“我构建模型时世界的样子”,测试集则是“新的、未见过的数据”。缩放器只应从前者学习这个“世界”。
MinMaxScaler
Min-max 标准化很直接:它为每列保存训练集中的最小值与最大值,然后在后续应用相同映射。
如果您发现自己在测试集上调用了
fit(),请停下来。这违背了保留测试集的初衷。StandardScaler
StandardScaler会保存训练集的均值与标准差,并用这些值同时变换训练集与测试集。这就是发生泄露时“悄无声息”出问题的那种,因为均值/标准差很容易因不小心使用了过多数据而被“稳定”。
RobustScaler
RobustScaler依旧是“只拟合一次、反复复用”,但使用中位数与 IQR,因此少量极端点不会决定尺度。一个实用信号,提示值得用稳健缩放:您有一个想保留的长尾(支付、理赔、传感器尖峰),且不希望某个奇怪的一天把其余样本挤到接近零。
快速 pandas 计算
用于快速探索,直接在 pandas 中做运算没问题,只要您清楚:这是为了目测分布,而不是用于模型评估。
防止数据泄露
这里的风险在于:统计量基于整个数据集。若在划分前这么做,测试值会影响变换。您的评估将失去意义,因为预处理已经偷看了不该看的答案。
泄露的模式通常是这样的:
错误做法:
这种方法在划分前先做了归一化,因此测试数据已经影响了变换。
正确做法:
先划分数据,确保缩放器只从训练集学习统计量,保持测试数据真正“未见”。
同样的操作,不同的顺序。而顺序就是关键。
如果您想端到端练习预处理(包括正确标准化与避免泄露),这门课程正合适:Python 机器学习预处理。
在 SQL 中的“规范化”
如前所述,我们有同一词的不同含义。这里的“规范化”不是数值变换,而是一个结构性决策:停止重复事实。
如果您的订单表在每行都存
customer_email,数据库会允许这么做。数据库也会在之后欣然接受矛盾:同一客户在不同行有不同邮箱,而且没有显而易见的办法判断哪一个才是“真实”。规范化之前:
客户信息在每行重复。更新邮箱意味着要找到并修改其所有订单。
规范化之后:
客户信息只存一次。查询需要关联,但更新只在一个地方完成。
如何选择合适的归一化技术
最后,我想给您一个决策框架,帮助您在下次需要选择归一化技术时做判断。
当存在边界时用 min-max
当数据具有已知且稳定的边界,且这些边界在训练与部署间不会变化时,min-max 缩放效果最佳。像素值始终在 0 到 255;概率不会超过 1;考试分数有定义好的最小值和最大值。
当模型明确期望有界输入时(一些神经网络架构即如此),这种方法也很合适。但若存在离群点应尽量避免 min-max,因为一个极端值就可能把所有正常观测压到靠近零的狭窄区间。
不确定时用标准化作兜底
当您对数据的边界或分布缺乏强假设时,标准化是一个合理默认。它适合取值范围各异、上限未知或近似钟形分布的特征。
许多算法实现会假定或推荐标准化输入,包括多数神经网络框架与逻辑回归库。若不确定该用哪种方法,且数据没有明显自然边界,标准化通常是安全选择。
真实世界“脏数据”用稳健缩放
当数据包含代表真实值(而非错误)的显著离群点时,稳健缩放成为正确选择。金融交易数据通常具备这一特征:大多数购买金额较小,但偶发大额交易是真实存在且应保留的。
收入分布、带有偶发尖峰的传感器读数,以及任何具有重偏斜或长尾的数据都能从稳健缩放中受益。中位数与四分位距始终锚定在分布主体,无论极端区域如何波动。
何时不必归一化
基于树的模型(随机森林、XGBoost、梯度提升树)通过阈值切分处理特征,从不在特征间计算距离或梯度。尺度对它们而言是“隐形”的,因此归一化只会平添复杂而无益处。
独热编码特征已是二值(0 和 1),对其缩放并无实质意义。仅含类别特征的数据集同理。
有时,领域特定的变换优于通用归一化:
总结对比表
以下是各技术及其适用情形的概览:
技术
适用情形
避免情形
输出范围
Min-max
数据有已知边界;模型期望有界输入
存在离群点;边界可能变化
固定 0 到 1
标准化
边界未知;近似正态;拿不准用哪种
需要保证边界;离群点很多
无界
稳健缩放
离群点显著;分布偏斜;长尾
数据已干净且对称
无界
L1/L2 归一化
文本数据;余弦相似度;高维空间
量级有意义
单位向量
无
树模型;独热特征;有更合适的领域变换
基于梯度或距离的模型
原始范围
结论
尺度差异会给在意尺度的模型带来真实困扰。距离度量会偏向数值量级大的特征;当梯度跨数个数量级时,梯度下降会吃力。训练停滞或发散的原因未必能从代码或架构上直接看出。
归一化可以解决这些问题。对有界数据用 min-max,对无法移除的真实离群点用稳健缩放,而标准化是一个合理默认。操作机制很简单:在训练集上拟合,并在各处一致应用。
以我的经验,最费时的不是实现缩放,而是没意识到何时需要缩放,结果为模型调试了好几天,而答案其实在预处理。反之亦然,动不动就对不在意尺度的模型做缩放,徒增复杂却无任何收益。
准备升级吗?我们全面的机器学习工程师学习路径将教授机器学习工作流所需的一切。