数据与算法

金融数据归一化:为何Min-Max在量化模型中常被误用

x' = (x - min) / (max - min)

金融数据归一化:为何Min-Max在量化模型中常被误用

公式没有问题。问题在于 minmax 从哪里来。

在普通机器学习任务中,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}

\]

这是一种仿射变换。它不会改变排序关系,也不会自动消除异常值,更不会让金融数据变成正态分布。

金融时间序列的问题在于:minmax 不是固定常数。

价格会创新高。波动率会突然扩张。成交量会产生尖峰。价差会在流动性下降时扩大。宏观数据会出现结构性断点。历史样本的边界不是数据生成机制的边界,只是当前数据集中的两个观测值。

把它们直接拿来定义整个数据集的尺度,相当于假设:

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\),记录用于变换的 minmax、均值和标准差。检查这些统计量是否包含 \(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不应默认使用。对滚动窗口、扩展窗口和固定先验边界分别建模,再用时间外数据验证。最终保留的是可复现、可审计、能处理越界的版本。不是回测曲线最平滑的版本。

相关阅读: 交易员决策疲劳应对策略:减少日内无效交易的系统化方案全职交易员的社交孤立:享受孤独还是走向心理失衡?.

常见问题

为什么在量化模型中不能直接使用全局Min-Max归一化?
全局Min-Max归一化会使用整个数据集的最大值和最小值,这导致训练过程读取了测试区间的未来信息,造成前视偏误,使回测结果虚高。
Min-Max归一化能消除金融数据中的异常值吗?
不能。Min-Max归一化只是一种仿射变换,它不会改变样本间的线性顺序,反而可能因为极值存在而将正常样本压缩在极窄的区间内。
如果实盘数据超过了训练时的Min-Max边界,该如何处理?
处理方式包括允许超出区间以保留突破幅度、强制截断到目标区间,或采用滚动窗口动态更新边界,具体选择取决于模型对边界信息的敏感度。
决策树模型是否可以忽略归一化过程中的时间泄漏?
不可以。虽然树模型对特征缩放不敏感,但数据泄漏发生在预处理阶段,全局拟合的预处理依然会污染评估流程,导致回测结果不可靠。
如何正确地对金融时间序列进行归一化?
应按时间排序数据,在训练区间拟合归一化参数,并将其应用于验证和测试区间;在滚动回测中,应确保每个时点的统计量仅使用该时点之前的数据。