统计数学---数据归一化(Data Normalization)
一、归一化定义
1、定义
数据归一化 是一种数据预处理技术,其核心目标是将数据中不同特征(列)的数值范围缩放至一个统一的特定区间内(通常是 [0, 1] 或 [-1, 1]),或者将数据转换为均值为0、标准差为1的分布。
2、为什么需要这样做?
因为现实世界的数据中,不同的特征往往具有完全不同的量纲 和尺度。
举个例子:
假设我们有一个数据集,包含两个特征来预测一个人的信用评分:
收入:范围可能是 [20000, 200000] (元)
年龄:范围可能是 [18, 80] (岁)
这两个特征的数值范围差异巨大。收入的值远大于年龄的值。
3、为什么需要数据归一化?(核心原因)
如果不进行归一化,直接将数据送入机器学习模型(尤其是那些基于距离计算或梯度下降的模型),会产生一系列问题:
-
加快梯度下降的收敛速度
- 这是最重要、最常见的原因。对于使用梯度下降法求解最优解的模型(如线性回归、逻辑回归、神经网络等),特征的尺度差异会导致损失函数的等高线图呈“扁长的椭圆形”。
- 梯度下降过程会沿着最陡峭的方向反复震荡,需要很多次迭代才能收敛到最小值。
- 归一化后,等高线图更接近“圆形”,梯度方向更直接地指向最小值,能大大加快收敛速度。
- 图示理解: 想象一个又窄又长的山谷,归一化就是把这个山谷变得更“圆”,让小球(梯度)能更直接地滚到谷底。
-
保证距离度量的公平性
- 对于基于距离计算的模型(如K近邻、K均值聚类、支持向量机等),尺度大的特征会完全主导距离的计算结果。
- 在上面的例子中,收入(数值大)对距离的影响会远远超过年龄(数值小),这相当于我们默认“收入比年龄重要得多”,但这可能并非事实。归一化让所有特征在距离计算中拥有同等重要的地位。
-
提升模型精度
由于上述两点,归一化通常能直接提升模型的整体性能和稳定性。
二、数学公式
1、Min-Max 归一化(最常用)
- 公式: Xnorm=X−XminXmax−XminX_{norm} = \frac{X - X_{min}}{X_{max} - X_{min}}Xnorm=Xmax−XminX−Xmin
- 作用: 将原始数据线性地映射到 [0, 1] 区间。如果需要映射到其他区间 [a, b],公式为:Xnorm=a+(X−Xmin)(b−a)Xmax−XminX_{norm} = a + \frac{(X - X_{min})(b-a)}{X_{max} - X_{min}}Xnorm=a+Xmax−Xmin(X−Xmin)(b−a)。
- 优点: 简单易懂,保留了原始数据的分布形状。
- 缺点: 对异常值非常敏感。如果数据中存在极大或极小的异常值,会导致 XminX_{min}Xmin或 XmaxX_{max}Xmax异常,从而使大部分正常数据被压缩到一个非常窄的范围内。
- 适用场景: 适用于数据分布比较均匀、边界相对清晰的情况。如图像处理中,将像素值(0-255)归一化到 [0, 1]。
import onnxruntime as ort
import numpy as np
import scipy.special
from PIL import Image# 预处理图像
def preprocess_image(image, resize_size=256, crop_size=224, mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]):image = image.resize((resize_size, resize_size), Image.BILINEAR) # 将原照片缩放到 256*256 w, h = image.size # 获取照片大小left = (w - crop_size) / 2top = (h - crop_size) / 2image = image.crop((left, top, left + crop_size, top + crop_size)) # 从照片中间裁剪一个224*224的图片image = np.array(image).astype(np.float32)# 将image转换成narray,并将元素类型转换成float32类型image = image / 255.0 # 图像归一化image = (image - mean) / std # 标准化image = np.transpose(image, (2, 0, 1))image = image.reshape((1,) + image.shape)return image
三、MinMaxScaler(极差归一化)
1、语法
from sklearn.preprocessing import MinMaxScalerclass MinMaxScaler(_OneToOneFeatureMixin, TransformerMixin, BaseEstimator):def __init__(self, feature_range=(0, 1), *, copy=True, clip=False):self.feature_range = feature_rangeself.copy = copyself.clip = clip
2、参数详解
- feature_range: tuple (min, max), 默认=(0, 1)
- 作用: 定义数据缩放的目标范围
- 类型: 包含两个数字的元组 (min, max)
- 要求: min 必须小于 max
# 缩放到不同范围
scaler1 = MinMaxScaler() # [0, 1]
scaler2 = MinMaxScaler(feature_range=(-1, 1)) # [-1, 1]
scaler3 = MinMaxScaler(feature_range=(0, 100)) # [0, 100] 百分比形式
-
copy: bool, 默认=True
- 作用: 控制是否创建数据的副本
- True: 创建数据副本,不修改原始数据(推荐)
- False: 原地修改数据,可能改变原始数组
- 使用建议: 除非内存非常紧张,否则保持默认 True
-
clip: bool, 默认=False
- 作用: 控制是否将转换后的值限制在 feature_range 内
- False: 转换后的值可能略微超出目标范围(由于浮点精度)
- True: 严格限制转换值在 [min, max] 范围内
- 使用场景: 当需要严格保证输出范围时使用
3、方法详解
MinMaxScaler 的主要方法是一个典型的工作流程:拟合(计算统计量)-> 转换 -> (可选)逆转换。
其中X代表特征矩阵,是一个二维数组
| 方法 | 主要参数 | 返回值与作用 | 常用场景 |
|---|---|---|---|
fit(X, y=None) | X: 训练数据 | 返回 self(MinMaxScaler对象本身)。核心作用是计算并保存训练数据 X 每个特征的最大值(data_min_ )、最小值(data_min_ )和每个特征的数据范围 (data_max_ - data_min_)(data_range_)。 | 初始化,从训练数据学习归一化化参数。 |
transform(X) | X: 待转换的数据(类数组) | 返回与 X 形状相同的NumPy数组或稀疏矩阵。核心作用是利用 fit 阶段学到的 data_min_ 和 data_min_ 、 data_range_ ,对输入数据 X 进行归一化转换:(X - data_min_ ) / data_range_ 。 | 对训练集、测试集或新数据进行归一化。关键:对测试集应使用从训练集学到的相同scaler进行 transform,而非重新 fit 。 |
fit_transform(X, y=None) | X: 训练数据 | 返回转换后的数据。核心作用相当于先调用 fit(X),再调用 transform(X)。这是一个便捷的方法 。 | 一步完成对训练数据的拟合和转换。 |
inverse_transform(X) | X: 已被归一化过的数据 | 返回与输入 X 形状相同的数组。核心作用是执行归一化的逆过程,将数据尽可能还原到原始尺度:X * scale_ + mean_ 。 | 将归一化后的预测结果或数据还原回原始尺度,便于解释 。 |
partial_fit(X, y=None) | X: 一批数据 | 返回 self。核心作用是在线计算最大值(data_min_ )、最小值(data_min_ ),适用于数据量过大无法一次性载入内存时进行增量学习 。 | 大型数据集的批量归一化。 |
4、属性详解
在调用 fit 方法后,缩放器对象会获得以下重要属性,这些属性存储了从数据中学到的信息:
| 属性名 | 形状 | 说明 |
|---|---|---|
**data_min_** | Series | 拟合数据中,每个特征的观察到的最小值。 |
**data_max_** | Series | 拟合数据中,每个特征的观察到的最大值。 |
**data_range_** | Series | 拟合数据中,每个特征的范围(data_max_ - data_min_)。 |
n_features_in_ | int | 拟合过程中看到的特征数量。 |
