数值标准化(Z-score)
使用训练集均值和标准差把不同量纲的数值特征转换到均值约为 0、标准差约为 1 的尺度。
交互图形
从原始值到 Z-score
拖动原始值和训练集统计量,观察同一个 如何映射到标准差坐标。这里的 与 代表已经由训练集拟合完成的参数。
滑动条改变什么
原始值改变样本位置;均值移动中心;标准差改变统一尺子的刻度大小。
为什么只能用训练参数
若验证或测试值参与均值、标准差计算,评价数据的分布信息会泄漏到预处理过程。
如何理解结果
正值表示高于训练均值,负值表示低于训练均值,绝对值表示相距多少个训练标准差。
学习前需要掌握
背景与问题
真实数据的特征量纲经常不同。房屋面积可能是数百平方米,卧室数量只有个位数;Wine 数据中的 hue 约为 0~2,而 proline 可达到数百至上千。
如果直接计算欧氏距离,大尺度特征会主导 KNN、K-Means 等算法;如果直接做梯度下降,损失等高线会变得狭长,不同参数方向的梯度尺度悬殊,更新容易震荡或迫使学习率非常小。
L1/L2 正则化直接惩罚权重大小。若特征单位差异很大,相同预测贡献需要完全不同的权重,正则化会因为单位而不公平地压制某些特征。
概念定义
数值标准化是对每一列数值特征分别做中心化与尺度缩放:先减去该特征在训练集中的均值,再除以训练集标准差。
标准化后的数值不再保留原单位,而表示“当前值距离训练集均值多少个标准差”。例如 z=1.5 表示该值比训练集均值高 1.5 个标准差。
直观理解
可以把标准化理解为给每个特征换一把统一的尺子。原来“平方米”“万元”“次数”无法直接比较,转换后都用“距离自己的平均水平几个标准差”来描述。
它不会让所有特征拥有相同分布,也不会自动消除偏态和异常值;它只统一中心与典型波动尺度。
核心原理
对第 j 个特征,只使用训练集的 m 个样本计算均值 μⱼ 和总体标准差 σⱼ。之后训练集、验证集、测试集以及未来线上样本都复用同一组 μⱼ、σⱼ。
训练阶段的 fit 学习均值和标准差;transform 只应用已经学到的参数。验证集和测试集绝不能再次 fit,否则评价数据的整体分布会进入模型流程,形成数据泄漏。
标准化通常适用于 KNN、K-Means、SVM、PCA、线性/逻辑回归及其正则化版本、神经网络。决策树、随机森林和梯度提升树主要比较单特征阈值,线性缩放不改变样本相对顺序,因此通常不要求标准化。
数学表达
训练集均值
对训练集中第 j 列的 m 个数值求平均,描述该特征的中心位置。
变量含义
m训练集样本数量。验证集和测试集样本不参与统计。j特征列编号,每一列独立计算自己的参数。xⱼ⁽ⁱ⁾第 i 个样本在第 j 个特征上的原始值。μⱼ第 j 个特征在训练集中的均值。σⱼ第 j 个特征在训练集中的总体标准差。zⱼ⁽ⁱ⁾标准化后的数值,表示相对训练均值的标准差距离。
计算步骤
- 1均值 μ=(50+60+70)/3=60。
- 2平方偏差分别为 (50-60)²=100、(60-60)²=0、(70-60)²=100。
- 3总体方差为 (100+0+100)/3=66.667,标准差 σ≈8.165。
- 4训练集 Z-score 约为 [-1.225, 0, 1.225]。
代码对应位置
示例 1使用 NumPy 手工实现训练集标准化:直接观察均值、标准差、广播、验证集复用参数和逆变换之间的关系。示例 2StandardScaler 与 Pipeline 的正确用法:把标准化和逻辑回归放进同一条防泄漏流程,并展示训练、验证、测试的职责。
训练集总体标准差
描述训练集第 j 个特征围绕均值的典型波动大小。StandardScaler 使用总体方差约定。
变量含义
m训练集样本数量。验证集和测试集样本不参与统计。j特征列编号,每一列独立计算自己的参数。xⱼ⁽ⁱ⁾第 i 个样本在第 j 个特征上的原始值。μⱼ第 j 个特征在训练集中的均值。σⱼ第 j 个特征在训练集中的总体标准差。zⱼ⁽ⁱ⁾标准化后的数值,表示相对训练均值的标准差距离。
计算步骤
- 1均值 μ=(50+60+70)/3=60。
- 2平方偏差分别为 (50-60)²=100、(60-60)²=0、(70-60)²=100。
- 3总体方差为 (100+0+100)/3=66.667,标准差 σ≈8.165。
- 4训练集 Z-score 约为 [-1.225, 0, 1.225]。
代码对应位置
示例 1使用 NumPy 手工实现训练集标准化:直接观察均值、标准差、广播、验证集复用参数和逆变换之间的关系。示例 2StandardScaler 与 Pipeline 的正确用法:把标准化和逻辑回归放进同一条防泄漏流程,并展示训练、验证、测试的职责。
Z-score 变换
先中心化,再按标准差缩放。若 σⱼ=0,说明该列是常量特征,需要删除或单独处理。
变量含义
m训练集样本数量。验证集和测试集样本不参与统计。j特征列编号,每一列独立计算自己的参数。xⱼ⁽ⁱ⁾第 i 个样本在第 j 个特征上的原始值。μⱼ第 j 个特征在训练集中的均值。σⱼ第 j 个特征在训练集中的总体标准差。zⱼ⁽ⁱ⁾标准化后的数值,表示相对训练均值的标准差距离。
计算步骤
- 1均值 μ=(50+60+70)/3=60。
- 2平方偏差分别为 (50-60)²=100、(60-60)²=0、(70-60)²=100。
- 3总体方差为 (100+0+100)/3=66.667,标准差 σ≈8.165。
- 4训练集 Z-score 约为 [-1.225, 0, 1.225]。
代码对应位置
示例 1使用 NumPy 手工实现训练集标准化:直接观察均值、标准差、广播、验证集复用参数和逆变换之间的关系。示例 2StandardScaler 与 Pipeline 的正确用法:把标准化和逻辑回归放进同一条防泄漏流程,并展示训练、验证、测试的职责。
逆变换
需要回到原始单位时,可以用保存的均值和标准差还原。
变量含义
m训练集样本数量。验证集和测试集样本不参与统计。j特征列编号,每一列独立计算自己的参数。xⱼ⁽ⁱ⁾第 i 个样本在第 j 个特征上的原始值。μⱼ第 j 个特征在训练集中的均值。σⱼ第 j 个特征在训练集中的总体标准差。zⱼ⁽ⁱ⁾标准化后的数值,表示相对训练均值的标准差距离。
计算步骤
- 1均值 μ=(50+60+70)/3=60。
- 2平方偏差分别为 (50-60)²=100、(60-60)²=0、(70-60)²=100。
- 3总体方差为 (100+0+100)/3=66.667,标准差 σ≈8.165。
- 4训练集 Z-score 约为 [-1.225, 0, 1.225]。
代码对应位置
示例 1使用 NumPy 手工实现训练集标准化:直接观察均值、标准差、广播、验证集复用参数和逆变换之间的关系。示例 2StandardScaler 与 Pipeline 的正确用法:把标准化和逻辑回归放进同一条防泄漏流程,并展示训练、验证、测试的职责。
变量解释
| 变量 | 含义 |
|---|---|
m | 训练集样本数量。验证集和测试集样本不参与统计。 |
j | 特征列编号,每一列独立计算自己的参数。 |
xⱼ⁽ⁱ⁾ | 第 i 个样本在第 j 个特征上的原始值。 |
μⱼ | 第 j 个特征在训练集中的均值。 |
σⱼ | 第 j 个特征在训练集中的总体标准差。 |
zⱼ⁽ⁱ⁾ | 标准化后的数值,表示相对训练均值的标准差距离。 |
完整数值示例
对训练特征 [50, 60, 70] 手工标准化
已知条件
- 训练集某特征:50、60、70
- 验证集同一特征:80
- 使用总体标准差,即分母为 m=3
- 1
均值 μ=(50+60+70)/3=60。
- 2
平方偏差分别为 (50-60)²=100、(60-60)²=0、(70-60)²=100。
- 3
总体方差为 (100+0+100)/3=66.667,标准差 σ≈8.165。
- 4
训练集 Z-score 约为 [-1.225, 0, 1.225]。
- 5
验证值 80 必须复用训练参数:z=(80-60)/8.165≈2.449,不能用验证集重新计算均值。
训练列从原单位 [50,60,70] 变为无单位的 [-1.225,0,1.225],均值约 0、总体标准差约 1。验证值 80 表示比训练均值高约 2.449 个标准差。
处理前后对比
- 标准化前:数值保留原单位,中心在 60,尺度约 8.165。
- 标准化后:中心约为 0,尺度约为 1,大小顺序不变。
- 标准化不会限制范围;80 被转换为 2.449,完全可以大于 1。
计算与实现步骤
- 1
先按真实使用场景划分训练集、验证集和测试集。
- 2
只在训练集上检查缺失值和常量列。缺失值应先按 Pipeline 中约定方式处理。
- 3
对训练集每一列计算并保存均值与标准差,即执行 scaler.fit(X_train)。
- 4
使用保存的参数转换训练集,即 scaler.transform(X_train)。
- 5
对验证集、测试集和未来数据只调用 transform,不再重新拟合。
- 6
把 StandardScaler 与需要缩放的模型放在同一个 Pipeline 中,使每个交叉验证训练折独立拟合参数。
- 7
记录特征顺序和列名;部署时必须以相同结构输入。
代码实现
示例 1
使用 NumPy 手工实现训练集标准化
example_01.py用途:直接观察均值、标准差、广播、验证集复用参数和逆变换之间的关系。
import numpy as np
X_train = np.array([[50.0], [60.0], [70.0]])
X_valid = np.array([[80.0]])
# 只能使用训练集计算参数;axis=0 表示逐列统计。
mean = X_train.mean(axis=0)
std = X_train.std(axis=0)
if np.any(std == 0):
raise ValueError("存在标准差为 0 的常量特征")
X_train_scaled = (X_train - mean) / std
X_valid_scaled = (X_valid - mean) / std
X_train_restored = X_train_scaled * std + mean
print("mean:", mean.round(3))
print("std:", std.round(3))
print("train scaled:", X_train_scaled.ravel().round(3))
print("valid scaled:", X_valid_scaled.ravel().round(3))
print("restored:", X_train_restored.ravel().round(3))代码解析
解析始终位于完整代码下方,并按实际代码段逐项对应。
输入数据与任务
直接观察均值、标准差、广播、验证集复用参数和逆变换之间的关系。
X_train- 训练特征,只允许它参与预处理器和模型的 fit。
mean- 训练特征逐列均值。
std- 训练特征逐列标准差。
Step 1 · 1–1 行
导入当前步骤需要的数值计算、预处理、模型或评价工具。依赖集中写在代码开头,便于复现。
import numpy as npStep 2 · 3–4 行
验证集使用训练参数,因此它相对训练分布的位置得到真实保留。
X_train = np.array([[50.0], [60.0], [70.0]])
X_valid = np.array([[80.0]])Step 3 · 6–8 行
只从训练数据逐列计算均值与标准差,对应标准化公式中的 μ 和 σ。
# 只能使用训练集计算参数;axis=0 表示逐列统计。
mean = X_train.mean(axis=0)
std = X_train.std(axis=0)Step 4 · 10–11 行
只从训练数据逐列计算均值与标准差,对应标准化公式中的 μ 和 σ。
if np.any(std == 0):
raise ValueError("存在标准差为 0 的常量特征")Step 5 · 13–15 行
执行当前代码段,并把得到的状态传给下一步。
X_train_scaled = (X_train - mean) / std
X_valid_scaled = (X_valid - mean) / std
X_train_restored = X_train_scaled * std + meanStep 6 · 17–21 行
输出中间参数、形状或最终指标,用于核对代码是否符合预期。
print("mean:", mean.round(3))
print("std:", std.round(3))
print("train scaled:", X_train_scaled.ravel().round(3))
print("valid scaled:", X_valid_scaled.ravel().round(3))
print("restored:", X_train_restored.ravel().round(3))代码与数学原理
减去训练均值并除以训练标准差,对应代码中的 mean/std 或 StandardScaler。
预期输出或运行结果
mean: [60.];std: [8.165];train scaled: [-1.225 0. 1.225];valid scaled: [2.449];restored: [50. 60. 70.]
常见错误 · 10 条
- 不要在测试集上调用 fit 或 fit_transform;测试集只能复用训练参数。
- 先对完整数据 fit_transform,再划分训练集和测试集。
- 对验证集或测试集再次调用 fit 或 fit_transform。
- 认为标准化会把数据限制到 [0,1];这是 Min-Max 缩放的典型目标,不是 Z-score。
- 忽略标准差为 0 的常量列,导致除零。
- 存在强异常值时仍机械使用均值和标准差;异常值会显著改变两者。
- 对 One-Hot 列、类别编号或树模型不加区分地全部标准化。
- 训练与线上输入列顺序不一致,导致把某列的均值和标准差应用到另一列。
- 认为标准化可以修复偏态、错误单位、缺失值或数据泄漏;它不能替代数据质量处理。
- 确认样本轴、特征轴以及 X 与 y 的第一维完全对应。
示例 2
StandardScaler 与 Pipeline 的正确用法
example_02.py用途:把标准化和逻辑回归放进同一条防泄漏流程,并展示训练、验证、测试的职责。
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42, stratify=y
)
model = make_pipeline(
StandardScaler(),
LogisticRegression(max_iter=2000),
)
# Pipeline 内部:scaler.fit(X_train),然后训练分类器。
model.fit(X_train, y_train)
# 测试阶段只 transform 和 predict,不会重新拟合 scaler。
print("test accuracy:", model.score(X_test, y_test))
scaler = model.named_steps["standardscaler"]
print("training means:", scaler.mean_)
print("training scales:", scaler.scale_)代码解析
解析始终位于完整代码下方,并按实际代码段逐项对应。
输入数据与任务
把标准化和逻辑回归放进同一条防泄漏流程,并展示训练、验证、测试的职责。
X- 完整特征矩阵,每行一个样本、每列一个特征。
y- 目标标签或连续目标值。
X_train- 训练特征,只允许它参与预处理器和模型的 fit。
X_test- 测试特征,只用于最终 transform、predict 和评价。
y_train- 与 X_train 对齐的训练目标。
y_test- 与 X_test 对齐的测试目标。
model- 组合预处理和估计器的模型对象。
scaler- 保存训练集缩放参数的转换器。
Step 1 · 1–4 行
导入当前步骤需要的数值计算、预处理、模型或评价工具。依赖集中写在代码开头,便于复现。
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScalerStep 2 · 6–8 行
按固定协议切分训练与测试数据;此处的数据边界决定后续哪些样本可以参与 fit。
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42, stratify=y
)Step 3 · 10–13 行
保存 Pipeline 时,缩放参数会和分类器一起保存,避免推理遗漏预处理。
model = make_pipeline(
StandardScaler(),
LogisticRegression(max_iter=2000),
)Step 4 · 15–16 行
调用 fit 学习训练数据中的参数;若在 Pipeline 中,预处理器与模型会按顺序拟合。
# Pipeline 内部:scaler.fit(X_train),然后训练分类器。
model.fit(X_train, y_train)Step 5 · 18–19 行
复用已经学到的状态处理未见数据;这里不能再次 fit,否则会产生数据泄漏。
# 测试阶段只 transform 和 predict,不会重新拟合 scaler。
print("test accuracy:", model.score(X_test, y_test))Step 6 · 21–23 行
输出中间参数、形状或最终指标,用于核对代码是否符合预期。
scaler = model.named_steps["standardscaler"]
print("training means:", scaler.mean_)
print("training scales:", scaler.scale_)代码与数学原理
减去训练均值并除以训练标准差,对应代码中的 mean/std 或 StandardScaler。
预期输出或运行结果
输出一个 0~1 之间的测试准确率,以及长度等于特征数的 training means 和 training scales。具体分数取决于数据集。
常见错误 · 10 条
- 不要在测试集上调用 fit 或 fit_transform;测试集只能复用训练参数。
- 先对完整数据 fit_transform,再划分训练集和测试集。
- 对验证集或测试集再次调用 fit 或 fit_transform。
- 认为标准化会把数据限制到 [0,1];这是 Min-Max 缩放的典型目标,不是 Z-score。
- 忽略标准差为 0 的常量列,导致除零。
- 存在强异常值时仍机械使用均值和标准差;异常值会显著改变两者。
- 对 One-Hot 列、类别编号或树模型不加区分地全部标准化。
- 训练与线上输入列顺序不一致,导致把某列的均值和标准差应用到另一列。
- 认为标准化可以修复偏态、错误单位、缺失值或数据泄漏;它不能替代数据质量处理。
- 确认样本轴、特征轴以及 X 与 y 的第一维完全对应。
实际应用
- KNN 和 K-Means 的距离计算
- SVM 的间隔和 RBF 核
- 带正则化的线性/逻辑回归
- PCA 主成分分析
- 神经网络梯度优化
- 不同量纲连续特征的统一处理
常见错误
文档来源
02|数据预处理与特征工程原始文档
学习资料/learning_tech/02_preprocessing_feature_engineering.md01|数学与数据基础原始文档
学习资料/learning_tech/01_math_data_foundations.md11|L1 正则化:稀疏模型与特征选择原始文档
学习资料/learning_tech/11_l1_regularization.md- 02 / §1 先划分,再学习预处理参数
- 02 / §5 数值标准化与特征缩放
- 02 / §12 使用 Pipeline 防止泄漏
- 01 / §3 均值、方差和标准差
- 01 / §5.2 为什么距离模型需要标准化
- 11 / §5 使用 L1 前为什么要标准化
推荐学习资料
scikit-learn User Guide
覆盖监督学习、无监督学习、预处理、模型选择、评估和常见陷阱。
scikit-learn Contributors · scikit-learn
资料笔记
Google Machine Learning Crash Course
以短视频、可视化和练习讲解回归、分类、数据、过拟合与神经网络基础。
Google · Google for Developers
资料笔记
scikit-learn Examples
按算法和应用组织可运行示例,展示预处理、训练、评估与可视化流程。
scikit-learn Contributors · scikit-learn
资料笔记
StatQuest Machine Learning Videos
用图形和分步推理讲解回归、分类、树模型、聚类、PCA 与评估指标。
Josh Starmer · YouTube
资料笔记
scikit-learn/scikit-learn
经典机器学习算法、模型选择、预处理和评估工具的核心实现仓库。
scikit-learn Contributors · GitHub
仓库信息
研究 scikit-learn 实现和贡献流程
主要语言:Python / Cython包含数据集或实验需要额外环境