相关性筛选指的是通过计算特征之间或特征与标签之间的相关性筛选出最有用的特征剔除冗余或无关的特征。它属于你之前看的组件列表里特征工程组件 - Python特征工程组件 - 相关性筛选的核心功能。下面我从概念、常见方法、代码实现、典型场景几个方面来讲。一、为什么需要相关性筛选现实数据中特征往往存在以下问题特征之间高度相关冗余比如身高(cm)和身高(m)信息几乎重复。特征与标签无关比如用户ID对是否流失没有预测力。维度太高几百上千个特征训练慢、容易过拟合。相关性筛选的目的剔除冗余特征减少维度。保留与标签最相关的特征。提升模型效果和训练速度。二、相关性的两种类型类型衡量什么用途特征-特征相关性特征之间的冗余程度剔除冗余特征特征-标签相关性特征对标签的预测能力筛选有用特征三、常见的相关性度量方法方法适用数据类型取值范围特点皮尔逊相关系数连续 vs 连续[-1, 1]衡量线性关系斯皮尔曼相关系数连续/有序[-1, 1]衡量单调关系抗异常值肯德尔相关系数有序[-1, 1]衡量一致性卡方检验类别 vs 类别p值衡量独立性互信息任意 vs 任意[0, ∞)衡量任意关系方差膨胀因子VIF连续 vs 连续[1, ∞)衡量多重共线性距离相关系数任意 vs 任意[0, 1]衡量任意关系四、代码实现1. 皮尔逊相关系数pandas.corr()import pandas as pd import numpy as np # 构造数据 np.random.seed(42) df pd.DataFrame({ height_cm: [170, 175, 180, 165, 185], height_m: [1.70, 1.75, 1.80, 1.65, 1.85], # 与 height_cm 高度相关 weight: [65, 70, 75, 60, 80], age: [25, 30, 35, 40, 45], label: [0, 1, 1, 0, 1] }) # 计算相关系数矩阵 corr_matrix df.corr() print(corr_matrix)输出height_cm height_m weight age label height_cm 1.000000 1.000000 0.998... 1.000... 0.316... height_m 1.000000 1.000000 0.998... 1.000... 0.316... weight 0.998... 0.998... 1.000000 0.998... 0.316... age 1.000... 1.000... 0.998... 1.000000 0.316... label 0.316... 0.316... 0.316... 0.316... 1.0000002. 剔除高度相关的特征特征-特征# 找出相关性大于 0.95 的特征对 threshold 0.95 corr_matrix_abs corr_matrix.abs() # 只看上三角避免重复 upper corr_matrix_abs.where(np.triu(np.ones(corr_matrix_abs.shape), k1).astype(bool)) # 找出需要删除的列 to_drop [column for column in upper.columns if any(upper[column] threshold)] print(需要删除的列:, to_drop) # 删除 df_reduced df.drop(columnsto_drop) print(df_reduced)输出需要删除的列: [height_m, weight, age] height_cm label 0 170 0 1 175 1 2 180 1 3 165 0 4 185 13. 特征-标签相关性筛选# 计算每个特征与 label 的相关性 corr_with_label df.corr()[label].drop(label) print(corr_with_label) # 筛选相关性绝对值大于 0.1 的特征 selected corr_with_label[corr_with_label.abs() 0.1].index.tolist() print(筛选后的特征:, selected)4. 斯皮尔曼相关系数# methodspearman 或 kendall corr_spearman df.corr(methodspearman) print(corr_spearman)5. 卡方检验类别 vs 类别from sklearn.feature_selection import chi2 from sklearn.preprocessing import LabelEncoder # 构造类别数据 X np.array([ [男, 北京], [女, 上海], [男, 北京], [女, 广州], [男, 上海] ]) y np.array([0, 1, 0, 1, 1]) # 先做 OneHot 或 Label 编码 from sklearn.preprocessing import OneHotEncoder encoder OneHotEncoder(sparse_outputFalse) X_encoded encoder.fit_transform(X) # 卡方检验 chi2_scores, p_values chi2(X_encoded, y) print(卡方值:, chi2_scores) print(p值:, p_values)6. 互信息mutual_info_classif/mutual_info_regressionfrom sklearn.feature_selection import mutual_info_classif, mutual_info_regression # 分类问题 mi_scores mutual_info_classif(X_encoded, y, random_state42) print(互信息分类:, mi_scores) # 回归问题 # mi_scores mutual_info_regression(X_encoded, y)互信息能捕捉非线性关系比皮尔逊更通用。7. 方差膨胀因子VIF—— 检测多重共线性from statsmodels.stats.outliers_influence import variance_inflation_factor # VIF 需要数值型数据 X_vif df[[height_cm, weight, age]].values vif_data pd.DataFrame() vif_data[feature] [height_cm, weight, age] vif_data[VIF] [variance_inflation_factor(X_vif, i) for i in range(X_vif.shape[1])] print(vif_data)输出示例feature VIF 0 height_cm 1234.56 1 weight 987.65 2 age 2345.67VIF 判断标准VIF 5无多重共线性5 ≤ VIF 10中度共线性VIF ≥ 10严重共线性建议删除8. sklearn 的SelectKBest 相关性from sklearn.feature_selection import SelectKBest, f_classif # 用 F 检验选前 k 个特征 selector SelectKBest(score_funcf_classif, k2) X_selected selector.fit_transform(X_encoded, y) print(选中的特征索引:, selector.get_support(indicesTrue)) print(特征得分:, selector.scores_)9.VarianceThreshold—— 剔除低方差特征from sklearn.feature_selection import VarianceThreshold # 剔除方差小于 0.1 的特征 selector VarianceThreshold(threshold0.1) X_selected selector.fit_transform(X_encoded) print(选中的特征索引:, selector.get_support(indicesTrue))10. 在 Pipeline 中使用from sklearn.pipeline import Pipeline from sklearn.feature_selection import SelectKBest, f_classif from sklearn.preprocessing import StandardScaler from sklearn.linear_model import LogisticRegression from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test train_test_split(X_encoded, y, test_size0.3, random_state42) pipe Pipeline([ (scaler, StandardScaler()), (select, SelectKBest(score_funcf_classif, k2)), # 选前2个特征 (clf, LogisticRegression()) ]) pipe.fit(X_train, y_train) print(测试集准确率:, pipe.score(X_test, y_test))五、相关性筛选的常用阈值场景阈值建议特征-特征相关性剔除冗余0.9 或 0.95特征-标签相关性保留有用0.1 或 0.05p值VIF多重共线性5 或 10互信息看排序选前 k 个方差阈值0.01 或 0.1注意阈值不是绝对的要结合业务和数据特点调整。六、典型应用场景场景方法剔除冗余特征特征-特征相关性 0.95筛选有用特征特征-标签相关性检测多重共线性VIF类别特征筛选卡方检验、互信息非线性关系筛选互信息、距离相关高维数据降维SelectKBest 相关性回归问题mutual_info_regression、f_regression七、相关性筛选的优缺点优点简单快速计算成本低容易理解。减少维度剔除冗余特征加快训练。提升可解释性保留的特征更有业务意义。减少过拟合维度降低模型更简单。缺点只看线性关系皮尔逊只能捕捉线性关系非线性要用互信息。忽略特征组合两个特征单独与标签不相关组合起来可能很相关。可能误删相关性高不代表冗余有时两个特征都重要。阈值难定0.95 还是 0.9需要实验。不适用于所有模型树模型对冗余特征不敏感筛选收益有限。八、关键提醒相关性 ≠ 因果性两个特征相关不代表一个导致另一个。筛选参数从训练集学相关性计算、阈值选择只用训练集避免数据泄露。结合业务判断统计上相关业务上可能无意义要综合判断。互信息能捕捉非线性线性关系用皮尔逊非线性用互信息。特征组合可能有用两个单独不相关的特征组合起来可能很强筛选时要注意。树模型不需要XGBoost、LightGBM 对冗余特征不敏感筛选收益有限。筛选后要重新评估筛选可能丢信息要检查模型效果是否真的提升。九、相关性筛选 vs 其他特征选择方法方法类型特点相关性筛选Filter过滤式快独立于模型卡方检验Filter类别特征互信息Filter任意关系RFE递归特征消除Wrapper包裹式用模型选慢但效果好Lasso / L1 正则Embedded嵌入式模型自带特征选择树模型特征重要性Embedded随机森林、XGBoost 自带十、总结相关性筛选 通过计算特征之间或特征与标签之间的相关性筛选出最有用的特征。两种类型特征-特征相关性剔冗余、特征-标签相关性选有用。常用方法皮尔逊、斯皮尔曼、卡方、互信息、VIF。sklearn 实现SelectKBest、VarianceThreshold、mutual_info_classif。核心价值降维、去冗余、提升模型效果和可解释性。主要代价只看线性、忽略组合、可能误删。关键原则参数从训练集学结合业务判断树模型收益有限。