为什么要做特征选择?
在真实数据中,我们常会遇到:
- 特征太多(几十、上百个)
- 有些特征几乎没变化
- 有些特征高度重复(高度相关)
-
特征多 →
- 模型慢
- 过拟合
- 可解释性差
用「更少、更有用」的特征 达到「更好或差不多」的模型效果
特征选择三大类(先有概念)
今天我们重点讲 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️⃣ 建模 + 验证