python机器学习 特征选择(Feature Selection)

为什么要做特征选择?

在真实数据中,我们常会遇到:

  • 特征太多(几十、上百个)
  • 有些特征几乎没变化
  • 有些特征高度重复(高度相关)
  • 特征多 →

    • 模型慢
    • 过拟合
    • 可解释性差

用「更少、更有用」的特征 达到「更好或差不多」的模型效果


特征选择三大类(先有概念)

今天我们重点讲 Filter & Wrapper

方法 思想 是否用模型
Filter 用统计方法筛特征
Wrapper 用模型反复试
Embedded 模型自己选 ✅(如 Lasso)

直觉理解

如果一个特征:

  • 几乎所有样本都一样
  • 那它对「区分样本」没什么帮助
ID 是否VIP
A 1
B 1
C 1

没有区分度


sklearn:VarianceThreshold

from sklearn.feature_selection import VarianceThreshold

selector = VarianceThreshold(threshold=0.01)
X_new = selector.fit_transform(X)
  • threshold=0:只移除完全不变的特征
  • 数值越大 → 筛得越严格

什么时候用?

  • 数据刚整理完
  • 特征很多
  • 快速清掉废特征

不看 y(标签),只是纯统计


相关性分析(Correlation Analysis)

两种常见相关性

(1)特征 vs 特征(去冗余)

如果两个特征:

  • 相关系数 ≈ 0.95
  • 表达的是几乎同一件事

os: 留一个就好

import pandas as pd

corr = X.corr()

(2)特征 vs 目标 y(选重要)

corr_with_y = X.join(y).corr()['y'].sort_values(ascending=False)
类型 指标
连续-连续 Pearson
非线性 Spearman
分类目标 点二列相关 / ANOVA

经验法则(教学用)

  • corr > 0.8:高度相关
  • corr < 0.05:几乎没用

os : 相关 ≠ 因果 os : 非线性模型(树、NN)相关性不一定反映重要性


SelectKBest(Filter 方法)

对每个特征「单独打分」 选分数最高的 K 个


常用打分函数

函数 适用场景
f_classif 分类(ANOVA)
chi2 分类(非负特征)
f_regression 回归
mutual_info_* 非线性

示例(分类)

from sklearn.feature_selection import SelectKBest, f_classif

selector = SelectKBest(score_func=f_classif, k=5)
X_new = selector.fit_transform(X, y)

查看得分:

selector.scores_

优缺点

✅ 快 ✅ 简单 ❌ 不考虑特征之间关系


RFE(Recursive Feature Elimination)

思想(很重要)

用模型训练 → 删掉最不重要的特征 → 再训练 → 直到剩下 K 个

📌 真正“用模型来选特征”


示例(逻辑回归)

from sklearn.feature_selection import RFE
from sklearn.linear_model import LogisticRegression

model = LogisticRegression(max_iter=1000)

rfe = RFE(
    estimator=model,
    n_features_to_select=5
)

X_new = rfe.fit_transform(X, y)

3️⃣ 查看结果

rfe.support_   # True / False
rfe.ranking_   # 排名(1 是最重要)

4️⃣ 优缺点

✅ 考虑特征组合 ✅ 模型导向 ❌ 计算慢 ❌ 不适合超大特征数


什么时候用哪一种?

场景 推荐
特征很多 方差筛选 + 相关性
快速 baseline SelectKBest
特征少但要求准 RFE
树模型 常用内建重要性

标准流程

1️⃣ 数据清洗
2️⃣ 方差筛选
3️⃣ 相关性去冗余
4️⃣ SelectKBest / RFE
5️⃣ 建模 + 验证