机器学习归一化(Normalization)完全指南
归一化是机器学习特征工程中的核心技术,用于将不同尺度、范围的特征转换到统一的数值区间,消除特征间的量纲差异,从而提升模型训练效率和预测精度。本文将系统梳理所有主流归一化方法,涵盖原理、适用场景、语法格式、实战案例及方法对比,帮助你全面掌握归一化技术。
一、归一化基础认知
1. 定义
归一化(Normalization):将特征值缩放至固定数值范围(如[0,1]、[-1,1])或单位范数(如L1、L2范数)的过程,核心是“缩放”而非“中心化”(与标准化的核心区别)。
2. 核心目的
- 消除量纲影响:例如“身高(cm,范围150-190)”和“体重(kg,范围40-100)”,避免模型过度偏向尺度大的特征。
- 加速模型收敛:尤其是基于梯度下降的模型(如神经网络、逻辑回归),统一尺度可减少迭代次数。
- 提升模型精度:对基于距离的模型(如KNN、SVM)至关重要,避免距离计算被尺度大的特征主导。
3. 归一化 vs 标准化(关键区分)
初学者易混淆两者,核心差异如下:
| 特性 | 归一化(Normalization) | 标准化(Standardization) |
|---|---|---|
| 核心目标 | 缩放至固定范围/单位范数 | 缩放至均值=0,方差=1(中心化+缩放) |
| 数据分布假设 | 无强制假设(可非正态) | 隐含假设数据近似正态分布 |
| 异常值敏感性 | 高(如Min-Max受极值影响大) | 低(基于均值和方差,受极值影响小) |
| 适用模型 | KNN、SVM、神经网络、协同过滤 | 逻辑回归、线性回归、PCA、深度学习 |
| 典型方法 | Min-Max、Max-Abs、L1/L2、小数定标 | Z-Score标准化(最常用) |
二、主流归一化方法(原理+语法+案例)
以下方法均基于 Python 3.x + scikit-learn 1.2+ 实现(scikit-learn是机器学习特征工程的标准库),部分无现成API的方法将手动实现。
2.1 最小-最大归一化(Min-Max Normalization)
原理
将特征值线性缩放至 [0,1] 区间(默认),也可自定义目标区间(如[a,b])。
核心公式:
- 默认区间[0,1]:Xnorm=X−XminXmax−XminX_{\text{norm}} = \frac{X - X_{\text{min}}}{X_{\text{max}} - X_{\text{min}}}Xnorm=Xmax−XminX−Xmin
- 自定义区间[a,b]:Xnorm=a+(X−Xmin)×(b−a)Xmax−XminX_{\text{norm}} = a + \frac{(X - X_{\text{min}}) \times (b - a)}{X_{\text{max}} - X_{\text{min}}}Xnorm=a+Xmax−Xmin(X−Xmin)×(b−a)
其中,XminX_{\text{min}}Xmin 是特征的最小值,XmaxX_{\text{max}}Xmax 是特征的最大值。
适用场景
- 特征分布无明显异常值(如用户年龄、商品价格)。
- 模型对特征范围有明确要求(如神经网络输入层、协同过滤算法)。
语法格式(sklearn)
from sklearn.preprocessing import MinMaxScaler
# 1. 初始化归一化器(默认区间[0,1],可通过feature_range自定义)
scaler = MinMaxScaler(feature_range=(0, 1)) # 自定义区间如(1,5)
# 2. 拟合(计算X_min和X_max)+ 转换(缩放数据)
X_norm = scaler.fit_transform(X) # X为2D数组(n_samples, n_features)
# 3. 逆转换(从归一化后的数据恢复原始数据)
X_original = scaler.inverse_transform(X_norm)
实战案例
以鸢尾花(Iris)数据集的“萼片长度(sepal length)”为例(原始范围:4.3~7.9 cm):
from sklearn.preprocessing import MinMaxScaler
from sklearn.datasets import load_iris
import numpy as np
# 1. 加载数据(取单个特征,需reshape为2D数组)
iris = load_iris()
X = iris.data[:, 0].reshape(-1, 1) # sepal length,shape=(150,1)
print("原始数据(前5个):", X[:5].flatten())
print("原始数据范围:", X.min(), "~", X.max())
# 2. 初始化并拟合转换
scaler = MinMaxScaler(feature_range=(0, 1))
X_norm = scaler.fit_transform(X)
# 3. 输出结果
print("\n归一化后数据(前5个):", X_norm[:5].flatten().round(3))
print("归一化后范围:", X_norm.min(), "~", X_norm.max())
# 4. 逆转换验证
X_original = scaler.inverse_transform(X_norm)
print("\n逆转换后数据(前5个):", X_original[:5].flatten().round(1))
输出结果
原始数据(前5个): [5.1 4.9 4.7 4.6 5. ]
原始数据范围: 4.3 ~ 7.9
归一化后数据(前5个): [0.222 0.167 0.111 0.083 0.194]
归一化后范围: 0.0 ~ 1.0
逆转换后数据(前5个): [5.1 4.9 4.7 4.6 5. ]
优缺点
- 优点:简单直观、缩放后数据范围明确。
- 缺点:对异常值极其敏感(如数据中存在100的极端值,会压缩其他数据至接近0)。
2.2 最大绝对值归一化(Max-Abs Normalization)
原理
将特征值除以该特征的最大绝对值,缩放至 [-1, 1] 区间(若特征有负值)或 [0, 1] 区间(若特征无负值)。
核心公式:Xnorm=X∣Xmax∣X_{\text{norm}} = \frac{X}{|X_{\text{max}}|}Xnorm=∣Xmax∣X
其中,∣Xmax∣|X_{\text{max}}|∣Xmax∣ 是特征绝对值的最大值。
适用场景
- 特征存在正负值(如温度、股票涨跌幅)。
- 稀疏数据(如文本TF-IDF特征):不改变数据的稀疏性(因未中心化,零值仍为零)。
语法格式(sklearn)
from sklearn.preprocessing import MaxAbsScaler
# 1. 初始化归一化器
scaler = MaxAbsScaler()
# 2. 拟合+转换
X_norm = scaler.fit_transform(X)
# 3. 逆转换
X_original = scaler.inverse_transform(X_norm)
实战案例
用模拟的“股票涨跌幅”数据(范围:-5.2 ~ 7.8):
from sklearn.preprocessing import MaxAbsScaler
import numpy as np
# 1. 模拟数据(2D数组)
X = np.array([[-5.2, 3.1], [2.4, -1.8], [7.8, 4.5], [-3.6, 0.9]]).reshape(-1, 2)
print("原始数据:")
print(X.round(1))
print("各特征最大绝对值:", np.abs(X).max(axis=0))
# 2. 归一化
scaler = MaxAbsScaler()
X_norm = scaler.fit_transform(X)
# 3. 输出结果
print("\n归一化后数据:")
print(X_norm.round(3))
print("归一化后范围:", X_norm.min(), "~", X_norm.max())
输出结果
原始数据:
[[-5.2 3.1]
[ 2.4 -1.8]
[ 7.8 4.5]
[-3.6 0.9]]
各特征最大绝对值: [7.8 4.5]
归一化后数据:
[[-0.667 0.689]
[ 0.308 -0.4 ]
[ 1. 1. ]
[-0.462 0.2 ]]
归一化后范围: -0.667 ~ 1.0
优缺点
- 优点:不改变数据稀疏性、计算简单、对正负值友好。
- 缺点:对异常值敏感(极端值会导致其他数据被过度压缩)。
2.3 小数定标归一化(Decimal Scaling Normalization)
原理
通过移动小数点位置,将特征值缩放至 [-1, 1] 区间。核心是找到特征绝对值的最大值,确定其位数kkk,然后将所有数据除以10k10^k10k。
核心公式:Xnorm=X10kX_{\text{norm}} = \frac{X}{10^k}Xnorm=10kX
其中,k=⌈log10(∣Xmax∣)⌉k = \lceil \log_{10}(|X_{\text{max}}|) \rceilk=⌈log10(∣Xmax∣)⌉(向上取整)。
适用场景
- 特征值为整数且范围不极端(如用户ID、订单编号、产品销量)。
- 希望保留数据原始分布趋势,仅通过“缩小小数点”简化尺度。
语法格式(手动实现,sklearn无现成API)
import numpy as np
def decimal_scaling(X):
# 1. 计算每个特征的最大绝对值
max_abs = np.abs(X).max(axis=0)
# 2. 计算k(最大绝对值的位数,向上取整)
k = np.ceil(np.log10(max_abs + 1e-8)) # +1e-8避免max_abs=0
# 3. 归一化
X_norm = X / (10 ** k)
return X_norm, k
实战案例
用“产品销量”数据(范围:12 ~ 6789):
import numpy as np
# 1. 模拟数据
X = np.array([[123], [45], [6789], [12], [987]]).reshape(-1, 1)
print("原始数据:", X.flatten())
# 2. 小数定标归一化
X_norm, k = decimal_scaling(X)
print(f"\n最大绝对值:{np.abs(X).max()},k={int(k)}")
print("归一化后数据:", X_norm.flatten().round(4))
输出结果
原始数据: [ 123 45 6789 12 987]
最大绝对值:6789.0,k=4
归一化后数据: [0.0123 0.0045 0.6789 0.0012 0.0987]
优缺点
- 优点:计算简单、不改变数据分布、无参数依赖。
- 缺点:仅适用于整数特征、对极端值(如1000000)缩放效果差。
2.4 L1归一化(L1 Normalization / 曼哈顿归一化)
原理
对每行数据(样本)进行归一化,使每行的L1范数(绝对值之和)= 1。
核心公式(对第iii个样本):Xnorm(i,j)=X(i,j)∑j=1m∣X(i,j)∣X_{\text{norm}}(i,j) = \frac{X(i,j)}{\sum_{j=1}^m |X(i,j)|}Xnorm(i,j)=∑j=1m∣X(i,j)∣X(i,j)
其中,mmm是特征数,∑j=1m∣X(i,j)∣\sum_{j=1}^m |X(i,j)|∑j=1m∣X(i,j)∣ 是第iii个样本的L1范数。
适用场景
- 稀疏数据(如文本分类、推荐系统):归一化后会增强数据稀疏性(小值更接近0)。
- 希望突出样本中“占比大”的特征(如TF-IDF中高频词的权重)。
语法格式(sklearn)
from sklearn.preprocessing import Normalizer
# 1. 初始化归一化器(指定norm='l1')
scaler = Normalizer(norm='l1')
# 2. 转换(无需拟合,因基于每行自身的范数)
X_norm = scaler.transform(X) # 注意:Normalizer默认对行归一化
实战案例
用“用户行为特征”数据(2个样本,3个特征):
from sklearn.preprocessing import Normalizer
import numpy as np
# 1. 模拟数据(2个样本,3个特征)
X = np.array([[3, 4, 0], [1, -2, 3]])
print("原始数据:")
print(X)
# 2. L1归一化
scaler = Normalizer(norm='l1')
X_norm = scaler.transform(X)
# 3. 验证:每行绝对值之和=1
l1_norms = np.sum(np.abs(X_norm), axis=1)
print("\nL1归一化后数据:")
print(X_norm.round(3))
print("每行L1范数:", l1_norms.round(3))
输出结果
原始数据:
[[ 3 4 0]
[ 1 -2 3]]
L1归一化后数据:
[[ 0.375 0.5 0. ]
[ 0.167 -0.333 0.5 ]]
每行L1范数: [1. 1.]
优缺点
- 优点:增强数据稀疏性、对异常值鲁棒性中等。
- 缺点:仅对样本行归一化(非特征列)、不适用于需要特征列统一范围的场景。
2.5 L2归一化(L2 Normalization / 欧几里得归一化)
原理
对每行数据(样本)进行归一化,使每行的L2范数(平方和开根号)= 1。
核心公式(对第iii个样本):Xnorm(i,j)=X(i,j)∑j=1mX(i,j)2X_{\text{norm}}(i,j) = \frac{X(i,j)}{\sqrt{\sum_{j=1}^m X(i,j)^2}}Xnorm(i,j)=∑j=1mX(i,j)2X(i,j)
其中,∑j=1mX(i,j)2\sqrt{\sum_{j=1}^m X(i,j)^2}∑j=1mX(i,j)2 是第iii个样本的L2范数。
适用场景
- 分类模型(如SVM、逻辑回归):降低异常值对距离计算的影响。
- 深度学习(如CNN、Transformer):防止梯度爆炸,加速训练。
- 需计算样本间余弦相似度的场景(归一化后余弦相似度=点积)。
语法格式(sklearn)
from sklearn.preprocessing import Normalizer
# 1. 初始化归一化器(指定norm='l2',默认值)
scaler = Normalizer(norm='l2')
# 2. 转换
X_norm = scaler.transform(X)
实战案例
沿用L1案例的用户行为特征数据:
from sklearn.preprocessing import Normalizer
import numpy as np
# 1. 模拟数据
X = np.array([[3, 4, 0], [1, -2, 3]])
print("原始数据:")
print(X)
# 2. L2归一化
scaler = Normalizer(norm='l2') # 等价于scaler = Normalizer()
X_norm = scaler.transform(X)
# 3. 验证:每行L2范数=1
l2_norms = np.sqrt(np.sum(X_norm**2, axis=1))
print("\nL2归一化后数据:")
print(X_norm.round(3))
print("每行L2范数:", l2_norms.round(3))
输出结果
原始数据:
[[ 3 4 0]
[ 1 -2 3]]
L2归一化后数据:
[[ 0.6 0.8 0. ]
[ 0.267 -0.534 0.802]]
每行L2范数: [1. 1.]
优缺点
- 优点:对异常值鲁棒性强、适合距离/相似度计算、广泛用于分类和深度学习。
- 缺点:仅对样本行归一化、不改变特征列的尺度差异(若需列尺度统一,需结合其他方法)。
三、所有归一化方法对比总表
| 方法 | 核心原理 | 输出范围 | 异常值敏感性 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|---|---|---|
| 最小-最大归一化 | (X-X_min)/(X_max-X_min) | [0,1](可自定义) | 高 | 无异常值、模型需固定范围(如神经网络) | 直观、范围明确、计算简单 | 对异常值敏感、依赖数据极值 |
| 最大绝对值归一化 | X / | X_max | [-1,1]或[0,1] | 高 | 正负值特征、稀疏数据(如TF-IDF) | |
| 小数定标归一化 | X / 10^k(k为最大值位数) | [-1,1] | 中 | 整数特征、销量/ID类数据 | 计算简单、无参数依赖 | 仅适用于整数、极端值效果差 |
| L1归一化 | 每行除以L1范数(绝对值之和) | 每行L1范数=1 | 中 | 稀疏数据、文本分类、突出占比特征 | 增强稀疏性、鲁棒性中等 | 仅行归一化、不适用于列尺度统一需求 |
| L2归一化 | 每行除以L2范数(平方和开根号) | 每行L2范数=1 | 低 | 分类模型、深度学习、相似度计算 | 抗异常值、广泛适用、加速训练 | 仅行归一化、计算量略高于L1 |
四、实战注意事项(避坑关键)
1. 归一化时机:训练集 vs 测试集
- 必须用训练集数据拟合归一化器(如计算Min-Max的X_min/X_max),再用同一归一化器转换训练集和测试集。
- 严禁用测试集数据参与拟合!否则会导致“数据泄露”(测试集信息提前被模型知晓)。
# 正确做法
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler
X_train, X_test = train_test_split(X, test_size=0.2, random_state=42)
scaler = MinMaxScaler()
X_train_norm = scaler.fit_transform(X_train) # 仅训练集拟合+转换
X_test_norm = scaler.transform(X_test) # 测试集仅转换
2. 异常值处理
- 对异常值敏感的方法(Min-Max、Max-Abs):先处理异常值(如删除、替换为中位数/均值),再归一化。
- 示例:用IQR法去除异常值后再Min-Max归一化。
3. 模型与归一化的匹配
| 模型类型 | 是否需要归一化 | 推荐方法 |
|---|---|---|
| KNN、SVM、逻辑回归 | 是 | Min-Max、L2归一化 |
| 神经网络、深度学习 | 是 | Min-Max([0,1]或[-1,1]) |
| 决策树、随机森林、XGBoost | 否 | 无需(基于信息增益,与尺度无关) |
| 推荐系统(协同过滤) | 是 | Min-Max、L2归一化 |
| 文本分类(TF-IDF) | 是 | Max-Abs、L1归一化 |
4. 稀疏数据的特殊处理
- 稀疏数据(如文本TF-IDF、高维零值特征):优先选择Max-Abs、L1/L2归一化(不改变零值,保留稀疏性)。
- 避免用Min-Max(中心化会引入非零值,破坏稀疏性)。
五、总结
归一化的核心是“统一特征尺度”,不同方法的选择需结合数据分布、异常值情况、模型类型:
- 若特征无异常值、需固定范围 → 选Min-Max;
- 若特征有正负值、稀疏数据 → 选Max-Abs;
- 若为整数特征、简单缩放 → 选小数定标;
- 若需突出占比、稀疏数据 → 选L1归一化;
- 若需抗异常值、分类/深度学习 → 选L2归一化。
掌握归一化的核心逻辑和实战细节,能显著提升模型的训练效率和预测精度,是机器学习工程师的必备技能!
1652

被折叠的 条评论
为什么被折叠?



