特征化工程初学者笔记 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 出现了。它的思想就是一个类别对应一列

绿
100
010
001

原数据

颜色
绿

One-Hot 后

绿
100
010
001
100

为什么叫 One-Hot,因为一行只有一个1,只有一个位置是热(Hot)

再举一个真实机器学习例子,下面就是一个职业的例子。

程序员老师医生
100
010
001

那么缺点呢?那就是维度爆炸。

中国
日本
美国
英国
法国
德国
……

100 个国家。One-Hot就会变成100 列。如果10000 个类别就会成为 10000 列。

这叫维度爆炸(Curse of Dimensionality 的一个表现)所以One-Hot 不适合类别特别多的数据。总结一下

数据类型Label EncodingOne-Hot Encoding
有顺序(Ordinal)✅ 推荐❌ 一般不用
无顺序(Nominal)❌ 不推荐✅ 推荐

有顺序 → Label Encoding

  • 学历
  • 满意度
  • 风险等级
  • 衣服尺码(S、M、L、XL)

无顺序 → One-Hot Encoding

  • 性别
  • 城市
  • 国家
  • 职业
  • 颜色
  • 品牌

2 标准化

什么是标准化?为什么需要呢?

标准化属于数据预处理中的特征工程。这是重点,是特征工程。意思就是说在训练之前就要做的事情,记到这里就可以了。

标准化就是把不同单位、不同大小的数据,变到同一个尺度上。

这是机器学习里最重要的概念之一,也是很多初学者第一次觉得为什么要这么做的地方。先来看一个真实例子。假设我们要预测一个人是否喜欢游泳。有两个特征

身高(cm)年龄(岁)
18020
17030
16040

假设有一个新的人

身高年龄
17535

如果 KNN 去计算距离。对于第一位。

  • 身高差。175-180=-5
  • 年龄差。35-20=15

欧氏距离 (5)2+152=15.81\sqrt{(-5)^2+15^2}=15.81 看起来年龄影响更大。为什么呢。

  • 身高一般在 150~190
  • 年龄一般在 20~40

这个还不错太严重,再看一个更夸张的例子

年龄收入(日元)
202,000,000
308,000,000

来了一个新的人。年龄:25。收入:5,000,000,

对于第一位。直接计算一下 52+30000002\sqrt{5^2+3000000^2} 结果就是 约等于3000000。

这样一看年龄几乎没有任何影响。也就是说收入把年龄给淹没了。

为什么会这样?因为欧氏距离会平方。但是年龄和收入,两者根本不是一个数量级。所以模型几乎只看收入。这是不合理的。

标准化就是为了解决这个问题而出来的,他会用一种方式让平均值为 0,标准差为 1。

也就是说原来年龄2040,收入200万800万,标准化之后。就是

  • 年龄 -1.2 0.3 1.5
  • 收入 -0.8 0.1 1.2

大家都变成差不多大小。距离计算就公平了。标准化(Standard Deviation:简称SD)是怎么做到的?它使用下面这个公式

z=xμσz=\frac{x-\mu}{\sigma}
  • x:原来的数据
  • μ\mu:这一列的平均值
  • σ\sigma:这一列的标准差

计算出来的新值就是标准化后的值。假设一列年龄⬇️

20 25 30 35 40

平均值 μ=30\mu=30 标准差约 σ=7.07\sigma=7.07

对于20 z=20307.071.41z=\frac{20-30}{7.07}\approx-1.41 对于30 z=0 对于40 z=1.41

标准化之后数据就成了下面的这个样子

原始年龄标准化
20-1.41
25-0.71
300
350.71
401.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

x=xxminxmaxxminx'=\frac{x-x_{\min}}{x_{\max}-x_{\min}}

上面的计算之后,最终结果通常位于[0,1],下面这一组可以手算一下,因为最大值60,最小值20。分母肯定永远都是60-20=40

所以它本质上就是:先把最小值平移到 0,再按照整个数据范围进行缩放。

原始年龄归一化结果
200
300.25
400.5
500.75
601

归一化不是把所有数变得相同,而是保持数据之间的相对大小关系,把整组数据按比例压缩到固定区间。

归一化为什么有用?

假设一个数据集有两个特征。两个特征的数量级差距非常大

年龄年收入(日元)
203,000,000
305,000,000
408,000,000

在 KNN 里计算距离时,收入会严重压过年龄。归一化以后可能变成

年龄年收入
00
0.50.4
11

这样两个特征都处于 0 ~ 1的尺度,模型就不会因为单位和数量级不同而只关注收入。

归一化只是让特征处于相近尺度,并不意味着两个特征一定同样重要。特征的重要程度仍然由数据和模型决定。

什么时候选择归一化?

  1. 数据需要固定在特定范围内

例如神经网络的输入经常缩放到 [0,1]

例如 图片像素原本是 0255 通常可以除以 255 x=x255x'=\frac{x}{255} 像素值 128 1282550.502\frac{128}{255}\approx0.502 这样图片数据就变成了 01。

  1. 特征本身有明确上下界
  • 百分比:0 ~ 100
  • 像素:0 ~ 255
  • 考试成绩:0 ~ 100
  • 某些传感器量程

这类数据使用归一化比较直观。

  1. 模型对输入范围比较敏感
  • 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)

这里每一列分别归一化。也就是说

  • 年龄列根据年龄自己的最小值和最大值处理
  • 收入列根据收入自己的最小值和最大值处理

不是把整个二维表中的所有数混在一起计算。

还要注意fittransform 分别是不同的职责。

  • 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规则 40206020=0.5\frac{40-20}{60-20}=0.5

如果test 恰好只有 40 然后单独对test集执行 fit_transform

年龄 40 会变成 40405040=0\frac{40-40}{50-40}=0 同一个年龄 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集规则 70206020=5040=1.25\frac{70-20}{60-20}=\frac{50}{40}=1.25

所以测试集归一化后可能超过 1。同样,如果测试数据比训练集最小值还小,也可能得到负数。

这不是程序错误,而是表示 新数据超出了训练时观察到的范围。

因此,MinMaxScaler 的结果一定在 [0,1 只对用于 fit 的那批训练数据严格成立。

归一化到其他区间

MinMaxScaler 默认范围是 [0,1] 也可以指定为 [-1,1]

from sklearn.preprocessing import MinMaxScaler

scaler = MinMaxScaler(feature_range=(-1, 1))

通用公式是 其中目标区间为 [a,b]

x=a+xxminxmaxxmin(ba)x'=a+\frac{x-x_{\min}}{x_{\max}-x_{\min}}(b-a)

两种含义

归一化这个词可能有两种含义

含义一:Min-Max 缩放

把每一个特征缩放到 [0,1],这是当前最常见的初学者语境。

MinMaxScaler()

含义二:向量范数归一化

把每一个样本向量缩放为长度 1。 例如原向量 (3,4) 它的欧氏长度是 32+42=5\sqrt{3^2+4^2}=5

归一化后 (35,45)=(0.6,0.8)\left(\frac35,\frac45\right)=(0.6,0.8) 此时新向量的长度 0.62+0.82=1\sqrt{0.6^2+0.8^2}=1

在 sklearn 中对应

from sklearn.preprocessing import Normalizer
  • MinMaxScaler:通常按列缩放特征
  • Normalizer:通常按行缩放每个样本向量

现阶段在数据预处理中所说的归一化,通常先理解为 MinMaxScaler 即可。

归一化和标准化的区别

标准化处理后

  • 均值约为 0
  • 标准差约为 1
  • 没有固定的最大值和最小值
  • 结果可以是负数,也可以大于 1

归一化处理后

  • 最小值为 0
  • 最大值为 1
  • 通常全部在 [0,1] 之间
  • 不一定均值为 0
  • 不一定标准差为 1

对比表

对比项标准化归一化
英文StandardizationNormalization / Min-Max Scaling
sklearnStandardScalerMinMaxScaler
依据均值、标准差最小值、最大值
常见范围无固定范围通常为 [0,1]
是否可能为负数默认不会
均值是否为 0不一定
标准差是否为 1不一定
对异常值是否敏感敏感更敏感