scikit-learn中f_regression如何处理含缺失值的特征?是否直接丢弃?
问题背景与疑问
我用scikit-learn构建简单回归模型,数据集包含数千个特征、约600行数据。为建立基准模型,我采用SelectKBest(score_func=f_regression, k=50)选择50个最优特征,但目前未对大量存在缺失值的特征做插补或删除操作,想知道这个特征选择策略会如何处理这些带缺失值的特征?
特征选择函数代码
def process_training_and_test_data_for_LG(df): training_datasets = {} test_datasets = {} for drug in df.keys(): print("at "+drug) X = df[drug].drop(["cell_line_name", "ln_IC50","putative_target"], axis=1) y = df[drug]["ln_IC50"] X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=42) #Select 50 top correlated features feature_selector = SelectKBest(score_func=f_regression, k=50) feature_selector.fit(X_train, y_train) X_train = feature_selector.transform(X_train) X_test = feature_selector.transform(X_test) #Add data to relevant dictionaries training_datasets[drug] = [X_train, y_train] test_datasets[drug] = [X_test, y_test] return training_datasets, test_datasets
问题解答
f_regression对缺失值的处理逻辑:
f_regression是通过计算特征与目标变量的皮尔逊相关系数,再转换为F值和p值来打分的。而皮尔逊相关系数计算时会自动忽略包含缺失值的样本行——也就是说,某个特征只要存在缺失值,计算它的得分时只会用该特征无缺失的那些样本数据。SelectKBest的对应行为:
SelectKBest会基于f_regression输出的得分排序,选出前50个得分最高的特征。但这里存在明显隐患:如果某个特征缺失值极多,计算出的相关性可能只基于少量样本,完全不具备代表性,却有可能被选入最终特征集。当前代码的风险:你的代码未做缺失值处理,执行
feature_selector.fit(X_train, y_train)时scikit-learn不会主动报错(除非全特征全是缺失值),但会悄悄丢弃含缺失值的样本进行计算,这会导致:- 不同特征的得分基于不同的样本子集,特征之间的得分不具备可比性;
- 最终选出的特征可能是基于少量样本计算出的“虚假”高相关特征,模型泛化能力极差;
- 后续
transform操作时,测试集里的缺失值会直接保留,进入模型训练/预测阶段,而大多数回归模型(比如线性回归)无法处理缺失值,会直接报错或输出异常结果。
建议的改进步骤:
- 先处理缺失值:在特征选择前,对训练集做缺失值插补(比如用均值、中位数,或者简单的0填充,根据特征类型选择),注意要只基于训练集计算插补统计量,再应用到测试集,避免数据泄露;
- 过滤高缺失率特征:先删除缺失率过高的特征(比如缺失率超过50%的),这类特征本身信息密度极低,没必要参与后续流程;
- 验证特征得分的可靠性:可以查看
feature_selector.scores_和feature_selector.pvalues_,检查那些被选中的特征对应的有效样本量,确认得分的可信度。
内容的提问来源于stack exchange,提问作者LJM
相关产品推荐
相关产品推荐

