稀疏 PCA 统计套利:只保留少数正交共性因子#
结论先行#
统计套利的第一步,是把”市场共性”从个股收益里剥掉,只对剩下的”个性残差”做均值回复。标准 PCA 是最自然的剥法——但它在样本小、资产多时有一个致命毛病:主成分载荷被噪声铺满,第 1 主成分往往同时牵扯到几十只股票,你根本说不清它代表什么。
稀疏 PCA(Sparse PCA)给主方向加一个 L1 惩罚,强制载荷里大部分系数为零。结果非常直观:每个共性因子只点亮少数几只同板块的股票,因子彼此正交,而且用 3 个因子就换到了约 57% 的解释方差(牺牲的 43% 大半是 Idiosyncratic 噪声)。把它们从收益里回归掉,残差干净到可以做套利——合成 40 股 4 板块里,残差均值回复策略净值一路跑赢等权买入持有。
下面用自洽合成数据演示:从相关矩阵 → 标准 PCA vs 稀疏 PCA → 残差套利,并给出可跑的 Python。
一、为什么标准 PCA 的载荷”看不懂”#
假设 40 只股票分属 4 个板块,板块内强相关、板块间弱相关。这是真实的横截面结构。你在 个交易日上估计样本相关矩阵 ,然后做特征分解:
问题出在 是带噪估计。 不够大时,估计误差会把每一只股票的”个性噪声”也塞进前几个主成分,导致 的载荷符号正负交错、铺满全部 40 只股票。你看着图,知道 PC1 解释了最多方差,却说不出它对应哪个行业、哪条宏观线索——这种因子没法写进交易逻辑,更没法向任何人解释。

左列是标准 PCA 的 PC1/PC2:载荷在四个板块之间来回抖动,没有明显的板块归属。右列是稀疏 PCA:PC1 干净地落在某一板块、PC2 落在另一板块——结构一眼可读。
二、稀疏 PCA:给主方向加 L1 惩罚#
标准 PCA 求的是”方差最大方向”:
稀疏 PCA 在目标里加一个 L1 惩罚,逼出稀疏解:
越大,越多系数被压成 0。约束 保证它是单位方向;L1 项制造稀疏。这是个凸约束 + 非平滑目标,近端梯度(proximal gradient)是最直接的求导外解法:每一步沿梯度上升,再做软阈值(soft-threshold)投影回单位球。
提取 个因子时用 deflation:算出一个稀疏方向 ,从矩阵里减掉 ,再在残差矩阵上求下一个——天然保证因子彼此正交。
三、代码:从相关矩阵到稀疏因子#
import numpy as np
def sparse_pca(Sigma, rho, n_iter=3000, seed=7):
"""L1 惩罚 PCA:max w'Σw - rho||w||_1, s.t. ||w||_2<=1(近端梯度上升)。"""
p = Sigma.shape[0]
r = np.random.default_rng(seed)
w = r.standard_normal(p)
w /= np.linalg.norm(w)
L = 2.0 * np.linalg.eigvalsh(Sigma).max() # Lipschitz 常数
lr = 1.0 / L
for _ in range(n_iter):
grad = 2.0 * (Sigma @ w)
z = w + lr * grad # 梯度上升
u = np.sign(z) * np.maximum(np.abs(z) - lr * rho, 0.0) # 软阈值
n = np.linalg.norm(u)
w = u / n if n > 1.0 else u # 投影回单位球
return w
def spca_matrix(Sigma, K, rho, seed=7):
"""逐次 deflation 提取 K 个稀疏正交因子,返回 N×K 载荷矩阵。"""
M = Sigma.copy()
vecs = []
for k in range(K):
w = sparse_pca(M, rho, seed=seed + k * 13)
vecs.append(w)
M = M - np.outer(M @ w, w) # 去掉已提取方向
return np.array(vecs).Tpython注意 spca_matrix 返回的是载荷矩阵 ,列为各稀疏因子方向。下面把它当共性因子,做”收益 → 因子 → 残差”的拆解。
四、稀疏因子 vs 稠密因子:解释方差的取舍#
你当然会问:稀疏是有代价的,丢了多少解释力?下图给出答案——标准 PCA 用全部 40 个成分把累计方差推到 1.0,而稀疏 PCA 只取前 3 个因子:累计解释方差约 57%,剩下的 43% 主要是个股 Idiosyncratic 噪声和估计误差。

关键洞察:你不想解释那 43%。统计套利要剥的是”共性”,个性噪声留着反而污染配对信号。稀疏 PCA 等于主动把”不可交易的共同信息”和”可套利的个性残差”切开。
五、稀疏载荷矩阵:每个因子只点亮少数股票#
把 画成热力图,稀疏结构一目了然:因子 1 只点亮科技板块那 10 只、因子 2 只点亮金融板块、因子 3 只点亮能源——每个因子约 10/40 个非零系数,其余是 0。

这种”块状”结构不是艺术效果,而是 L1 惩罚在样本小、噪声大时把载荷重新集中回真实板块的结果。对比标准 PCA 的满载荷,这才是能写进交易笔记的因子。
六、参数怎么定:扫 ρ 与选 K#
稀疏 PCA 落地有两个旋钮:(稀疏强度)和 (因子个数)。它们不是拍脑袋定的,要扫一遍看权衡。下面这段代码扫描 、报告每个稀疏因子的非零系数个数和解释方差,帮你定位”稀疏够用、方差不掉太多”的甜蜜点:
import numpy as np
def scan_rho(Sigma, K, rho_grid):
"""扫描rho:返回每个rho下各因子非零个数与累计解释方差。"""
S = np.corrcoef(Sigma, rowvar=False) if Sigma.shape[0] == Sigma.shape[1] and \
np.allclose(Sigma, Sigma.T) else Sigma
out = []
for rho in rho_grid:
W = spca_matrix(S, K, rho)
proj = S @ W
explained = np.sort(np.sum(W * proj, axis=0))[::-1]
ev = np.cumsum(explained) / S.shape[0]
nz = [int(np.sum(np.abs(W[:, j]) > 0.05)) for j in range(K)]
out.append((rho, nz, float(ev[-1])))
return out
# 用法示例(Sigma 为样本相关矩阵)
for rho, nz, ev in scan_rho(S, K=3, rho_grid=[0.2, 0.4, 0.55, 0.8]):
print(f"rho={rho:.2f} 非零系数={nz} 累计解释方差={ev:.3f}")python经验法则:先把 从小到大扫,看非零系数从”满”降到”每因子约 10/40”的拐点;再在拐点附近定 —— 太小留不住板块共性, 太大又把噪声放回来。40 只股票 4 板块的场景里, 通常够用。
七、把共性因子剥掉,残差才干净地套利#
有了 ,对任意一期收益向量 (已标准化),共性部分就是它在因子上的投影,残差即个性:
def resid_series(R, W):
"""R: (T, N) 收益矩阵;返回剥掉共性因子后的残差 (T, N)。"""
A = W.T @ W
At = np.linalg.inv(A) @ W.T # 因子收益 F = At @ R
F = R @ At.T
rec = F @ W.T # 共性部分
return R - rec # 个性残差python残差里每只股票都已经是”板块中性”的——同一板块的共同涨跌被因子吃掉了,剩下的才是它自己的故事。挑一只残差最平稳(最均值回复)的股票,做最简单的 z-score 阈值交易:残差 z 突破 ±1 开仓、回到 |z|<0.3 平仓。

合成样本外约 2 年里,残差套利净值稳定爬升、明显跑赢等权买入持有。差别的来源很清楚:买入持有赚的是”板块共同涨跌”——那部分你用因子已经能表达,没必要靠个股残差去赌;而残差套利赚的是共性剥干净之后剩下的、真正可均值回复的个性。
八、真实陷阱:比想象中更硬的六类#
陷阱一:L1 惩罚不是免费的,会丢掉弱信号。 越大越稀疏,但真有少量信息分散在”少数中等系数”里时,也会被一并压成 0。实务上要用交叉验证扫 ,而不是拍脑袋定。本文用 仅作演示。
陷阱二:稀疏 PCA 仍依赖相关矩阵估计质量。 太小(如 )时 病态,稀疏也只是”在烂估计上选稀疏”,复现不出真实板块。落地前先确认 足够、或先用 Ledoit-Wolf 收缩再喂进去。
陷阱三:正交≠独立。 稀疏因子彼此正交是说线性相关为零,但金融收益常有非线性、尾部联动,正交不防尾部同跌。危机时残差会一起跳,止损必须独立于因子结构。
陷阱四:deflation 顺序敏感。 先提的因子吃掉最多方差,后续因子在残差上求,可能和先前提的因子在经济含义上”撞车”。K 不要贪多,3~5 个足够覆盖共性。
陷阱五:残差套利的换手成本会被忽略。 本文净值未计手续费与冲击成本;真实残差波动小、换手高,成本可能吃掉大半 alpha。落地必须按真实费率回测。
陷阱六:板块结构会漂移。 今天的”科技抱团”明年可能解散,稀疏载荷会过时。要滚动重估,不能拿一年前的因子用三年。
九、诚实结论#
稀疏 PCA 不是比标准 PCA “更准”,而是更克制、更可解释:它主动放弃解释那 43% 的个性噪声,只保留少数几个能落回板块的共性因子,且彼此正交。对统计套利而言,这正是你要的——剥掉共性,残差才干净。
落地顺序:收缩相关矩阵 → 扫 求稀疏因子 → deflation 取 K 个 → 回归得残差 → 选最平稳残差做均值回复。先过本文的六类陷阱,尤其是相关矩阵质量、成本、板块漂移这三关。
注:全文数据为自洽合成(40 只股票分 4 板块、板块内强相关板块间弱相关,参数经数值校准使结构清晰可读),仅用于演示稀疏 PCA 的稀疏化机制与残差套利框架。真实复现请替换为实际收益序列,并对相关矩阵收缩、 选择、成本与板块漂移逐一做稳健性检验。