第三章:特征缩放方法——归一化、标准化、最大绝对值缩放与稳健缩放
特征缩放,说白了就是让不同特征的数据范围“统一口径”。我刚开始做特征工程那会儿,总觉得这步有点多余——数据本来好好的,干嘛非要折腾它们?直到有次用KNN做分类,两个特征一个范围是0到100,另一个是0到1,结果模型几乎只看第一个特征。嗯,从那以后我就明白了,量纲不统一,好多算法都会“偏科”。
这一章咱们就来聊聊四种最常用的缩放方法:归一化(Min-Max)、标准化(Z-score)、最大绝对值缩放以及稳健缩放。每种方法都有它拿手的场景,也有它使不上劲的时候。我会结合我自己踩过的坑,尽量讲得接地气些。
1. 归一化(Min-Max Scaling)——把数据硬拉到0-1区间
归一化是最直观的缩放方式。公式很简单:(x - min) / (max - min)。它把所有数据都压缩到 [0, 1] 范围内,数据的最小值变成0,最大值变成1,其他的按比例落在中间。
我个人习惯在两种情况下优先考虑归一化:
- 数据分布比较均匀,没有极端值。比如图像像素值(0-255),打个整数范围,归一化后每个像素都在0到1之间,计算起来方便得多。
- 模型对输入范围有明确要求。像神经网络,特别是用了sigmoid或tanh激活函数的层,输入值太大或太小都会让梯度消失——说白了就是模型学不动。这时候归一化是首选。
2. 标准化(Z-score)——让数据符合标准正态分布
标准化就不一样了。它用 (x - mean) / std 把数据变成均值为0、标准差为1的分布。这么做的好处是,不受数据范围的影响,也不硬性要求数据落到某个区间。
什么时候用标准化?我建议以下场景可以优先:
- 数据大致符合正态分布。标准化后数据更接近标准正态,很多算法(比如线性回归、SVM)在假设数据服从正态分布时表现更好。
- 你需要保留数据的异常结构。标准化不会把异常值压死,离群点依然可以被观察到。
- 模型依赖特征之间的方差结构。比如主成分分析(PCA),标准化是标准的预处理步骤。我做过一个客户流失预测项目,原始数据里有几个特征的方差差了上百倍,PCA直接跑出来全是方差大的特征起作用,标准化之后才看到真实的结构。
3. 最大绝对值缩放(MaxAbs Scaling)——专治稀疏数据
最大绝对值缩放做的事情是:x / max(|x|)。它把数据缩放到 [-1, 1] 区间,但只除以最大绝对值。这跟归一化有点像,但归一化会减去最小值,而这个方法不做平移。
为什么?因为平移会破坏稀疏结构。稀疏数据(比如文本词袋向量,大部分是0)一旦被减去某个值,很多0就会变成负数,稀疏性就消失了。我个人在推荐系统的物品特征处理上常用MaxAbsScaler——用户行为矩阵本来就很稀疏,用Min-Max缩放后数据变得极其稠密,模型反而学不到模式。
4. 稳健缩放(Robust Scaling)——离群点克星
稳健缩放用了中位数和四分位距:(x - median) / IQR。IQR 是第三四分位数减第一四分位数。说白了,它只看数据中间50%的范围来做缩放,自动忽略了那些边缘的离群点。
我在金融风控项目里用过一次稳健缩放,印象很深。数据里有些人的年收入是几个亿(离群点),用标准化处理会把大部分人的收入压到接近0;用归一化更是夸张,99%的人集中在0到0.001之间。换成稳健缩放后,中间90%的人的收入分布终于能看清楚了。
适用场景:离群点确实存在,但又不想直接删除它们。比如异常检测任务,离群点本身可能是重要的信号,但你又不能让这些点主导整个缩放过程。
四种方法对比:一张表让你一目了然
| 方法 | 公式 | 输出范围 | 受离群点影响 | 适合的数据类型 |
|---|---|---|---|---|
| 归一化(Min-Max) | (x - min) / (max - min) | [0, 1] | 严重 | 均匀分布、图像数据 |
| 标准化(Z-score) | (x - mean) / std | 无固定范围 | 中等 | 近似正态分布、需要保留异常结构 |
| 最大绝对值缩放(MaxAbs) | x / max(|x|) | [-1, 1] | 严重 | 稀疏数据、特殊符号数据 |
| 稳健缩放(Robust) | (x - median) / IQR | 无固定范围 | 很小 | 含离群点的数据 |
怎么选?我的一点实战建议
说实话,没有万能的金标准。我一般会按这样的顺序走:
- 先看数据里有没有离群点。画个箱线图,一目了然。有离群点,直接上稳健缩放。
- 没有离群点? 看数据分布。大致像正态分布,选标准化;范围确定且均匀,选归一化。
- 数据稀疏(大部分是0),用最大绝对值缩放没错。
- 实在拿不准? 试试三个方法,用下游模型的性能来评判。
代码示例:scikit-learn 快速上手
from sklearn.preprocessing import MinMaxScaler, StandardScaler, MaxAbsScaler, RobustScaler
# 假设 X 是你要缩放的特征矩阵
X = [[101, 2000],
[102, 1800],
[103, 2200],
[104, 1000],
[105, 2500]]
# 归一化
scaler_minmax = MinMaxScaler()
X_minmax = scaler_minmax.fit_transform(X)
# 标准化
scaler_std = StandardScaler()
X_std = scaler_std.fit_transform(X)
# 最大绝对值缩放
scaler_maxabs = MaxAbsScaler()
X_maxabs = scaler_maxabs.fit_transform(X)
# 稳健缩放
scaler_robust = RobustScaler()
X_robust = scaler_robust.fit_transform(X)
你看,代码本身没什么难的。难的是判断什么时候用哪个。我个人建议,每个新项目都把四种方法跑一遍交叉验证,让最终模型的性能告诉你答案。