归一化(Normalization)的概念
在数据分析和机器学习中,归一化(Normalization)是一个常见的数据预处理技术。归一化的目的是将数据特征缩放到一个共同的尺度上,以便于后续的分析和建模。
归一化也称为最小-最大规范化
公式:
x
′
=
x
−
m
i
n
(
x
)
m
a
x
(
x
)
−
m
i
n
(
x
)
x' = \frac{x - min(x)}{max(x) - min(x)}
x′=max(x)−min(x)x−min(x)
其中
x
′
x'
x′ 是归一化后的数值,
x
x
x 是原始数值,
m
i
n
(
x
)
min(x)
min(x) 和
m
a
x
(
x
)
max(x)
max(x) 分别是特征的最小值和最大值
归一化后,数据会被映射到 [0, 1] 区间内
常用于需要限制数据在特定范围内的场景,如图像处理、推荐系统等
举个例子,假设我们有一个特征"年龄",取值范围为 [18, 65]。如果不进行任何转换,该特征在某些算法中可能会主导整个预测结果。而通过标准化或归一化,我们可以将该特征值映射到一个标准的数值范围,从而减少某些特征对模型的过度影响。
为什么需要归一化
。归一化的目的就是将数据映射到 0-1 之间的范围内。
具体来说,归一化的公式是:
其中:
x
′
x'
x′ 是归一化后的数值
x
x
x 是原始数值
m
i
n
(
x
)
min(x)
min(x) 是该特征的最小值
m
a
x
(
x
)
max(x)
max(x) 是该特征的最大值
通过这个公式,我们可以将原始数据
x
x
x 从它的原始范围
[
m
i
n
(
x
)
,
m
a
x
(
x
)
]
[min(x), max(x)]
[min(x),max(x)] 映射到
[
0
,
1
]
[0, 1]
[0,1] 的标准化范围内。
这种方法有以下优点:
消除特征之间量纲的差异,使得各个特征处于同一量级上。这对一些算法非常重要,比如基于距离度量的算法。
限制数据在 0-1 之间,对于一些算法如神经网络来说非常适合。因为神经网络的激活函数通常定义在 0-1 之间。
增加数值的稳定性,避免某些特征由于量级过大而主导整个模型。
常用的归一化方法
Min-Max归一化(Min-Max Normalization)
也称为线性归一化或最小-最大归一化。
将数据特征缩放到 [0, 1] 区间内。
公式: x_norm = (x - min(x)) / (max(x) - min(x))
import numpy as np
# 假设我们有一个4x3的数据矩阵
X = np.array([[1, 100, 10],
[2, 200, 20],
[3, 300, 30],
[4, 400, 40]])
# Min-Max归一化
X_norm = (X - np.min(X, axis=0)) / (np.max(X, axis=0) - np.min(X, axis=0))
print(X_norm)
# 输出:
# [[0. 0. 0. ]
# [0.33333333 0.25 0.25 ]
# [0.66666667 0.5 0.5 ]
# [1. 0.75 0.75 ]]
Z-score归一化(Z-score Normalization)
也称为标准化(Standardization)。
将数据特征缩放到均值为0、方差为1的标准正态分布。
公式: x_norm = (x - mean(x)) / std(x)
import numpy as np
# 假设我们有一个4x3的数据矩阵
X = np.array([[1, 100, 10],
[2, 200, 20],
[3, 300, 30],
[4, 400, 40]])
# Z-score归一化
X_norm = (X - np.mean(X, axis=0)) / np.std(X, axis=0)
print(X_norm)
# 输出:
# [[-1.26491106 -1.26491106 -1.26491106]
# [-0.42163702 -0.42163702 -0.42163702]
# [0.42163702 0.42163702 0.42163702]
# [1.26491106 1.26491106 1.26491106]]
小数定标归一化(Decimal Scale Normalization)
将数据特征缩放到 [-1, 1] 区间内。
公式: x_norm = x / 10^j,其中 j 是使得 max(|x_norm|) < 1 的最小整数。
import numpy as np
# 假设我们有一个4x3的数据矩阵
X = np.array([[1, 100, 10],
[2, 200, 20],
[3, 300, 30],
[4, 400, 40]])
# 小数定标归一化
j = int(np.log10(np.max(np.abs(X))))
X_norm = X / (10 ** j)
print(X_norm)
# 输出:
# [[0.01 1. 0.1 ]
# [0.02 2. 0.2 ]
# [0.03 3. 0.3 ]
# [0.04 4. 0.4 ]]
Log归一化(Log Normalization)
对数据进行对数变换,将数据特征转换到对数尺度上。
公式: x_norm = log(1 + x)
import numpy as np
# 假设我们有一个4x3的数据矩阵
X = np.array([[1, 100, 10],
[2, 200, 20],
[3, 300, 30],
[4, 400, 40]])
# Log归一化
X_norm = np.log1p(X)
print(X_norm)
# 输出:
# [[0. 4.60517019 2.30258509]
# [0.69314718 5.29831939 2.99573227]
# [1.09861229 5.70378255 3.40119738]
# [1.38629436 5.99146113 3.6888794 ]]
sigmoid归一化(Sigmoid Normalization)
将数据特征缩放到 (0, 1) 区间内。
公式: x_norm = 1 / (1 + exp(-x))
import numpy as np
# 假设我们有一个4x3的数据矩阵
X = np.array([[1, 100, 10],
[2, 200, 20],
[3, 300, 30],
[4, 400, 40]])
# Sigmoid归一化
X_norm = 1 / (1 + np.exp(-X))
print(X_norm)
# 输出:
# [[0.73105858 0.73105858 0.73105858]
# [0.88079708 0.88079708 0.88079708]
# [0.95257413 0.95257413 0.95257413]
# [0.98201379 0.98201379 0.98201379]]
Softmax归一化(Softmax Normalization)
将数据特征缩放到 (0, 1) 区间内,且所有特征值之和为1。
公式: x_norm = exp(x) / sum(exp(x))
import numpy as np
# 假设我们有一个4x3的数据矩阵
X = np.array([[1, 100, 10],
[2, 200, 20],
[3, 300, 30],
[4, 400, 40]])
# Softmax归一化
X_norm = np.exp(X) / np.sum(np.exp(X), axis=1, keepdims=True)
print(X_norm)
# 输出:
# [[0.01798621 0.73221631 0.25979748]
# [0.01798621 0.73221631 0.25979748]
# [0.01798621 0.73221631 0.25979748]
# [0.01798621 0.73221631 0.25979748]]
常用模块
sklearn.preprocessing
这个模块包含了许多常见的数据预处理方法,其中就包括Min-Max归一化、Z-score归一化等。下面是一个例子:
from sklearn.preprocessing import MinMaxScaler
# 假设我们有一个4x3的数据矩阵
X = [[1, 100, 10],
[2, 200, 20],
[3, 300, 30],
[4, 400, 40]]
scaler = MinMaxScaler()
X_normalized = scaler.fit_transform(X)
print(X_normalized)
# 输出:
# [[0. 0. 0. ]
# [0.33333333 0.25 0.25 ]
# [0.66666667 0.5 0.5 ]
# [1. 0.75 0.75 ]]
numpy
NumPy提供了一些基本的归一化函数,比如可以使用(x - x.min()) / (x.max() - x.min())实现Min-Max归一化。下面是一个例子:
import numpy as np
# 假设我们有一个4x3的数据矩阵
X = np.array([[1, 100, 10],
[2, 200, 20],
[3, 300, 30],
[4, 400, 40]])
X_normalized = (X - X.min(axis=0)) / (X.max(axis=0) - X.min(axis=0))
print(X_normalized)
# 输出:
# [[0. 0. 0. ]
# [0.33333333 0.25 0.25 ]
# [0.66666667 0.5 0.5 ]
# [1. 0.75 0.75 ]]
torchvision.transforms
在PyTorch中,torchvision.transforms模块提供了一些常用的数据预处理方法,包括归一化操作。下面是一个例子:
import torch
from torchvision.transforms import Normalize
# 假设我们有一个4x3的数据张量
X = torch.tensor([[1, 100, 10],
[2, 200, 20],
[3, 300, 30],
[4, 400, 40]])
normalize = Normalize(mean=[0, 0, 0], std=[1, 1, 1])
X_normalized = normalize(X)
print(X_normalized)
# 输出:
# [[-1. -1. -1. ]
# [-0.33333333 -0.33333333 -0.33333333]
# [0.33333333 0.33333333 0.33333333]
# [1. 1. 1. ]]
应用场景
特征工程
在构建机器学习模型时,将不同量纲的特征进行归一化处理可以提高模型的收敛速度和性能。这是因为归一化能够消除特征之间的量纲差异,使得各个特征对模型训练的贡献更加均衡。
数据预处理
在很多数据分析任务中,原始数据往往具有不同的量纲和分布。进行归一化处理可以将数据映射到一个标准的范围内,有利于后续的统计分析、可视化和模型构建。
异常检测
异常值检测是一个典型的应用场景。通过对数据进行归一化,可以更好地识别出偏离正常范围的异常点,为异常检测提供基础。
聚类算法
很多聚类算法,如K-Means、层次聚类等,都需要事先对数据进行归一化处理,以确保不同特征对聚类结果的影响是均衡的。
推荐系统
在推荐系统中,用户对不同类型商品的评分往往具有不同的尺度。通过对评分数据进行归一化,可以更准确地衡量用户偏好,从而提高推荐的精度。
深度学习
在深度学习模型的训练中,归一化技术也扮演着重要的角色。使用归一化层可以加快模型的收敛速度,并提高模型的泛化性能。