多索引存储的多日相关矩阵数据集如何按日期执行PCA分析
报错根因
直接把全量rolling_cor_monthly(维度6140行×10列)传入LA.eig是触发报错的核心:特征值求解接口仅支持二维方阵输入,非方阵结构会直接触发维度校验报错。由于每个日期分组下刚好是10×10的对称相关矩阵,完全可以逐分组完成PCA计算,最终拼回原有两级多索引结构。
实现代码
import numpy as np import pandas as pd from scipy.linalg import eigh # 对称矩阵专用分解接口,数值稳定无虚数 def pca_per_date(corr_group): # 提取当前日期下的10×10相关矩阵 corr_mat = corr_group.values # 对对称相关矩阵做特征分解,返回升序排列的特征值、特征向量 eigvals, eigvecs = eigh(corr_mat) # 按特征值降序重排,保证第一主成分对应最大方差贡献 sort_order = np.argsort(eigvals)[::-1] sorted_eigvals = eigvals[sort_order] sorted_eigvecs = eigvecs[:, sort_order] # 构造主成分载荷表,完全复用原分组的多索引结构 loadings = pd.DataFrame( data=sorted_eigvecs, index=corr_group.index, columns=[f"PC{i+1}" for i in range(10)] ) # 构造特征值行,追加到当前日期的分组下,保持层级结构统一 eigval_row = pd.DataFrame( data=[sorted_eigvals], index=pd.MultiIndex.from_tuples( [(corr_group.index.get_level_values("Date")[0], "Eigenvalue")], names=corr_group.index.names ), columns=loadings.columns ) return pd.concat([loadings, eigval_row]) # 按一级交易日期分组,逐组计算后合并为完整多索引结果 pca_output = rolling_cor_monthly.groupby(level="Date", group_keys=False).apply(pca_per_date)
结果说明
- 输出的
pca_output完全匹配原数据集的两级多索引结构:一级索引为交易日期,二级索引为对应行业类别+每个日期对应的特征值行 - 每个日期分组下的10行行业数据,对应该期相关矩阵分解得到的主成分载荷,按方差贡献从高到低排序
- 替换原代码中的
LA.eig为eigh的原因:输入为对称相关矩阵,专用分解接口计算速度比通用特征分解快30%以上,不会返回无意义的虚数结果,数值稳定性更高
灵活调整说明
如果需要让输出列名和原数据集保持一致,仅需将loadings构造部分的columns参数替换为corr_group.columns即可,列内容会同步替换为排序后的特征向量值,无需额外调整索引结构。
内容的提问来源于stack exchange,提问作者Bjarne Timm
相关产品推荐
相关产品推荐

