特征工程相关问题
wangzf / 2026-01-27
目录
1.特征工程与表示学习
2.数据归一化和标准化
在进行数据分析的时候,什么情况下需要对数据进行标准化处理?
主要看 模型是否具有伸缩不变性。
- 有些模型在各个维度进行不均匀伸缩后,最优解与原来不等价,例如 SVM。对于这样的模型, 除非本来各维数据的分布范围就比较接近,否则必须进行标准化, 以免模型参数被分布范围较大或较小的数据主导(dominate)。
- 有些模型在各个维度进行不均匀伸缩后,最优解与原来等价,例如 logistic regression。 对于这样的模型,是否标准化理论上不会改变最优解。但是,由于实际求解往往使用迭代算法, 如果目标函数的形状太“扁”,迭代算法可能收敛得很慢甚至不收敛。 所以对于具有伸缩不变性的模型,最好也进行数据标准化。
归一化和均值方差标准化(z-score)
- 归一化(Normalization)
- 减去最小值,除以极差,映射到
[0,1]之间 - 只适用于有明显范围的数据,没有 outlier 的情况
- 需要 MinMaxScaler 的特征
- 标准差较小的特征
- 稀疏特征(很多元素是0)
- 减去最小值,除以极差,映射到
- 均值方差标准化(Z-score standardization)
- 减去均值,除以标准差,映射后数据集为
X(0,1)的分布 - 无明显范围、有 outlier 时同样使用
- 减去均值,除以标准差,映射后数据集为
Z分数(z-score),也叫标准分数(standard score)是一个数与平均数的差再除以标准差的过程。 在统计学中,标准分数是一个观测或数据点的值高于被观测值或测量值的平均值的标准偏差的符号数。(无量纲)
对 outlier 不同的处理能力:
处理 outlier 的基本前提:我们不应该因为 outlier 而过多改变对变量的缩放。
- 0-1 归一化中,若部分变量存在 outlier,会使得不同变量之间的压缩程度变得不一致。
如 x1 范围为
[0,5],x2 范围为[0,10],压缩比例应该为1:2, x1 增加一个取 100 的 outlier,压缩比例就变成了 10:1。 - 而 Z-score 标准化中,除数为标准差,不会像极差一样对 outlier 敏感。 在上述例子中,x1 增加一个 outlier 后,压缩比例也不会改变太多。 Z-score 标准化后,方差为 1,但极差仍然可能很大(outlier 仍存在), 这体现了 Z-score 标准化对 outlier 的容纳能力。
3.数据划分
完整的建模流程通常是:
- 已有数据划分(hold-out/留一法/K 折交叉验证)为训练集和验证集,通过验证集上的评价指标来调整超参数, 选择超参数后再以完整的数据集训练出模型交付,模型在应用中遇到的实际数据可成为测试集
- 有时候会把数据集简单划分(hold-out/留一法/K折交叉验证)为训练集和测试集,如不需要调整超参数时, 或只有实验数据(不需要交付模型)时想评估模型性能
几种数据划分方法的细节:
- 留出法(hold-out):按一定比例(常见 Train 为 2/3~4/5,如 70%)直接将 D 划分为 train 和 test, 要保证标签分布尽量一致(可使用分层抽样),由于抽样的随机性要保证结果的稳定性可重复操作取均值
- K 折交叉验证(k-fold cross-validation):以分层抽样将 D 划分为 K 个大小相似的子集, 每次以其中一个作为测试集,返回 K 次操作的均值
- 留一法(Leave-One-Out):K-fold 的特例,每次以一个样本作为测试集,返回 M 次(D 的样本数量)操作的均值。 缺点是时间开销大
- bootstrap/out-of-bag 估计:有放回抽样 |D| 次构成训练集,约有 36.8% 的样本没有被抽到, 进入测试集。优点是能保持训练样本的规模,缺点是会改变训练样本的分布, 因此在大数据量时还是多用 hold-out 和交叉验证
4. 预处理(以归一化为例)和划分 train/test 的顺序
对训练集的特征做归一化后,测试集的特征怎么办?这是一个非常关键的问题, 因为训练集特征归一化后,测试集的特征范围可能就不同了,因此模型失效。 一般有几种思路:
- 方法 1:把训练集和测试集合在一起做归一化,这样特征范围就统一了。 之后用训练集做训练,那测试集做测试。但很明显的,在训练模型时,不应该包括任何测试集的信息。 这种做法会导致存在人为偏差的模型,不能用。
- 方法 2:对训练集单独做归一化,之后对测试集单独做归一化。这种看法看似也可以, 重点在于数据量以及数据的排列顺序。在数据量大且数据被充分打乱的前提下, 这种做法是可行的。但换句话说,如果有这样的前提假设,那么方法1的结论也是可行的。
- 方法 3:对训练集先做归一化,并保留其归一化参数(如最大、最小值), 之后用训练集的归一化参数对测试集做处理。这种做法看似是可以的。 但风险在于数据量有限的前提下,训练集的参数会导致测试集的结果异常, 如产生极大或者极小的数值。
其实不难看出,从某种意义上说,三种做法是等价的。在数据量大且充分打乱的前提下, 训练集和验证集有相同的分布假设,因此用任意一种其实差别不大。然而这样的假设过于乐观, 且我们在真实情况下应该只有:训练集 + 一个测试数据,因此方法 2 是明显不行的。
于是似乎方法 1 和方法 3 都可以。但其实不然,方法 1 常常被认为是错误的操作, 原因是在训练阶段引入了测试数据,这属于未知数据。即使仅仅引入了 1 个测试数据, 如果取值非常极端,依然会导致输出范围有较大的波动。 其次,如果对于每一个测试数据都需要用整个训练集来归一的话,那么运算开销会非常大。
那么似乎备选的只有方案 3,即保留验证集上的归一化参数,并运用于测试集。这样的做法看似可以,但有不少风险:
- 不是每种特征工程都可以保存参数,很多特征工程是非常繁复的。
- 如果测试集数据和训练集数据有很大的差别,那么用测试集的参数会产生异常数据。
参考上述文章所言,特征工程(以归一化为例)和数据划分的顺序共有三种方案:
- 整体归一化后,再划分
- 划分后,train 和 test 各自单独归一化
- 划分后,以 train 的规则对 test 进行归一化
理想情况,数据量大且充分打乱时,划分后各部分的分布相同,三种方法区别不大。
对于一般流程而言:
- 方案 2 应该首先排除,因为最起码应该保持 train/test 上的归一化操作相同;
- 方案 1 通常被视为 “data leakage” 原则错误,在训练模型的时候应用了 test 的信息(如极值、均值方差等);
同时方案 1 也会使得训练集中各变量不严格服从
[0,1]的分布,这和归一化的初衷是相违背的; - 方案 3 符合业界实际的模型部署,不断遇到新的 test,相对于 1 而言不需要重新训练模型, 运算开销小。
但也有说法表示,方案 1 虽然在进行特征工程的时候引入了测试集的信息,但是在整体来看, 我们本来就是为了能够更贴合真实数据分布,故而这种引入信息的行为是可以接受的。
倾向于认为方案 1 不是绝对的错误,方案 1 的 test error 未必总是和真实泛化误差离得更远。 不过即使刨除这一项,其他原因也足够让我在接下来的操作中:先划分 train/test,再作归一化。
补充:不拘泥于归一化这种简单的操作,从广义的特征工程的角度,依靠全部数据集的特征工程, 方案 1 会造成 test 的 leakage 就比较好理解,在数据挖掘竞赛中,名次对此会比较敏感。 而业界实际部署中,这些并不严格,使用方案3更多是来自实用性的原因。
5.不平衡条件下的 test 是否需要 resampling?
不需要,test 是试图对真实分布的模拟,test 上的误差是对真实泛化误差的近似。 train set 上 resampling 是为了防止模型训练不出来。
