halo 的技术博客

返回

先说结论:高维资产表征里,点不是均匀撒开的,而是卷在一张低维曲面上;PCA 用直线丈量距离,会把这张曲面拍扁、撕裂,Isomap 用『沿曲面爬行』的测地距离,才能把它平整展开。 本文合成实验里,一条一维流形升到 30 维,Isomap 的局部近邻保持率是 0.927,PCA 只有 0.681——差距不在「压了多少方差」,而在「谁挨着谁的邻里关系有没有被保住」。

流形学习资产表征:用降维把高维因子铺成可看的地图

一、问题:高维点云不是一团雾,是一张卷起来的纸#

给每只资产算几十个因子(动量、价值、波动、流动性、质量……),它就成了高维空间里的一个点。直觉会以为这些点在高维里均匀散布,但真实数据几乎从不这样——它们受少数几个潜在驱动支配,实际躺在一个**远低于特征维数的曲面(流形)**上。

一个经典比喻:一张纸本质是二维的,但你把它揉成一团扔进三维空间。纸上任意两点的「真实距离」应该沿纸面量(测地距离),可如果你用三维空间里的直线量(欧氏距离),揉皱处贴在一起的两点会被误判成「很近」,其实它们在纸上隔了半张纸远。

量化里这个场景太常见了:板块轮动相位就是一条一维曲线——资金从周期到成长到防御再回来,是个环。但这条一维的「相位」被几十个因子包裹,在高维里绕成一圈。PCA 这种线性方法只会做正交投影,把环从某个角度拍扁,环的两端就重叠了。

二、合成实验:把一维流形塞进 30 维#

构造一个真相已知的场景:一条一维隐坐标 t(可理解为轮动相位),先做成 swiss-roll 式的三维曲线,再用随机线性映射升到 30 维、加小噪声。

import numpy as np
rng = np.random.default_rng(11)
n = 200
t = np.sort(rng.uniform(0, 1.6*np.pi, n))     # 真实 1 维坐标(轮动相位)
x = t*np.cos(t); z = t*np.sin(t)              # 卷曲
y = 12*rng.uniform(0,1,n)                     # 一点厚度
X3 = np.c_[x, y, z]
D = 30
Rmap = rng.normal(size=(3, D))
Xhd = X3 @ Rmap + rng.normal(0, 0.05, size=(n, D))   # 升到 30 维
color = t                                     # 真实顺序,用于上色/验证
python

目标:只看这 30 维数据,能不能把隐藏的一维相位 t 的顺序还原出来。

三、Isomap 从零实现:换一个距离#

Isomap 的核心洞察只有一句——在弯曲流形上,欧氏距离说谎,要用测地距离。 它分三步:

  1. 建 kNN 图:每个点只连它欧氏最近的 k 个邻居(局部上,流形近似平直,欧氏距离可信);
  2. 算测地距离:图上两点的最短路径长度,近似它们沿流形的真实距离(Floyd-Warshall);
  3. 经典 MDS:把这个测地距离矩阵嵌到低维,保持距离关系。

对照组 PCA 就是标准 SVD 投影:

Xc = Xhd - Xhd.mean(0)
U, S, Vt = np.linalg.svd(Xc, full_matrices=False)
pca2 = Xc @ Vt[:2].T
python

四、欧氏 vs 测地:假象从哪来#

这张图是全文的核心直觉。取流形一端的点做参照,给所有点按「到参照点的距离」上色:

欧氏距离穿越流形空洞,测地距离沿流形爬行

左边用欧氏距离:颜色横跨整个图乱窜——因为直线会直接穿过流形卷曲留下的空洞,把物理上隔了大半圈的点判成近邻。这就是「近邻假象」。右边用测地距离:颜色沿着展开的带子平滑渐变,这才是流形上真实的「远近」。

五、结果:谁保住了邻里关系#

先说一个诚实的观察:单看「嵌入某根轴与真实相位 t 的相关」,PCA 是 0.797,Isomap 是 0.729——PCA 反而略高。为什么还说 Isomap 赢?

因为轴相关是个粗糙的全局指标,它衡量不了「局部结构有没有被撕裂」。真正该看的是局部近邻保持率——嵌入后每个点的 k 近邻,有多少还是它在高维里的原始近邻:

def knn_preserved(hd, emb, k=10):
    Dh, De = pairwise(hd), pairwise(emb)
    nh = np.argsort(Dh,1)[:,1:k+1]; ne = np.argsort(De,1)[:,1:k+1]
    return np.mean([len(set(nh[i]) & set(ne[i]))/k for i in range(len(hd))])
python

局部近邻保持率:Isomap 0.93 vs PCA 0.68

  • Isomap 近邻保持率 0.927
  • PCA 近邻保持率 0.681

Isomap 保住了 93% 的局部邻里关系,PCA 只有 68%——它在拍扁流形时把大量「本来挨着的点」拆散了。对量化的意义很直接:如果你要用这张低维地图做聚类、找相似资产、构造近邻组合,PCA 的地图上有近三分之一的「邻居」是错的。

六、死穴:k 太小图断裂,太大短路穿洞#

Isomap 不是免费午餐,它对近邻数 k 极其敏感:

Isomap 对近邻数 k 的敏感性

实测轴相关随 k 变化:

k361240
轴相关0.6530.6950.7480.880
  • k 太小(k=3):kNN 图可能断裂成几块,测地距离出现无穷大或估计极差,流形展不平;
  • k 太大(k=40):本例里数值上更高,但这是危险的高——k 大到一定程度,图里会出现「短路边」直接穿过流形空洞,Isomap 退化回类欧氏行为,在更弯的流形上会灾难性折叠。

换句话说,k 是 Isomap 的命门,没有万能值,必须针对数据密度和曲率去调,还得检查 kNN 图是否连通。

已知偏差(Limitations and Bias)#

  • 合成流形是干净剧本:真实资产特征的流形没这么规整,维数未知、噪声更大、还随市场状态漂移。这里的 0.93 近邻保持是理想条件下的上限,实盘会明显打折。
  • 样本外无自然投影:Isomap(及多数流形方法)是「直推式」的——它只给训练集里这些点的坐标,来了一只新资产没有现成的投影公式,得重算或用近似(landmark / 核外扩展)。PCA 有显式投影矩阵,这点上更实用。
  • 测地距离贵:Floyd-Warshall 是 O(n³),几百个资产还行,上千就吃力,需换 Dijkstra + 堆或 landmark Isomap。
  • 轴相关与近邻保持可能打架:本文 PCA 轴相关反而更高,说明单一指标会骗人;评估降维必须同时看全局(相关/应力)和局部(近邻保持/trustworthiness),只看一个容易下错结论。

结果解读(Result Interpretation)#

流形学习在量化里的正确定位是『探索性地图』,不是『可交易信号』。 它最擅长回答「这些资产的相似结构长什么样」——把几十维因子压成一张二维图,让你肉眼看出聚类、轮动路径、离群资产。本文实验里 Isomap 把卷曲的相位环平整展开、保住 93% 的邻里关系,这是可视化和聚类的坚实基础。

但别把地图当真相。 三个高频误用:其一,降维图上的距离≠可交易的关系——两只资产在 Isomap 图上靠得近,只说明它们的因子画像相似,不代表价差会收敛,配对交易还得单独验证协整。其二,Isomap 不是永远赢 PCA——如果数据本就近似线性(流形几乎是平面),PCA 又快又稳还能样本外投影,杀鸡不必用牛刀;本文轴相关 PCA 反超就是提醒。其三,流形假设本身可能不成立——不是所有高维数据都躺在低维曲面上,强行套流形方法会「看见」并不存在的结构,这和随机游走里「发现」假周期是同一类错误。

方法选择的分工。 要快、要样本外投影、数据近线性 → PCA;要保住局部邻里、做可视化探索、数据明显弯曲 → Isomap / LLE / t-SNE / UMAP;要可加的『构成』解释、数据非负 → NMF。流形学习是探索阶段的显微镜,不是回测循环里的价格序列——任何降维坐标都不能直接当因子喂进交易信号,这是纪律,不是建议。

流形学习资产表征:用降维把高维因子铺成可看的地图
https://blog.halo26812.eu.org/blog/manifold-learning-assets
Author halo
Published at 2026年7月24日
版权声明 CC BY-NC-SA 4.0
Comment seems to stuck. Try to refresh?✨