流形学习资产表征:用降维把高维因子铺成可看的地图
几十个因子把每只资产变成高维空间里的一个点,但这些点往往不是均匀撒开的——它们卷在一张低维曲面(流形)上,比如『板块轮动相位』这条一维曲线被揉进 30 维。PCA 是线性投影,遇到弯曲流形只会把它拍扁、撕裂:把卷在一起的两端硬凑到一块。Isomap 换个距离度量——不走欧氏直线(会穿过流形空洞造成近邻假象),而走 kNN 图上的最短路径(测地距离,沿曲面爬行),再用经典 MDS 展开。合成实验:一条一维流形(swiss-roll 式)升到 30 维,Isomap 的局部近邻保持率 0.927 碾压 PCA 的 0.681——谁挨着谁的结构被保住了。纯 numpy 从零实现 Isomap(kNN 图→Floyd-Warshall 测地距离→MDS),并诚实暴露它的死穴:对近邻数 k 极敏感(k=3 轴相关 0.65、k=40 到 0.88),k 太小图断裂、太大短路穿洞;样本外无自然投影;测地距离 O(n³)。拆穿降维=可视化即真相/Isomap 必胜 PCA/k 随便选/流形假设永成立五类陷阱(中阶)。
先说结论:高维资产表征里,点不是均匀撒开的,而是卷在一张低维曲面上;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 的核心洞察只有一句——在弯曲流形上,欧氏距离说谎,要用测地距离。 它分三步:
- 建 kNN 图:每个点只连它欧氏最近的 k 个邻居(局部上,流形近似平直,欧氏距离可信);
- 算测地距离:图上两点的最短路径长度,近似它们沿流形的真实距离(Floyd-Warshall);
- 经典 MDS:把这个测地距离矩阵嵌到低维,保持距离关系。
def pairwise(A):
s = (A**2).sum(1)
d2 = s[:,None] + s[None,:] - 2*A@A.T
return np.sqrt(np.maximum(d2, 0))
def isomap(A, k=8, dim=2):
Dm = pairwise(A)
nn = np.argsort(Dm, 1)[:, 1:k+1]
G = np.full_like(Dm, np.inf); np.fill_diagonal(G, 0)
for i in range(len(A)):
for j in nn[i]:
G[i,j] = Dm[i,j]; G[j,i] = Dm[i,j] # kNN 图(对称)
for kk in range(len(A)): # Floyd-Warshall 全对最短路
G = np.minimum(G, G[:,kk][:,None] + G[kk,:][None,:])
n = len(A) # 经典 MDS
J = np.eye(n) - np.ones((n,n))/n
B = -0.5 * J @ (G**2) @ J
w, V = np.linalg.eigh(B)
idx = np.argsort(w)[::-1][:dim]
Y = V[:, idx] * np.sqrt(np.maximum(w[idx], 0))
return Y, G
iso2, Gdist = isomap(Xhd, k=8, dim=2)python对照组 PCA 就是标准 SVD 投影:
Xc = Xhd - Xhd.mean(0)
U, S, Vt = np.linalg.svd(Xc, full_matrices=False)
pca2 = Xc @ Vt[:2].Tpython四、欧氏 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.927
- PCA 近邻保持率 0.681
Isomap 保住了 93% 的局部邻里关系,PCA 只有 68%——它在拍扁流形时把大量「本来挨着的点」拆散了。对量化的意义很直接:如果你要用这张低维地图做聚类、找相似资产、构造近邻组合,PCA 的地图上有近三分之一的「邻居」是错的。
六、死穴:k 太小图断裂,太大短路穿洞#
Isomap 不是免费午餐,它对近邻数 k 极其敏感:

实测轴相关随 k 变化:
| k | 3 | 6 | 12 | 40 |
|---|---|---|---|---|
| 轴相关 | 0.653 | 0.695 | 0.748 | 0.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。流形学习是探索阶段的显微镜,不是回测循环里的价格序列——任何降维坐标都不能直接当因子喂进交易信号,这是纪律,不是建议。