应使用 mutual_info_classif 或 mutual_info_regression 替代皮尔逊相关系数,因其能捕获非线性依赖关系;分类任务需先用 LabelEncoder 编码 y,回归任务保持 y 为数值型;结果为 0–1 归一化信息分值,非 p 值;计算前须对连续特征缩放,推荐手动调用函数而非 SelectKBest 以利于调试;注意高相关特征冗余性,避免预过滤低方差特征;小样本或稀疏数据需谨慎调整 n_neighbors 参数并结合模型验证。

用 mutual_info_classif 或 mutual_info_regression 替代皮尔逊相关系数
皮尔逊相关只抓线性关系,对非线性但强依赖的特征会漏判。比如 y = x² + noise 在 [-1, 1] 上和 y 完全相关,但 np.corrcoef(x, y)[0, 1] 接近 0。Scikit-learn 的互信息函数不假设关系形式,更适合真实数据。
实操建议:
- 分类任务用
mutual_info_classif,回归任务用mutual_info_regression - 必须先对目标变量
y做LabelEncoder(分类)或保持数值型(回归),不能直接传入字符串标签 - 结果是归一化后的信息分值(0~1),不是 p 值,不提供统计显著性,只反映预测能力强度
- 计算前务必用
StandardScaler或MinMaxScaler对连续特征缩放——互信息对数值尺度敏感,未缩放可能导致离散化误差放大
绕过 SelectKBest 手动排序更可控
SelectKBest 封装方便,但隐藏了中间分值,调试时无法判断阈值是否合理。直接调用评分函数拿到数组后手动处理,更利于观察分布。
示例片段:
from sklearn.feature_selection import mutual_info_regression mi_scores = mutual_info_regression(X, y, random_state=42) # 转成 Series 方便排序和可视化 mi_series = pd.Series(mi_scores, index=X.columns).sort_values(ascending=False) # 查看前 10 名 print(mi_series.head(10)) # 筛出得分 > 0.1 的特征 selected_cols = mi_series[mi_series > 0.1].index.tolist()
注意:mutual_info_* 内部会对连续特征做自动离散化(默认 3–5 个分位箱),random_state 必须固定,否则每次运行结果可能浮动。
警惕高相关特征之间的冗余性
互信息高的特征未必都该保留——如果 feature_A 和 feature_B 都与 y 高相关,但二者之间也高度线性相关(比如 corr(feature_A, feature_B) > 0.95),留一个就够了。
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
建议步骤:
- 先用互信息初筛(比如取 top 20)
- 在初筛结果上计算特征间相关系数矩阵,用
np.triu提取上三角 - 找出绝对值 > 0.9 的特征对,按互信息得分保留更高者,删掉另一个
- 避免用
VarianceThreshold预过滤——低方差特征在互信息中可能仍有判别力(如二值特征中 95% 是 0,但那 5% 全对应正样本)
稀疏数据或小样本时 n_neighbors 参数很关键
互信息底层用 k 近邻估计,样本少或特征稀疏时,默认 n_neighbors=3 容易过拟合,导致虚假高分。
调整策略:
- 样本量 n_neighbors=2,避免找不到足够邻居
- 样本量 100–1000:保持默认
n_neighbors=3 - 样本量 > 1000 且含噪声:可试
n_neighbors=5或7,提升稳定性 - 不能设得过大(如 > 10),否则估计会偏向均匀分布,所有分值趋近于 0
这个参数没有银弹,需要结合验证集上的模型性能反向验证——比如用筛选后的特征训练 LightGBM,看 CV 分数是否提升,而不是只盯着互信息数值本身。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










