第 10 章 · 02 t-SNE 与 UMAP 资产流形 本节摘要:PCA 是线性的,但金融数据里的低维结构往往是非线性的。本节讲两大力气充沛的非线性流形学习算法——t-SNE 与 UMAP,以及如何用它们把几百只股票的高维收益数据降到二维做可视化,揭示资产的聚类结构(行业、风格、市场板块)。本节讲清四件事:流形假设(manifold hypothesis)与「瑞士卷」这种非线性结构的直觉;t-SNE 如何通过「概率化近邻 + KL 散度」保局部结构,以及 perplexity 参数的含义;UMAP 如何用「模糊拓扑 + 黎曼几何」做到比 t-SNE 更快且保全局结构;以及把它们应用到美股收益上,对比 PCA 的线性投影效果。
本节摘要:PCA 是线性的,但金融数据里的低维结构往往是非线性的。本节讲两大力气充沛的非线性流形学习算法——t-SNE 与 UMAP,以及如何用它们把几百只股票的高维收益数据降到二维做可视化,揭示资产的聚类结构(行业、风格、市场板块)。本节讲清四件事:流形假设(manifold hypothesis)与「瑞士卷」这种非线性结构的直觉;t-SNE 如何通过「概率化近邻 + KL 散度」保局部结构,以及 perplexity 参数的含义;UMAP 如何用「模糊拓扑 + 黎曼几何」做到比 t-SNE 更快且保全局结构;以及把它们应用到美股收益上,对比 PCA 的线性投影效果。读完本节,你能用流形学习做资产聚类可视化,理解为什么同行业的票会自然聚成一团。
内容来源:原项目
13_unsupervised_learning/02_manifold_learning/03_manifold_learning_tsne_umap.ipynb、04_manifold_learning_asset_prices.ipynb,汉化并套用体系化模板。
⚠️ 学习提示:t-SNE 不能把新数据投影到已学的低维空间(没有 transform),且其输出距离不适合直接喂给基于距离的聚类算法。它是「可视化神器」,但不适合做下游建模的特征工程。
阅读完本节,你应当能够:
PCA 假设数据的主要变异方向是线性的,但真实世界很多数据是「弯曲的」——经典的例子是「瑞士卷」:数据在三维空间里是一张卷起来的二维曲面,PCA 会把卷的两端当成不同的方向,但真正的内在维度是二维。
流形假设(manifold hypothesis):高维数据往往落在(或靠近)一个嵌入高维空间的低维非线性流形上。流形学习的目标是找到这个内在低维结构,在低维里表示数据。
金融里这个假设也成立:几百只股票的日收益看似是几百维,但它们其实被少数几个系统性因子驱动(市场、行业、风格)——把这些因子看作「内在坐标」,资产就分布在一个低维流形上。
t-SNE(van der Maaten & Hinton, 2008)是目前最流行的高维可视化算法。它的核心思想是概率化近邻:
直观理解:t-SNE 不在乎「远的点保持远」,只在乎「近的点保持近」。所以它擅长揭示聚类结构(同类聚一团),但不擅长保留全局距离——两个低维图上离得很远的聚类,在原空间可能只是渐变过渡。
from sklearn.manifold import TSNE for p in [2, 10, 20, 30, 50]: embedding = TSNE(perplexity=p, n_iter=5000).fit_transform(data)
perplexity 是 t-SNE 的关键参数,大致对应「每个点认为多少个邻居是近邻」,典型 5~50。perplexity 小→只关注极近邻→局部分辨率高但全局结构乱;perplexity 大→关注更多邻居→全局更连贯但聚类边界模糊。没有「正确」值,实务里多试几个对比。
| 参数 | 含义 | 影响 |
|---|---|---|
perplexity |
期望近邻数(5~50) | 小→局部,大→全局 |
n_iter |
迭代次数 | 太少未收敛 |
learning_rate |
梯度下降步长 | 太大震荡,太小卡死 |
⚠️ t-SNE 三大坑:其一,不能 transform——新数据无法投影到已学的空间,每次都要重训;其二,复杂度 O(n^2)(后改进到 n \log n),大数据上慢;其三,输出距离不可信,不要把 t-SNE 的 2D 坐标当特征喂给 K-means 等基于距离的算法。
UMAP(McInnes & Healy, 2018)假设数据均匀分布在一个局部连通的流形上,用模糊拓扑表示:把每个点的 k 近邻构造成一个模糊拓扑图,然后在低维找一个拓扑等价的图。
import umap embedding = umap.UMAP(n_neighbors=15, min_dist=0.1).fit_transform(data)
UMAP 相对 t-SNE 的三大优势:
| 优势 | 说明 |
|---|---|
| 更快 | 复杂度更低,大数据上量级领先 |
| 保全局结构 | 同时保留局部近邻与全局拓扑,聚类间的相对位置更可信 |
| 可 transform | 训完能用 transform 投影新数据,可作下游特征工程 |
UMAP 还支持任意距离函数(欧氏、余弦、曼哈顿),处理稀疏高维(如文本的 TF-IDF)时尤其有用。n_neighbors 的作用类似 t-SNE 的 perplexity,控制局部 vs 全局权衡。
💡 选哪个:纯可视化且数据不算大,t-SNE 经验更成熟;数据大或要做下游特征工程,UMAP 综合更强。实务里两个都试,看哪个的二维图更能讲出金融故事。
notebook 04_manifold_learning_asset_prices.ipynb 用 2000-2018 的日度美股收益:
idx = pd.IndexSlice with pd.HDFStore('../../data/assets.h5') as store: returns = (store['quandl/wiki/prices'] .loc[idx['2000':'2018', :], 'adj_close'] .unstack('ticker') .pct_change()) returns = returns.dropna(thresh=int(returns.shape[0] * .95), axis=1) returns = returns.dropna(thresh=int(returns.shape[1] * .95)).clip(lower=-.5, upper=.5) returns = returns.sample(n=250) daily_avg = returns.mean(1) returns = returns.apply(lambda x: x.fillna(daily_avg))
预处理要点:
然后对比 PCA / t-SNE / UMAP 的二维投影:
pca = PCA(n_components=2) pca_proj = pca.fit_transform(returns.T) # 转置:股票是行 tsne_proj = TSNE(perplexity=30, n_iter=5000).fit_transform(returns.T) umap_proj = umap.UMAP(n_neighbors=15).fit_transform(returns.T)
把每只票按行业着色,你会看到:
流形学习在金融里的典型用途是「资产聚类可视化」——把几百只票的二维图画出来,看同行业是否聚拢、有没有「风格异常」的票(行业归属与收益结构不符)。这种探索性分析有助于理解市场结构,但不要把 t-SNE 的二维坐标当作严肃建模的输入——它们是描述性的,不可复现,不可外推。
下一节,我们看 层次风险平价 HRP——用层次聚类做稳健的资产配置,解决传统均值-方差优化对输入敏感的老问题。