np.corrcoef(x.t)可一次性计算特征间相关系数矩阵,但需转置确保按列视为变量;scipy.stats.pearsonr仅支持两两计算并返回r值与p值;二者均要求数据标准化且不适用离散或非线性特征。

用 numpy 和 scipy 计算特征间相关系数矩阵
共线性最直观的信号就是两个或多个特征高度线性相关,np.corrcoef() 或 scipy.stats.pearsonr() 能快速给出两两相关系数,但对高维数据更推荐用 np.corrcoef(X.T) 一次性算出完整矩阵。注意:必须传入 X.T(转置),否则默认按行计算,会把每个样本当一个变量——这是新手最常踩的坑。
实际使用时建议先做标准化(StandardScaler),否则量纲差异大的特征(比如年龄 vs 收入)会让皮尔逊相关系数失真;如果含大量离散变量或存在非线性关系,corrcoef 就不适用,得换 sklearn.feature_selection.mutual_info_classif 或秩相关(scipy.stats.spearmanr)。
用 VIF 定量识别强共线性特征
相关系数只能看两两关系,而 Variance Inflation Factor(VIF)能反映某个特征是否被其余所有特征联合线性解释得“太好”。statsmodels.stats.outliers_influence.variance_inflation_factor 是最直接的实现方式,但要注意它只接受二维 numpy.ndarray,且输入必须是 **不含截距项** 的原始特征矩阵(别提前加一列 1)。
- 一般认为 VIF > 5 表示中度共线性,> 10 则强烈建议处理
- 逐个计算 VIF 时,每次都要剔除当前列再拟合回归,所以速度随特征数增长变慢;超 50 维建议先用相关系数筛掉明显冗余的列再算 VIF
- 若某列全为常数(方差为 0),
variance_inflation_factor会抛LinAlgError: Singular matrix,需提前用np.var(X, axis=0) > 1e-8过滤
用 PCA 实现无监督降维并保留主要方差
sklearn.decomposition.PCA 不依赖标签,适合探索性降维。关键不是盲目设 n_components=2,而是用 explained_variance_ratio_ 看累计贡献率——比如取前 5 个主成分使累计达 0.95,就比硬设数量更可靠。
注意 PCA 对异常值敏感,且结果不可逆还原(除非保存 components_ 和 mean_);如果后续还要解释原始特征重要性,PCA 后的载荷矩阵(pca.components_)比主成分本身更有价值,别只盯着 transform() 结果。
- 务必在 PCA 前用
StandardScaler标准化,否则量纲大的特征会主导主成分方向 -
svd_solver='arpack'在特征数远大于样本数时更稳,避免'full'报内存错误 - 若数据稀疏(如文本 TF-IDF),改用
TruncatedSVD,它不强制中心化,更适合稀疏矩阵
用 selectKBest + f_regression 做有监督特征筛选
如果目标变量已知(回归任务),sklearn.feature_selection.SelectKBest 配合 f_regression 比单纯看共线性更实用:它评估每个特征单独对目标的线性解释力,自动过滤掉虽与其他特征共线、但对 y 本身贡献小的变量。
和 PCA 不同,这一步保留的是原始特征子集,可解释性强;但它无法发现“多个弱特征组合起来才有效”的情况(即协同效应),此时应考虑 RFECV 或树模型的 feature_importances_。
-
f_regression假设线性关系,若 y 和 x 是指数/对数关系,先做np.log1p(x)再跑 - 设置
k='all'可输出所有特征的 F 值和 p 值,方便人工判断阈值 - 若目标是分类问题,换成
f_classif或mutual_info_classif,别混用
真正难的不是选哪个方法,而是理解你手上的数据到底需要“解释性”还是“预测稳定性”:VIF 和 SelectKBest 保特征含义,PCA 保信息压缩效率——选错目标,降维就只是自我安慰。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











