SelectKBest 不是黑盒,它仅对每个特征单独计算统计得分并选取最高k个,不考虑特征相关性或交互;选择统计方法需匹配目标变量类型和特征分布,如f_classif用于分类任务的连续特征,chi2要求非负特征和分类目标,f_regression用于回归任务,互信息法可捕获非线性关系但具随机性;错误使用会引发报错或结果失真;通过get_support()获取选中特征布尔掩码,结合原始列名映射更安全;测试集必须用训练好的selector.transform()而非重新fit_transform()以避免数据泄露。

SelectKBest 不是黑盒,它只做一件事:对每个特征单独计算统计得分(比如 f_classif 或 chi2),然后挑出得分最高的 k 个。它不考虑特征之间的相关性,也不建模交互——这点必须先明确,否则后续结果容易误读。
怎么选合适的统计检验方法?
选错方法会导致得分失真,甚至报错。关键看目标变量类型和特征分布:
-
f_classif:目标变量是离散类别(如y是整数标签或字符串),特征是连续型(如浮点数值)。这是分类任务最常用的选择 -
chi2:所有特征和目标变量都必须 ≥ 0(常用于文本 TF-IDF 向量或计数型特征),且目标变量为分类变量 -
f_regression:目标变量是连续值(回归任务),特征也是连续型 -
mutual_info_classif或mutual_info_regression:更灵活,能捕获非线性关系,但结果有随机性(内部用近似估计),需设random_state
常见错误:chi2 输入含负数会直接抛 ValueError: Input X must be non-negative;f_regression 用在分类标签上得分无意义,但不会报错,容易被忽略。
fit_transform 之后,怎么知道哪些特征被留下了?
SelectKBest 本身不保留原始列名,get_support() 是唯一可靠方式:
立即学习“Python免费学习笔记(深入)”;
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
selector = SelectKBest(score_func=f_classif, k=5) X_selected = selector.fit_transform(X, y) mask = selector.get_support() # 返回布尔数组,True 表示被选中 selected_names = [col for col, keep in zip(feature_names, mask) if keep]
注意:selector.scores_ 是原始所有特征的得分数组,顺序与 X 列一致;但 selector.pvalues_ 只在部分检验(如 f_classif)中存在,chi2 就没有 pvalues_ 属性。
为什么训练集筛选后不能直接 transform 测试集?
必须用同一个 selector 实例调用 transform(),而不是重新 fit_transform():
- 训练时:用
selector.fit_transform(X_train, y_train) - 测试时:只能用
selector.transform(X_test)
如果对测试集再 fit_transform,相当于用测试标签 y_test 重新打分选特征——这属于数据泄露,模型评估会严重乐观。更隐蔽的问题是:当 k 大于测试样本数时,f_classif 会因自由度不足报 ZeroDivisionError,而训练阶段没问题,上线才崩。
真正麻烦的是特征维度变化后下游代码没适配:比如硬编码了 X[:, 0] 取第一个特征,筛选后这个位置可能已对应原第7列。别依赖位置索引,用列名 + get_support() 做映射才是稳的。

















