公式没有问题。问题在于 min 和 max 从哪里来。
在普通机器学习任务中,Min-Max归一化把特征线性映射到 [0, 1] 或 [-1, 1]。在量化交易中,数据按时间生成。未来数据尚不存在。若使用全样本的最大值和最小值,归一化过程就已经读取了未来信息。
结果通常具有三个特征:
- 回测指标异常稳定。
- 训练集和测试集分布衔接得过于平滑。
- 实盘数据进入后,模型表现显著偏离回测。
这不是归一化公式导致的。是统计量的计算边界错误。
Min-Max归一化的数学本质与金融场景的错位
Min-Max归一化只做一件事:改变数值尺度,不改变样本之间的线性顺序。
设原始特征为 \(x\),样本最小值为 \(min\),最大值为 \(max\)。目标区间为 [0, 1] 时:
\[
x' = \frac{x-min}{max-min}
\]
如果目标区间是 [a, b],则公式变为:
\[
x' = a + \frac{(x-min)(b-a)}{max-min}
\]
这是一种仿射变换。它不会改变排序关系,也不会自动消除异常值,更不会让金融数据变成正态分布。
金融时间序列的问题在于:min 和 max 不是固定常数。
价格会创新高。波动率会突然扩张。成交量会产生尖峰。价差会在流动性下降时扩大。宏观数据会出现结构性断点。历史样本的边界不是数据生成机制的边界,只是当前数据集中的两个观测值。
把它们直接拿来定义整个数据集的尺度,相当于假设:
1. 未来不会超过历史最大值。
2. 未来不会跌破历史最小值。
3. 数据分布在训练期间保持稳定。
4. 异常点可以代表整个特征空间的边界。
5. 模型部署时能够获得未来统计量。
这五个假设在金融数据中都不稳固。
归一化只改变尺度,不改变分布
Min-Max常被误解为一种“分布修复”方法。它不是。
假设一组数据为:
100、102、104、106、500
使用最小值100、最大值500进行归一化,结果约为:
0、0.005、0.01、0.015、1
原本相邻的100、102、104、106,被压缩到极窄区间。500这个极值占据了整个上边界。数据仍然偏斜。只是偏斜被映射到了 [0, 1]。
如果模型依赖特征之间的距离,影响会更直接。正常样本之间的差异在数值空间中被压扁,异常点与其他样本之间的距离被放大。模型看到的不是市场状态,而是极值对坐标系的重新定义。
这对以下模型尤其敏感:
- K近邻模型依赖样本间距离。
- 支持向量机依赖特征空间中的间隔。
- 深度神经网络的梯度下降受输入量纲影响。
- 线性模型在不同尺度的特征下,参数优化速度可能不同。
- 聚类算法直接使用距离或相似度。
决策树和随机森林通常对特征缩放更鲁棒。因为树模型主要寻找切分阈值,不直接依赖欧氏距离。但这不代表归一化过程中的时间泄漏可以忽略。即使模型本身不需要缩放,全局拟合的预处理仍然可能污染评估流程。
Min-Max的问题不在于把数值压到零和一之间,而在于用未来定义了今天的坐标系。
前视偏误:全局归一化如何泄露未来信息
前视偏误不是只有标签泄漏。
很多量化流程只检查目标变量,却忽略特征预处理。常见流程如下:
1. 读取完整历史数据。
2. 对完整数据执行Min-Max归一化。
3. 按时间切分训练集和测试集。
4. 使用训练集拟合模型。
5. 在测试集上评估。
表面上,模型没有直接读取测试集标签。实际上,步骤2已经使用了测试区间的最大值和最小值。
一个时间切分例子
设训练数据位于时间区间 \(T_1\),测试数据位于之后的 \(T_2\)。
正确的训练集变换应当是:
\[
x'_{T_1} = \frac{x_{T_1}-min(T_1)}{max(T_1)-min(T_1)}
\]
测试集应使用训练集统计量:
\[
x'_{T_2} = \frac{x_{T_2}-min(T_1)}{max(T_1)-min(T_1)}
\]
错误做法则是:
\[
x'{all} = \frac{x{all}-min(T_1,T_2)}{max(T_1,T_2)-min(T_1,T_2)}
\]
后一个公式把 \(T_2\) 的信息带入了 \(T_1\)。模型虽然没有看到未来标签,但已经知道未来数据的尺度边界。
如果测试阶段出现了更高的价格,全球最大值会把训练数据整体压低。如果测试阶段出现了更低的价格,全球最小值会把训练数据整体抬高。模型训练时接收的特征分布因此发生改变。
这种泄漏不一定让预测方向明显变好。更常见的表现是:
- 训练和测试的特征范围异常一致。
- 测试阶段的输入分布没有自然漂移。
- 模型对边界附近样本表现过度稳定。
- 交叉验证结果好于严格的时间外推。
- 重新按照真实上线流程运行后,指标明显下降。
管道顺序决定评估是否有效
时间序列不能使用普通随机切分替代严格的时间切分。
随机切分会打散时间关系。即便归一化只在训练折上拟合,临近样本之间的高度相关仍可能让评估结果偏乐观。金融数据通常存在自相关、波动聚集和市场状态持续性。随机打乱会让测试样本与训练样本共享相近状态。
更稳妥的流程是:
1. 按时间排序。
2. 先确定训练区间、验证区间和测试区间。
3. 只在训练区间拟合归一化参数。
4. 使用同一组参数变换验证区间。
5. 在参数不变的情况下变换测试区间。
6. 进入滚动或扩展回测时,在每个时点重新生成允许使用的统计量。
核心约束只有一个:
在时间 \(t\) 生成特征时,只能使用 \(t\) 及之前已经完成的数据。
这条约束适用于Min-Max、Z-score、缺失值填补、异常值截断、特征选择和降维。将Min-Max替换为Z-score,不会自动消除前视偏误。
极值敏感性:异常值如何压缩特征空间
Min-Max的分母是:
\[
max-min
\]
极值扩大,分母变大。其他样本的归一化结果被压缩。
这在金融数据中非常普遍。
价格序列不适合直接按绝对值缩放
直接使用收盘价进行Min-Max归一化,通常会保留趋势信息,也会保留价格绝对水平。对于跨资产模型,这种绝对水平未必有可比性。
例如,两只价格分别为几十和几百的资产,其价格单位不同。即使收益结构相近,Min-Max也会把它们放到不同的原始尺度中。若后续使用神经网络,模型可能先学习价格等级,而不是学习收益变化。
更常用的特征是:
- 对数收益率。
- 简单收益率。
- 高低价区间。
- 收盘价相对移动均线的偏离。
- 滚动波动率。
- 成交量变化率。
- 买卖价差的相对值。
- 订单簿深度的比例特征。
这些特征仍然需要处理异常值,但处理对象从绝对价格变成了变化率或相对量。尺度更接近模型需要识别的结构。
这不是说价格不能归一化。具体取决于模型目标。如果模型研究趋势位置,价格水平可能有用。如果模型研究横截面排序,绝对价格往往不是合理的共享尺度。
单个异常点可以重写整个区间
异常值不只来自错误记录。
以下情况都可能形成极端值:
- 复权处理错误。
- 合约换月造成价格跳变。
- 股票拆分或合并未正确调整。
- 交易所临时停牌后重新交易。
- 成交量字段单位变化。
- 时间戳错位。
- 盘口数据出现重复或负值。
- 低流动性资产产生孤立成交。
- 数据供应商在合并时发生字段异常。
如果一个极端值没有被识别,直接进入全局Min-Max,整个样本区间都会被它重新缩放。
数据清洗必须位于归一化之前。但清洗规则也不能读取未来分布。例如,使用全样本的分位数截断异常值,同样可能造成时间泄漏。训练阶段的截断边界应当由训练窗口产生。进入测试阶段时,边界保持不变,或者按照明确的滚动规则更新。
不要把截断当成删除
对异常值的处理至少有三种不同目标:
1. 删除错误记录。
2. 对合法但极端的观测进行截尾。
3. 保留极端状态,让模型学习波动扩张。
三者不能混用。
如果数据是坏的,应修复或剔除。
如果数据合法但稀有,应考虑截尾、变换或单独增加异常状态标记。
如果极端值正是策略关注的交易状态,则简单删除会损失信号。
归一化没有能力判断异常值是否有意义。它只执行公式。
突破边界:实盘数据超出训练范围后会发生什么
全局Min-Max通常被理解为把数据固定到 [0, 1]。这个结论只对训练样本成立。
假设训练集范围为:
\[
[min_{train}, max_{train}]
\]
当实盘样本满足:
\[
x_{live} > max_{train}
\]
则:
\[
x'_{live} > 1
\]
当:
\[
x_{live} < min_{train}
\]
则:
\[
x'_{live} < 0
\]
这不是数学错误。是边界外推。
边界外推的三种处理方式
第一种:允许超出区间
直接使用训练阶段的参数。
优点是保留了突破幅度。模型可以区分略微突破和大幅突破。
缺点是模型训练阶段没有见过这些区间。神经网络的激活函数、参数范围和损失函数可能对边界外输入不稳定。
第二种:强制截断到目标区间
将结果限制在 [0, 1]:
\[
x' = \min(1,\max(0,x'))
\]
优点是输入范围稳定。
缺点是所有超过上边界的值都会被压到1,所有低于下边界的值都会被压到0。不同程度的突破失去区分度。信息被截断。
第三种:动态更新窗口
使用滚动窗口或扩展窗口重新计算边界。
优点是适应非平稳数据。
缺点是输入尺度随时间变化。模型看到的同一原始数值,在不同时间可能对应不同的归一化结果。若策略逻辑依赖绝对可比性,解释会变得困难。
没有一种方式普遍正确。决策取决于特征定义、模型结构和上线时的更新机制。
训练和实盘必须使用同一套变换协议
很多项目在训练阶段保存了模型,却没有保存预处理器参数。上线后重新用实时数据计算Min-Max。这会导致模型输入坐标系持续漂移。
模型参数固定。特征尺度变化。输入分布不再匹配。
至少需要明确记录:
- 训练窗口的起止时间。
- 每个特征使用的最小值和最大值。
- 目标区间。
- 是否进行了截断。
- 异常值处理规则。
- 缺失值处理规则。
- 变换参数的更新时间。
- 新样本越界时的处理方式。
- 复权、换月和时区处理方式。
归一化参数不是附属文件。它属于模型的一部分。
时序建模的正确姿势:滚动窗口与扩展窗口
金融数据通常不是平稳分布。即使均值、方差和极值在一段时间内稳定,也不能推断未来仍然稳定。
因此,统计量必须绑定时间。
滚动窗口
滚动窗口只使用最近 \(k\) 个周期计算统计量:
\[
min_t = \min(x_{t-k},...,x_{t-1})
\]
\[
max_t = \max(x_{t-k},...,x_{t-1})
\]
当前时点的归一化结果为:
\[
x'_t = \frac{x_t-min_t}{max_t-min_t}
\]
窗口是否包含当前值,取决于信号生成时点。
如果特征用于在收盘后生成下一根K线的信号,可以使用已经完成的当前K线。若信号需要在当前K线结束前生成,则当前K线数据不可使用。时间戳必须和交易执行时点一致。
滚动窗口的主要参数是 \(k\)。它控制适应速度和统计稳定性:
- 窗口过短,边界变化快,噪声高。
- 窗口过长,边界更新慢,无法适应结构变化。
- 窗口过短时,极端值对当前尺度影响更大。
- 窗口过长时,旧制度仍然影响当前输入。
窗口不是越长越稳,也不是越短越灵敏。需要通过严格的时间外验证选择。
扩展窗口
扩展窗口从初始训练区间开始,随着时间增加持续加入新数据:
\[
min_t = \min(x_1,...,x_{t-1})
\]
\[
max_t = \max(x_1,...,x_{t-1})
\]
它保留完整历史的边界。相比滚动窗口,扩展窗口的统计量变化更慢。适合边界具有长期意义的特征,但对制度切换反应较弱。
滚动窗口和扩展窗口都必须排除未来观测。计算方式不同,时间约束相同。
冷启动阶段不能被忽略
使用窗口长度 \(k\) 时,最初的 \(k\) 个样本没有完整统计量。
常见处理方式:
- 丢弃冷启动区间。
- 使用最小必要样本数后开始计算。
- 先用扩展窗口,再切换到滚动窗口。
- 为模型增加有效样本标志。
不能用完整数据集的统计量填补冷启动期。这样会重新引入未来信息。
Min-Max与其他标准化方法的选择
归一化方法不是模型性能的独立开关。它必须和特征分布、模型结构以及上线机制共同设计。
| 方法 | 计算方式 | 对异常值的敏感度 | 越界特征 | 常见适用场景 |
|---|---|---|---|---|
| Min-Max | (x-min)/(max-min) | 高 | 可以超出目标区间 | 边界稳定、输入范围明确的特征 |
| Z-score | (x-μ)/σ | 较高 | 无固定边界 | 近似连续、需要中心化的特征 |
| 稳健标准化 | 使用中位数和四分位距 | 较低 | 无固定边界 | 含异常值的收益、成交量变化 |
| 小数定标 | x/(10^j) | 取决于原始尺度 | 通常无固定边界 | 数值位数控制 |
| 分位数变换 | 按经验分布映射 | 对极端排序较稳健 | 取决于目标分布 | 分布严重偏斜的特征 |
Z-score标准化为:
\[
x' = \frac{x-\mu}{\sigma}
\]
它把数据转换为中心化、尺度统一的形式。但如果 \(\mu\) 和 \(\sigma\) 使用全样本计算,仍然存在前视偏误。
Z-score也不保证数据服从正态分布。它只减去均值,再除以标准差。原始数据如果具有厚尾、偏斜或多峰结构,变换后仍然保留这些性质。
稳健标准化通常使用中位数和四分位距:
\[
x' = \frac{x-\operatorname{median}(x)}{IQR(x)}
\]
它对极端值的影响较小。但金融收益序列的尾部本身可能包含有效信息。降低尾部权重,不等于提高预测能力。
决策树模型不需要为了形式而归一化
决策树通过阈值切分特征。对单个特征施加保持顺序的单调变换,通常不会改变其候选排序关系。因此,Min-Max对决策树和随机森林的必要性较低。
但以下情况仍可能需要统一尺度:
- 多模型共享同一特征管道。
- 模型中包含距离计算。
- 树模型后接线性层或神经网络。
- 需要统一监控特征漂移。
- 不同资产或不同数据源需要相同接口。
“树模型不敏感”不等于“可以随意泄漏”。数据泄漏发生在预处理阶段,不会因为模型换成随机森林而消失。
归一化与特征工程的时间顺序
特征工程的每一步都可能产生前视偏误。
例如,计算滚动波动率时使用了未来窗口。先用完整数据计算技术指标,再切分训练测试。对全样本做异常值截断。用全量数据填充缺失值。对完整样本进行主成分分析。所有操作都可能把未来分布带入训练过程。
一个可审计的处理流程应当接近下面的顺序:
1. 读取原始数据,并按交易时间排序。
2. 处理明显的数据错误、重复记录和非法值。
3. 执行复权、换月和时间对齐。
4. 在不使用未来的条件下计算基础特征。
5. 按时间切分训练、验证和测试区间。
6. 只用训练区间拟合异常值边界与归一化参数。
7. 将训练参数应用到验证集和测试集。
8. 在滚动回测中按照指定时点更新统计量。
9. 记录越界样本、缺失样本和参数更新时间。
10. 比较离线回测、走步验证和模拟实盘的输入分布。
顺序不能反过来。
尤其不能先对全量特征表调用一个统一的 fit_transform,再进行时间切分。接口写法简洁,不代表统计流程正确。
需要监控的不只是收益指标
归一化错误有时不会立即体现在收益曲线上。应同时监控特征层面的指标:
- 每个特征的最小值和最大值。
- 训练、验证、测试区间的均值和标准差。
- 越界样本比例。
- 被截断到边界的样本数量。
- 缺失值数量。
- 每个时间窗口的统计量变化。
- 输入分布的分位数变化。
- 不同资产之间的尺度差异。
- 归一化前后的相关性变化。
如果测试集几乎没有越界,而历史数据本身存在明显价格突破,这种结果需要检查。它可能来自全局归一化。也可能来自数据截断。输入分布过于理想,通常比输入分布发生漂移更值得怀疑。
一个可执行的验证框架
验证归一化是否正确,不需要先看模型收益。先验证数据管道。
第一步:检查统计量的时间可用性
对每个时点 \(t\),记录用于变换的 min、max、均值和标准差。检查这些统计量是否包含 \(t\) 之后的数据。
如果统计量来自全量数据,流程已经不合格。无需继续比较模型。
第二步:构造故意越界的样本
在测试数据中加入一个超过训练范围的新值,确认系统如何处理:
- 输出是否允许大于1或小于0。
- 是否执行截断。
- 是否更新窗口。
- 是否记录越界事件。
- 模型是否仍然能够接收输入。
这不是为了改变回测结果。是为了验证上线边界行为。
第三步:比较三种变换结果
至少比较:
1. 全局Min-Max。
2. 训练集拟合、测试集固定参数。
3. 滚动或扩展窗口变换。
重点观察输入分布变化,而不是只看收益率。若三种流程的模型结果差异很大,应优先审查泄漏和边界处理。
第四步:执行走步验证
将历史数据按时间推进。每个阶段只允许使用当时已经结束的数据拟合参数和模型。之后在下一段时间测试。
走步验证能暴露两个问题:
- 预处理是否偷看未来。
- 模型是否依赖某一段固定分布。
如果全局归一化结果显著优于走步验证,不能直接解释为模型更强。更可能是评估规则不同。
第五步:分离预处理器与模型
保存模型时,同时保存:
- 特征列表。
- 特征计算版本。
- 归一化方法。
- 统计量。
- 窗口长度。
- 更新频率。
- 边界处理规则。
- 缺失值处理规则。
- 训练数据时间范围。
重新训练时,旧预处理器不能被静默覆盖。否则无法复现历史回测。
哪些情况下Min-Max仍然合理
不能把Min-Max归一化判定为普遍错误。
以下场景中,它仍然有合理用途:
- 特征本身具有稳定的理论上下界。
- 输入来自固定范围的比例或占比。
- 模型结构明确要求固定输入区间。
- 图像类数据中的像素值具有固定边界。
- 训练和部署环境使用完全一致的边界定义。
- 边界由先验规则给出,而不是由未来样本估计。
- 越界行为已经被定义并经过验证。
关键区别在于:边界是否具有外生约束。
如果某个特征天然位于 [0, 1],使用Min-Max没有必要。它已经是有界变量。如果边界来自业务规则,也不需要每次根据历史样本重新拟合。如果边界只是当前数据集中的最大值和最小值,就必须考虑未来突破。
对金融数据而言,样本极值通常不是稳定边界。它只是过去发生过的极值。
参数优化的重点不应是追求最漂亮的分布
归一化参数优化可以从四个方向展开。
优先调整窗口,而不是盲目更换算法
先定义窗口候选范围,再进行走步验证。窗口应与数据频率、策略持有周期和市场状态变化速度一致。
日频趋势策略和高频订单流模型,不应共享同一套窗口逻辑。前者关心较慢的结构变化,后者关心局部状态。窗口长度必须与信号时间尺度一致。
对极端特征进行单独处理
不要让一个成交量尖峰决定所有样本的Min-Max边界。可以将成交量转化为滚动分位数、对数变化或相对均值,再进行标准化。
但每种转换都要在时间窗口内计算。不能使用全样本分位数。
保留越界信息
如果越界本身具有交易含义,不要直接截断。可以拆成两个特征:
- 截断后的归一化值。
- 是否超过训练边界的标记。
这样模型既获得稳定输入,也获得边界突破信息。是否有效,需要通过严格验证确认。不能预设结果。
使用基线模型检查收益是否来自预处理
建立不依赖复杂归一化的基线:
- 线性模型。
- 树模型。
- 简单均值回归模型。
- 仅使用原始收益率和滚动统计量的模型。
如果只有全局Min-Max版本产生明显优势,而时间外测试没有同步改善,优势很可能来自泄漏或分布处理差异。
模型的局限性
正确使用Min-Max,也不能解决金融预测中的核心问题。
它不能:
- 让非平稳价格变成平稳序列。
- 消除结构性断点。
- 修复错误的标签时间。
- 提高低质量数据的预测信息量。
- 替代复权和换月处理。
- 自动处理缺失和重复记录。
- 保证实盘输入落在训练区间内。
- 使神经网络具备预测能力。
- 消除过拟合。
- 产生稳定的交易收益。
它只负责改变坐标尺度。
真正需要控制的是统计量的可用时间、异常值的来源、训练与部署的接口一致性,以及评估过程是否模拟真实上线条件。
金融数据归一化的检查重点,可以压缩为三条:
1. 统计量是否只来自过去。
2. 极值是否代表真实边界。
3. 测试和实盘越界后,系统是否有明确行为。
如果这三点无法回答,换成Z-score、稳健标准化或神经网络都没有意义。模型仍然运行在错误的数据管道上。
Min-Max可以使用。全局Min-Max不应默认使用。对滚动窗口、扩展窗口和固定先验边界分别建模,再用时间外数据验证。最终保留的是可复现、可审计、能处理越界的版本。不是回测曲线最平滑的版本。
相关阅读: 交易员决策疲劳应对策略:减少日内无效交易的系统化方案 、 全职交易员的社交孤立:享受孤独还是走向心理失衡?.
