「特征化工程」初学者笔记 2026年
收集数据
↓
数据预处理(Data Preprocessing)
↓
特征工程(Feature Engineering)⬅️ 这篇文章写这个
├── 缺失值处理(Missing Value)
├── 异常值处理(Outlier)
├── 编码(One-Hot Encoding、Label Encoding)
├── 标准化(Standardization)
├── 归一化(Normalization)
└── 特征选择(Feature Selection)
↓
划分训练集/测试集
↓
选择模型
↓
训练模型(fit)
↓
预测(predict)
↓
评估(evaluate)
写在前面的
缺失值处理和异常值处理这个可以略过,直接让AI写得了,反正都属于数据出现问题的时候你要知道问题出在哪里?我目前只对于一眼看不出的语义进行解释和学习。
1 编码 Encoding
为什么需要编码?假设有一列数据
- 男
- 女
机器学习模型实际上只能处理数字。它不能计算⬇️
男 + 女
男 × 0.8
所以必须先把文字转换成数字。这个就是编码,其实说人话就是电脑根本不认识字符串,电脑就是个01产物。你写字符串人家也要给你转换成01。常见的编码有2种
- Label Encoding(标签编码)
- One-Hot Encoding(独热编码)
Label Encoding
Label Encoding 最简单。就是每一个类别对应一个数字。
| 原始 | 编码 |
|---|---|
| 男 | 0 |
| 女 | 1 |
再比如
| 城市 | 编码 |
|---|---|
| 北京 | 0 |
| 上海 | 1 |
| 东京 | 2 |
但是这个有一个弊端,比如下面的数据。
| 颜色 | |
|---|---|
| 红 | 0 |
| 蓝 | 1 |
| 绿 | 2 |
| 红 | 0 |
因为红 = 0 蓝 = 1 绿 = 2。你会觉得绿 > 蓝 > 红?实际上不是的,颜色根本没有大小信息。但是模型看到,会误以为2比0大,这就是人为制造了顺序
什么时候可以用 Label Encoding?
只有一种情况,那就是本来就有顺序的。比如,因为大学确实比小学大。
| 学历 | 编码 |
|---|---|
| 小学 | 0 |
| 初中 | 1 |
| 高中 | 2 |
| 大学 | 3 |
或者是下面的这种评价系统。因为它本身就是等级
| 满意度 | 编码 |
|---|---|
| 非常好 | 0 |
| 好 | 1 |
| 一般 | 2 |
| 差 | 3 |
| 很差 | 4 |
所以Label Encoding适合有顺序的数据(Ordinal Data)。
One-Hot Encoding(独热编码)
如果没有顺序怎么办?不想写成
红=0
蓝=1
绿=2
One-Hot Encoding 出现了。它的思想就是一个类别对应一列
| 红 | 蓝 | 绿 |
|---|---|---|
| 1 | 0 | 0 |
| 0 | 1 | 0 |
| 0 | 0 | 1 |
原数据
| 颜色 |
|---|
| 红 |
| 蓝 |
| 绿 |
| 红 |
One-Hot 后
| 红 | 蓝 | 绿 |
|---|---|---|
| 1 | 0 | 0 |
| 0 | 1 | 0 |
| 0 | 0 | 1 |
| 1 | 0 | 0 |
为什么叫 One-Hot,因为一行只有一个1,只有一个位置是热(Hot)
再举一个真实机器学习例子,下面就是一个职业的例子。
| 程序员 | 老师 | 医生 |
|---|---|---|
| 1 | 0 | 0 |
| 0 | 1 | 0 |
| 0 | 0 | 1 |
那么缺点呢?那就是维度爆炸。
中国
日本
美国
英国
法国
德国
……
100 个国家。One-Hot就会变成100 列。如果10000 个类别就会成为 10000 列。
这叫维度爆炸(Curse of Dimensionality 的一个表现)所以One-Hot 不适合类别特别多的数据。总结一下
| 数据类型 | Label Encoding | One-Hot Encoding |
|---|---|---|
| 有顺序(Ordinal) | ✅ 推荐 | ❌ 一般不用 |
| 无顺序(Nominal) | ❌ 不推荐 | ✅ 推荐 |
有顺序 → Label Encoding
- 学历
- 满意度
- 风险等级
- 衣服尺码(S、M、L、XL)
无顺序 → One-Hot Encoding
- 性别
- 城市
- 国家
- 职业
- 颜色
- 品牌
2 标准化
什么是标准化?为什么需要呢?
标准化属于数据预处理中的特征工程。这是重点,是特征工程。意思就是说在训练之前就要做的事情,记到这里就可以了。
标准化就是把不同单位、不同大小的数据,变到同一个尺度上。
这是机器学习里最重要的概念之一,也是很多初学者第一次觉得为什么要这么做的地方。先来看一个真实例子。假设我们要预测一个人是否喜欢游泳。有两个特征
| 身高(cm) | 年龄(岁) |
|---|---|
| 180 | 20 |
| 170 | 30 |
| 160 | 40 |
假设有一个新的人
| 身高 | 年龄 |
|---|---|
| 175 | 35 |
如果 KNN 去计算距离。对于第一位。
- 身高差。175-180=-5
- 年龄差。35-20=15
欧氏距离 看起来年龄影响更大。为什么呢。
- 身高一般在 150~190
- 年龄一般在 20~40
这个还不错太严重,再看一个更夸张的例子
| 年龄 | 收入(日元) |
|---|---|
| 20 | 2,000,000 |
| 30 | 8,000,000 |
来了一个新的人。年龄:25。收入:5,000,000,
对于第一位。直接计算一下 结果就是 约等于3000000。
这样一看年龄几乎没有任何影响。也就是说收入把年龄给淹没了。
为什么会这样?因为欧氏距离会平方。但是年龄和收入,两者根本不是一个数量级。所以模型几乎只看收入。这是不合理的。
标准化就是为了解决这个问题而出来的,他会用一种方式让平均值为 0,标准差为 1。
也就是说原来年龄2040,收入200万800万,标准化之后。就是
- 年龄 -1.2 0.3 1.5
- 收入 -0.8 0.1 1.2
大家都变成差不多大小。距离计算就公平了。标准化(Standard Deviation:简称SD)是怎么做到的?它使用下面这个公式
- x:原来的数据
- :这一列的平均值
- :这一列的标准差
计算出来的新值就是标准化后的值。假设一列年龄⬇️
20 25 30 35 40
平均值 标准差约
对于20 对于30 z=0 对于40 z=1.41
标准化之后数据就成了下面的这个样子
| 原始年龄 | 标准化 |
|---|---|
| 20 | -1.41 |
| 25 | -0.71 |
| 30 | 0 |
| 35 | 0.71 |
| 40 | 1.41 |
- 平均值变成了 0
- 数值都集中在 -3~3 左右
为什么叫 StandardScaler?就是 按照标准差来缩放(Scale)数据。所以名字叫 StandardScaler()
哪些算法必须标准化?几乎所有基于距离或梯度的算法都建议标准化。
| 算法 | 是否建议标准化 |
|---|---|
| KNN | ✅ 必须 |
| KMeans | ✅ 必须 |
| SVM | ✅ 建议 |
| Logistic Regression | ✅ 建议 |
| Linear Regression(梯度下降) | ✅ 建议 |
| 神经网络 | ✅ 建议 |
哪些算法一般不用标准化?树模型几乎不用。
- Decision Tree
- Random Forest
- XGBoost
- LightGBM
为什么?因为树模型不是计算距离,而是比较大小,
收入 > 500 万?
年龄 < 35?
无论收入是 500 万还是标准化后的 0.85,只要大小关系不变,树的切分结果就不会变。
3 归一化
什么是归一化?为什么需要归一化?
在机器学习的数据预处理中,归一化通常指把数据缩放到一个固定区间,例如 [0,1],最常见的方法是 MinMaxScaler。
我感觉就是把一系列的数字等比例缩到一个范围内。大家一起断腿。
它和标准化一样,都属于数据预处理➡️特征缩放但两者的计算方式不同。最常见的是 Min-Max Normalization
上面的计算之后,最终结果通常位于[0,1],下面这一组可以手算一下,因为最大值60,最小值20。分母肯定永远都是60-20=40
所以它本质上就是:先把最小值平移到 0,再按照整个数据范围进行缩放。
| 原始年龄 | 归一化结果 |
|---|---|
| 20 | 0 |
| 30 | 0.25 |
| 40 | 0.5 |
| 50 | 0.75 |
| 60 | 1 |
归一化不是把所有数变得相同,而是保持数据之间的相对大小关系,把整组数据按比例压缩到固定区间。
归一化为什么有用?
假设一个数据集有两个特征。两个特征的数量级差距非常大
| 年龄 | 年收入(日元) |
|---|---|
| 20 | 3,000,000 |
| 30 | 5,000,000 |
| 40 | 8,000,000 |
在 KNN 里计算距离时,收入会严重压过年龄。归一化以后可能变成
| 年龄 | 年收入 |
|---|---|
| 0 | 0 |
| 0.5 | 0.4 |
| 1 | 1 |
这样两个特征都处于 0 ~ 1的尺度,模型就不会因为单位和数量级不同而只关注收入。
归一化只是让特征处于相近尺度,并不意味着两个特征一定同样重要。特征的重要程度仍然由数据和模型决定。
什么时候选择归一化?
- 数据需要固定在特定范围内
例如神经网络的输入经常缩放到 [0,1]
例如 图片像素原本是 0255 通常可以除以 255 像素值 128 这样图片数据就变成了 01。
- 特征本身有明确上下界
- 百分比:0 ~ 100
- 像素:0 ~ 255
- 考试成绩:0 ~ 100
- 某些传感器量程
这类数据使用归一化比较直观。
- 模型对输入范围比较敏感
- KNN
- KMeans
- 神经网络
- 某些梯度下降模型
但实际选择标准化还是归一化,需要结合数据分布和模型验证结果。
这里继续看sk
from sklearn.preprocessing import MinMaxScaler
X_train = [
[20, 3_000_000],
[30, 5_000_000],
[40, 8_000_000],
]
scaler = MinMaxScaler() # 在这里使用
X_train_scaled = scaler.fit_transform(X_train) # 看好这里用的是train
print(X_train_scaled)
这里每一列分别归一化。也就是说
- 年龄列根据年龄自己的最小值和最大值处理
- 收入列根据收入自己的最小值和最大值处理
不是把整个二维表中的所有数混在一起计算。
还要注意fit和transform 分别是不同的职责。
fit会从训练集学习transform使用已经学到的最小值和最大值转换数据。
scaler.fit(X_train)
- 每一列的最小值
- 每一列的最大值
X_train_scaled = scaler.transform(X_train)
- 虽然可以合并写成,但是你要看合并的只是train。也就是训练集。
X_train_scaled = scaler.fit_transform(X_train)
因为测试集必须使用训练集的缩放规则。也就是说,你可以进行缩放,但是你不能去🔥用test进行fit!!
#对于X_test测试集,只能transform
X_test_scaled = scaler.transform(X_test)
# 不能重新执行
scaler.fit_transform(X_test) # 错误做法
为什么测试集不能单独归一化?
假设训练集年龄范围为 20~60 模型学习到 min 20 max 60
train集中有一个年龄 40 按照train规则
如果test 恰好只有 40 然后单独对test集执行
fit_transform年龄 40 会变成 同一个年龄 40
- 在train训练规则下是 0.5
- 在test 测试规则下却是 0
这会导致训练和预测时的数据含义不一致。
# 正确做法是: scaler.fit(X_train) X_train_scaled = scaler.transform(X_train) X_test_scaled = scaler.transform(X_test)测试数据可能超过 0~1 吗?
可能。假设train训练集范围是20-60,test测试集出现年龄70
使用train集规则
所以测试集归一化后可能超过 1。同样,如果测试数据比训练集最小值还小,也可能得到负数。
这不是程序错误,而是表示 新数据超出了训练时观察到的范围。
因此,MinMaxScaler 的结果一定在 [0,1 只对用于
fit的那批训练数据严格成立。
归一化到其他区间
MinMaxScaler 默认范围是 [0,1] 也可以指定为 [-1,1]
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler(feature_range=(-1, 1))
通用公式是 其中目标区间为 [a,b]
两种含义
归一化这个词可能有两种含义
含义一:Min-Max 缩放
把每一个特征缩放到 [0,1],这是当前最常见的初学者语境。
MinMaxScaler()
含义二:向量范数归一化
把每一个样本向量缩放为长度 1。 例如原向量 (3,4) 它的欧氏长度是
归一化后 此时新向量的长度
在 sklearn 中对应
from sklearn.preprocessing import Normalizer
MinMaxScaler:通常按列缩放特征Normalizer:通常按行缩放每个样本向量
现阶段在数据预处理中所说的归一化,通常先理解为 MinMaxScaler 即可。
归一化和标准化的区别
标准化处理后
- 均值约为 0
- 标准差约为 1
- 没有固定的最大值和最小值
- 结果可以是负数,也可以大于 1
归一化处理后
- 最小值为 0
- 最大值为 1
- 通常全部在 [0,1] 之间
- 不一定均值为 0
- 不一定标准差为 1
对比表
| 对比项 | 标准化 | 归一化 |
|---|---|---|
| 英文 | Standardization | Normalization / Min-Max Scaling |
| sklearn | StandardScaler | MinMaxScaler |
| 依据 | 均值、标准差 | 最小值、最大值 |
| 常见范围 | 无固定范围 | 通常为 [0,1] |
| 是否可能为负数 | 是 | 默认不会 |
| 均值是否为 0 | 是 | 不一定 |
| 标准差是否为 1 | 是 | 不一定 |
| 对异常值是否敏感 | 敏感 | 更敏感 |