哈喽,大家好~
今儿和大家聊聊数据标准化与归一化的区别与应用场景
数据标准化和归一化是两种常用的预处理技术,目的是让数据更适合后续的算法处理。
标准化
目标:将数据转换成 均值为0、标准差为1 的分布。
本质:数据被拉伸或压缩,使其符合标准正态分布(但不保证正态分布,只保证均值与标准差固定)。
核心公式:
其中:
-
为原始数据; -
是样本均值; -
是样本标准差; -
为标准化后的数据。
推理过程:
-
首先中心化: → 数据的均值移到0; -
再缩放: → 数据的标准差变为1; -
优点:保留数据分布的形状(偏态、峰度),但去除了量纲影响。
归一化
目标:将数据线性映射到固定区间(通常是 [0,1] 或 [-1,1])。
本质:数据被压缩到指定范围,便于不同量纲的数据进行比较或输入模型。
核心公式:
其中:
-
; -
; -
为归一化后的数据,保证 。
推理过程:
-
数据平移: → 让最小值为0; -
数据缩放:除以 → 让最大值为1; -
优点:保持原始数据的比例关系,但会压缩异常值到边界。
两者的核心区别
|
|
|
|
|---|---|---|
|
|
||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
数学推理
假设有数据集:
1. 标准化
标准化后:
均值约0,标准差约1
2. 归一化到 [0,1]
数据线性映射到 [0,1],比例保持不变
总的来说,标准化 = 数据中心化 + 单位方差化 → 保留分布形状,适合统计建模。
归一化 = 数据线性压缩 → 保证固定范围,适合神经网络、梯度优化。
完整案例
案例中,我们生成一个二维虚拟数据集,包含两列特征,一列大范围,一列小范围,并加入异常值。
之后,对数据进行 标准化 和 归一化。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.preprocessing import StandardScaler, MinMaxScaler
# 设置随机种子
np.random.seed(42)
# 生成虚拟数据
n_samples = 2000
X1 = np.random.normal(loc=50, scale=10, size=n_samples) # 大范围特征
X2 = np.random.normal(loc=5, scale=2, size=n_samples) # 小范围特征
# 加入一些异常值
X1[:5] = [150, 160, 140, 155, 145]
X2[:5] = [-5, -3, -4, -6, -2]
data = np.vstack([X1, X2]).T
df = pd.DataFrame(data, columns=['Feature1', 'Feature2'])
# 原始数据统计
print("原始数据统计:")
print(df.describe())
# 1. 标准化
scaler_std = StandardScaler()
df_std = scaler_std.fit_transform(df)
# 2. 归一化
scaler_mm = MinMaxScaler()
df_mm = scaler_mm.fit_transform(df)
# 可视化
fig, axs = plt.subplots(2, 2, figsize=(16,12))
# 图1: 原始数据散点图
axs[0,0].scatter(df['Feature1'], df['Feature2'], c=df['Feature2'], cmap='viridis', s=80)
axs[0,0].set_title("原始数据分布", fontsize=16)
axs[0,0].set_xlabel("Feature1")
axs[0,0].set_ylabel("Feature2")
# 图2: 标准化数据散点图
axs[0,1].scatter(df_std[:,0], df_std[:,1], c=df_std[:,1], cmap='plasma', s=80)
axs[0,1].set_title("标准化后数据分布", fontsize=16)
axs[0,1].set_xlabel("Feature1 (标准化)")
axs[0,1].set_ylabel("Feature2 (标准化)")
# 图3: 归一化数据散点图
axs[1,0].scatter(df_mm[:,0], df_mm[:,1], c=df_mm[:,1], cmap='cool', s=80)
axs[1,0].set_title("归一化后数据分布", fontsize=16)
axs[1,0].set_xlabel("Feature1 (归一化)")
axs[1,0].set_ylabel("Feature2 (归一化)")
# 图4: 对比特征值变化 (条形图)
width = 0.35
indices = np.arange(5)
axs[1,1].bar(indices - width/2, df.iloc[:5,0], width=width, label='原Feature1', color='skyblue')
axs[1,1].bar(indices + width/2, df_std[:5,0], width=width, label='标准化Feature1', color='orange')
axs[1,1].set_title("原始 vs 标准化前5个样本Feature1", fontsize=16)
axs[1,1].legend()
plt.tight_layout()
plt.show()
-
原始数据分布:显示两列特征的原始散点分布,可见异常值对Feature1影响很大。
-
标准化后数据分布:均值中心化,标准差=1,异常值仍存在,但比例被压缩,数据更适合距离/相似度计算(如KNN、SVM)。
-
归一化后数据分布:所有数据被压缩到 [0,1] 区间,异常值会拉伸整个缩放区间,压缩大部分正常值,适合神经网络输入(避免梯度消失/爆炸)
-
原始 vs 标准化前5个样本条形图:可清楚看到异常值标准化后的变化,强调标准化“中心化 + 缩放”的作用。
最后

