You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

添加SelectKBest后模型性能骤降且出现除零警告问题排查

问题分析与解决方案

核心问题1:Pipeline执行顺序完全错误

你把SelectKBest放在了DecisionTreeRegressor之后,这是逻辑错误——特征选择的作用是筛选输入模型的特征,应该先做特征选择,再训练模型。当前流程是先训练模型,再对模型的输出做特征选择,完全偏离了优化模型的目的,这是性能暴跌的主要原因。

核心问题2:特征选择方法不匹配任务类型

你用了f_classif,这是针对分类任务的ANOVA F检验方法,而你的任务是回归,应该使用专门针对回归任务的f_regression。用错方法会导致筛选出的特征与回归目标无关,进一步拉低模型性能。

除零警告的原因

RuntimeWarning: divide by zero encountered in true_divide是因为部分特征在计算F值时,组内均方(msw)为0,比如某分类特征编码后,某个类别只有单一样本,或者特征本身方差为0,导致除法运算出现除零。


修正后的代码

from sklearn.feature_selection import SelectKBest, f_regression  # 替换f_classif为f_regression
from sklearn.tree import DecisionTreeRegressor
from sklearn.pipeline import Pipeline
from sklearn.compose import ColumnTransformer
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import MinMaxScaler, OneHotEncoder
from sklearn.model_selection import KFold, GridSearchCV

numeric_features = ['AGE_2019', 'Inhabitants']
categorical_features = ['familty_type','studying','Job_42','sex','DEGREE', 'Activity_type', 'Nom de la commune', 'city_type', 'DEP', 'INSEE', 'Nom du département', 'reg', 'Nom de la région']

numeric_transformer = Pipeline(steps=[
        ('imputer', SimpleImputer(strategy='median')),
        ('scaler', MinMaxScaler())
])

categorical_transformer = Pipeline(steps=[
        ('imputer', SimpleImputer(strategy='constant',fill_value='missing')),      
        ('encoder', OneHotEncoder(handle_unknown='ignore'))
])

preprocessor = ColumnTransformer(
    transformers=[
    ('numeric', numeric_transformer, numeric_features),
    ('categorical', categorical_transformer, categorical_features)
]) 

# 修正Pipeline顺序:预处理 → 特征选择 → 模型
pipe = Pipeline([
    ('preprocessor', preprocessor),     
    ('selector', SelectKBest(f_regression, k=7)),  # 移到模型前,替换为f_regression
    ('model', DecisionTreeRegressor(random_state=0))
])

dt_params = {'model__min_samples_split': [2, 5] + list(range(10, 250,5))}

cv_folds = KFold(n_splits=5, shuffle=True, random_state=0)

grid_piped = GridSearchCV(pipe, dt_params, cv=cv_folds, n_jobs=-1, scoring=['neg_mean_squared_error', 'r2'], refit='r2')
    
grid_piped.fit(df_X_train,df_Y_train)

额外优化建议

  1. 调整k值:当前固定k=7,建议把k加入网格搜索参数(比如selector__k: [5,7,10,15]),让模型自动选择最优的特征数量。
  2. 过滤低方差特征:在预处理后、特征选择前加入VarianceThreshold(threshold=0),去掉方差为0的特征,避免除零警告:
    from sklearn.feature_selection import VarianceThreshold
    
    pipe = Pipeline([
        ('preprocessor', preprocessor),     
        ('var_filter', VarianceThreshold(threshold=0)),  # 新增低方差过滤
        ('selector', SelectKBest(f_regression, k=7)),
        ('model', DecisionTreeRegressor(random_state=0))
    ])
    
  3. 尝试其他特征选择方法:比如SelectFromModel结合树模型,更适配决策树的特征重要性逻辑。

内容的提问来源于stack exchange,提问作者Gaspard_Boyer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 22:25:20