halo 的技术博客

返回

先说结论:把一段 40 步的价格轨迹压成”均值、波动、动量”几个统计量,等于把一部电影压成三张剧照——路径”怎么走”的信息全丢了。路径签名(path signature)是粗糙路径理论送给机器学习的礼物:用迭代积分把整条轨迹按阶数展开成一列数,一阶是净位移、二阶是 Lévy 面积(路径转了多少圈)、三阶以上编码更精细的时序几何。本文用纯 numpy 从零实现 level-3 截断签名,在三类合成路径上做特征对决:签名特征样本外 IC 0.737,碾压 6 维手工统计特征的 0.597——而消融实验揭示,决定性的信息恰恰藏在传统特征完全无法表达的三阶项里。

一、统计量丢掉了什么#

考虑两段 40 日的价格轨迹:

  • 轨迹 A:稳步上涨 2%,每天涨一点
  • 轨迹 B:先冲高 4% 再回落,最后也停在 +2%

它们的净收益完全相同,波动率也可以调到接近。用”均值+波动+动量”描述,这两条路径几乎无法区分。但对交易者来说它们是两个世界:A 是趋势延续的候选,B 是冲高回落、动能衰竭的信号。

区分它们需要的不是更多统计量,而是路径的形状——先后顺序、往返结构、绕行方向。这正是路径签名的主场。

二、签名是什么:迭代积分的层级展开#

设一条 dd 维路径 X:[0,T]RdX: [0,T] \to \mathbb{R}^d。它的签名是一列迭代积分:

S(i)=0TdXi,S(i,j)=0T0tdXsidXtj,S(i,j,k)=0<r<s<t<TdXridXsjdXtk,S^{(i)} = \int_0^T dX^i, \quad S^{(i,j)} = \int_0^T \int_0^t dX^i_s\, dX^j_t, \quad S^{(i,j,k)} = \iiint_{0<r<s<t<T} dX^i_r\, dX^j_s\, dX^k_t, \dots

直观理解逐级递进:

  • Level-1(dd 项):净位移。就是终点减起点,等价于总收益。
  • Level-2(d2d^2 项):对称部分是位移平方(可由 level-1 导出),反对称部分是 Lévy 面积——路径与其弦围成的有向面积,度量”绕行”:先涨后跌与先跌后涨的 Lévy 面积符号相反。
  • Level-3(d3d^3 项):三重时序嵌套,编码”先怎样、再怎样、后怎样”的三段式结构。

粗糙路径理论给出两个关键定理:(1)唯一性——无限阶签名(在树等价意义下)唯一决定路径;(2)万有性——路径的任何连续泛函都能被签名的线性函数任意逼近。翻译成机器学习语言:签名是路径的”万能特征”,后面接个线性模型理论上就够了。

当然,“理论上”三个字在量化里通常意味着一堆坑,第五节再算账。

时间增广:一个必须做的小动作#

一维价格序列直接算签名会退化(一维路径的高阶签名全由一阶决定)。标准做法是时间增广:把路径写成二维 (t,Pt)(t, P_t),时间做第一个坐标。这样二阶项里的 tdPPdt\int t\, dP - \int P\, dt 就是价格对时间的 Lévy 面积,“先涨后跌”和”匀速上涨”立刻分开。

三、纯 numpy 实现:Chen 恒等式递推#

对分段线性路径,签名不需要数值积分——Chen 恒等式说:两段路径拼接后的签名等于两段签名的张量积。对每个线性小段,签名有解析形式(v,vv2,vvv6v, \frac{v\otimes v}{2}, \frac{v\otimes v\otimes v}{6}),逐段递推即可:

def signature_level3(path):
    """path: (T, d) 分段线性路径 → level-1~3 截断签名 (d + d² + d³ 维)"""
    dx = np.diff(path, axis=0)
    d = dx.shape[1]
    S1 = np.zeros(d); S2 = np.zeros((d, d)); S3 = np.zeros((d, d, d))
    for v in dx:                      # 每个线性段增量 v
        s2 = np.outer(v, v) / 2.0     # 单段的二阶签名
        s3 = np.einsum("i,j,k->ijk", v, v, v) / 6.0
        # Chen 恒等式:新签名 = 旧签名 ⊗ 单段签名,按阶展开
        S3 = S3 + np.einsum("ij,k->ijk", S2, v) \
                + np.einsum("i,jk->ijk", S1, s2) + s3
        S2 = S2 + np.outer(S1, v) + s2
        S1 = S1 + v
    return np.concatenate([S1, S2.ravel(), S3.ravel()])
python

注意更新顺序必须从高阶往低阶写(先 S3 再 S2 再 S1),因为高阶更新要用旧的低阶值——这是实现里最容易翻车的地方。

时间增广后 d=2d=2,level-3 截断共 2+4+8=142 + 4 + 8 = 14 维。每条 40 步路径 14 个数,就是它的”形状指纹”。

四、特征对决:签名 vs 手工统计量#

4.1 实验设计#

合成 2100 条 40 步路径(1500 训练 / 600 测试),三类各占约三分之一,下期收益由路径类型决定

  • 趋势型:带漂移的随机游走,下期收益 = 0.6×漂移(趋势延续)
  • 均值回复型:正弦往返路径(冲高回落或探底回升),下期收益与冲高方向相反(动能衰竭反转)
  • 噪声型:纯随机,下期收益期望为零

三类路径示例

对照组是 6 维手工统计特征:均值、波动率、累计收益、偏度、末 10 日动量、最大回撤——这已经是相当认真的传统特征工程了。两边都接同一个岭回归(λ=5),比样本外 IC。

4.2 结果:0.737 vs 0.597,差距藏在三阶#

IC 对比

特征集维度样本外 IC
手工统计特征60.597
签名 level-120.435
签名 level-1~260.434
签名 level-1~3140.737

三个值得咀嚼的细节:

第一,level-1 单独就有 0.435。 这不奇怪——level-1 就是净位移(总收益),趋势延续的信息它直接携带。

第二,加入 level-2 几乎零增量(0.434)。 这一开始让我怀疑实现有 bug,后来想通了:本实验的关键区分是”往返路径下期反转”,而 Lévy 面积对对称的往返(冲高回落,起点终点几乎重合)幅度有限,且冲高与探底的面积符号相反、与反转方向的关系是非线性的——线性模型吃不动。Lévy 面积分布图也印证了这点:三类路径的面积分布大量重叠,单靠它切不开趋势与回复。

Lévy 面积分布

第三,level-3 一步从 0.434 跳到 0.737。 “先冲高、再回落”是一个三段式时序结构,恰好是三阶迭代积分 r<s<t\iiint_{r<s<t} 的表达范围。手工特征里没有任何一项能写出这个量——你当然可以事后设计一个”前半段收益减后半段收益”的特征,但那是看了答案再出题;签名是不看答案就把所有阶的时序几何系统性列出来,让模型自己挑。

这就是签名的真正卖点:不是某个神奇特征,而是一套完备的、免设计的路径特征基

五、维度爆炸:签名的原罪#

万有性定理的代价写在维度上:dd 维路径的 level-LL 截断签名共 k=1Ldk\sum_{k=1}^{L} d^k 项。

维度爆炸

d=2d=2 时 level-5 才 62 维,还算温柔;但如果你把”价格、成交量、买卖价差、持仓量”加时间做成 d=5d=5 的路径,level-3 就是 155 维,level-5 直接 3905 维——样本稍少就是过拟合火葬场。

工程上的续命三件套:

  1. 压低维度 dd:只放真正正交的通道,时间+价格+成交量(d=3d=3)通常够用;
  2. 低阶截断:金融噪声路径上 level-3~4 之后的高阶项信噪比急剧衰减,截断本身就是正则化;
  3. 对数签名(log-signature):签名的自由李代数坐标,去掉了代数冗余(比如 level-2 对称部分可由 level-1 导出),同样信息维度更紧凑——d=2d=2 level-3 从 14 维压到 5 维。

六、坑位备忘录#

坑一:签名 ≠ 万能钥匙。 万有性定理说的是”存在线性泛函逼近任意连续泛函”,前提是无限阶签名+任意精度。截断到 level-3 后它就是个普通特征集,会过拟合、会失效、需要交叉验证,一样都不少。把定理当营销词是学术裁缝的常见操作。

坑二:签名平移不变,丢掉绝对价位。 签名只依赖路径增量,“从 10 元涨到 12 元”和”从 100 元涨到 102 元”的时间增广签名在归一化后无法区分。如果你的策略逻辑依赖绝对价位(整数关口、历史新高),要额外把这些信息拼回特征里。

坑三:对采样频率敏感。 同一条连续路径,日频采样和分钟频采样的截断签名数值不同(高频路径的二次变差更大)。跨频率比较签名特征前必须统一采样协议,否则是在比较两个不同的东西。

坑四:路径尺度要归一化。 迭代积分是增量的乘积,波动大的路径签名数值天然大好几个量级。本实验中所有路径喂进岭回归前做了标准化;不做的话高波动样本会绑架整个回归。

七、能落地什么#

签名特征最舒服的场景是**“一段窗口的路径形状 → 一个标签”**的监督学习:形态分类(这段像不像顶部结构)、事件后路径聚类(财报后的走势分型)、以及作为 LSTM/Transformer 的替代——签名把变长序列变成定长向量,后面接线性模型或 GBDT,训练成本低一个数量级,且完全可解释到”第几阶第几项”。

反过来,如果你的预测目标只依赖净收益和波动(比如低频资产配置),签名的高阶项就是纯噪声,老老实实用统计特征。先问路径形状是否携带信息,再决定要不要为它付维度的钱——这是比任何定理都有用的一句话。

参考实现#

完整实验代码约 180 行纯 numpy:Chen 恒等式递推签名、时间增广、三类路径模拟、岭回归对决与消融。关键入口:

Xtr, ytr, _ = simulate(1500, seed=1)          # 三类路径 + 由形状决定的下期收益
F = np.array([signature_level3(make_path(x))  # (t/T, 累计收益) 时间增广
              for x in Xtr])                  # 每条路径 → 14 维签名
ic, pred, w = ridge_ic(F, ytr, Fte, yte, lam=5.0)
python

签名不是黑魔法,它只是把”路径怎么走”这件事第一次写成了可以喂给模型的数——剩下的过拟合攻防,和任何特征工程一样,一寸都不能少。

路径签名粗糙路径:用迭代积分把价格轨迹写成可学习的特征
https://blog.halo26812.eu.org/blog/path-signature-rough
Author halo
Published at 2026年7月25日
版权声明 CC BY-NC-SA 4.0
Comment seems to stuck. Try to refresh?✨