特征选择:过滤、包裹与嵌入方法
一句话定义
特征选择从 p 个特征中挑出与任务最相关的子集,三大范式是:过滤法(按统计量独立打分)、包裹法(用模型性能搜索子集)、嵌入法(训练过程自带选择,如 L1 与树重要性)。
为什么重要
维度高时:无关特征引入噪声与过拟合、训练与推理成本上升、可解释性崩塌、线上采集成本(每多一个特征就是一条埋点)增加。特征选择还常与降维(kp-021 的 PCA)二选一比较——前者保留原语义、后者压缩正交信息,工程上按「要不要解释」取舍。
前置知识
正则化:岭回归、Lasso 与弹性网 的 L1 稀疏性;主成分分析 PCA 的降维视角;树模型可解释性:特征重要性与 SHAP 的特征重要性概念。
核心概念
- 过滤法(Filter):与模型无关的打分——方差阈值(删常数列)、互信息 MI(X; Y) = ∑ p(x,y)logp(x,y)p(x)p(y)、卡方(非负计数特征)、F 检验(线性相关);快、可扩展、但只看单变量关系。
- 包裹法(Wrapper):以目标模型性能为准绳搜索子集——前向/后向逐步、递归特征消除 RFE(训练→删最不重要→重复)。
- 嵌入法(Embedded):训练即选择——L1/Lasso(kp-008)、树的不纯度重要性、带 L1 的逻辑回归;一次训练顺带出结果。
- 选择偏差风险:在全量数据上做有监督选择再评估 = 泄漏(kp-025),必须折内选择。
- 相关性 ≠ 重要性的陷阱:冗余特征组内互相分摊重要性;交互特征单变量打分可能为零。
直观类比
招聘筛选:过滤法是「先看简历硬条件筛一轮」(学历、年限,快但看不到协作能力);包裹法是「拉进项目试用一轮看业绩」(准但贵,每试一人跑一个项目);嵌入法是「试用期合同上写明表现差自动淘汰」(训练流程内置筛选)。三者成本与准度递进,工程常「过滤粗筛 → 嵌入精选」两级流水。
原理与机制
过滤法的互信息对任意依赖(含非线性、交互)敏感,但估计在高维稀疏下方差大;它逐特征独立打分,无法感知「两个特征各有噪声、合并才有效」的组合结构。包裹法(RFE)直接优化「模型的性能」,能捕捉交互,但每次迭代都要重训,复杂度 O(p) 次训练,且子集搜索本身是 NP-hard 的贪心近似。嵌入法是工程默认:L1 的稀疏性来自次梯度几何(kp-008),树重要性来自分裂增益累计(注意 kp-014 的高基数偏差,精选阶段应换置换重要性校准)。三种方法给出的子集可能差异巨大——因为「对模型 A 重要的特征」不必「对模型 B 重要」,选择必须绑定最终模型族做。
公式与推导
嵌入法的目标(L1 逻辑回归):
wj = 0 的特征即被「训练过程自动淘汰」;λ 由 CV 选,稀疏度随 λ 单调上升。RFE 的淘汰准则:每次删除重要性排序的末尾 s 个特征,St+1 = St ∖ bottoms(rankt),直到 | S | = k;最终子集在 CV 上与候选 k 联合选定(嵌套,防泄漏)。
图示
p 个特征
│ ①过滤:方差/MI/卡方 打分 (快,便宜,单变量)
▼
p′ 个特征
│ ②嵌入:Lasso / 树重要性 (一次训练顺带选择)
▼
p″ ≪ p 个特征
│ ③验证:CV 下确认性能不掉 (折内选择防泄漏)
▼
最终特征集 → 交付(含采集成本说明)实例或案例
过滤 + 嵌入的两级流水(在 Pipeline 内防泄漏):
from sklearn.datasets import make_classification
from sklearn.feature_selection import SelectKBest, mutual_info_classif, RFE
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import cross_val_score
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
import numpy as np
X, y = make_classification(n_samples=600, n_features=30, n_informative=5,
n_redundant=5, random_state=0)
pipe = make_pipeline(StandardScaler(), # 供LR使用
SelectKBest(mutual_info_classif, k=15),
LogisticRegression(penalty="l1", solver="saga", C=0.5, max_iter=3000))
print("过滤+L1 嵌入 CV:", cross_val_score(pipe, X, y, cv=5).mean().round(3))
rfe = RFE(RandomForestClassifier(n_estimators=100, random_state=0, n_jobs=-1), n_features_to_select=10)
print("RFE 包裹 CV:", cross_val_score(make_pipeline(StandardScaler(), rfe,
LogisticRegression(max_iter=2000)), X, y, cv=5).mean().round(3))
print("全特征基线 CV:", cross_val_score(make_pipeline(StandardScaler(),
LogisticRegression(max_iter=2000)), X, y, cv=5).mean().round(3))30 维压到 10~15 维性能不掉甚至略升——无关与冗余特征在拖后腿的直接证据。
常见误区
- 在 CV 外做有监督选择:选择用了标签 → 泄漏虚高(kp-025 的最常见变体)。
- 认为「被选中的特征更重要」:L1 在相关组内的取舍近乎随机,重采样下选择不稳定;报告应看选择频率(stability selection 思想)。
- 用过滤法打分否定交互特征:单变量 MI 对「x1 ⊕ x2 才有效」的结构打零分,交互场景需包裹/嵌入或显式构造交互列。
- 把特征选择与 PCA 混为一谈:选择保留原列(可解释、可采集),PCA 生成混合列(信息更稠但失去原语义)。
与其他知识点的关系
正则化:岭回归、Lasso 与弹性网 的 L1 是嵌入法的数学核心;树模型可解释性:特征重要性与 SHAP 的置换重要性是嵌入打分的纠偏器;主成分分析 PCA 提供对照的降维路线;端到端机器学习工作流与 Pipeline 把选择器作为 Pipeline 标准件;特征工程:编码、缩放与缺失值处理 强调「先构造后选择」的次序。
自测题
- 三大范式的成本与捕捉能力排序?
- 要点:过滤最便宜、只见单变量;嵌入一次训练、捕捉与该模型相关的关系;包裹最贵、最贴合目标模型(捕捉交互)。
- 为什么互信息比皮尔逊相关更适合做过滤打分?
- 要点:相关只测线性单调关系,MI 对任意统计依赖敏感(非线性、离散组合都计入)。
- 如何安全地「用 CV 选特征数量 k」?
- 要点:把选择器放进 Pipeline,让 k 作为超参数参与嵌套/外层验证;绝不在全量数据上先选定 k 再评估。
延伸阅读
Guyon & Elisseeff, An Introduction to Variable and Feature Selection(JMLR, 2003);周志华《机器学习》第 11 章。