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

如何结合SequentialFeatureSelector实现嵌套交叉验证?

嵌套交叉验证中整合SequentialFeatureSelector的问题

我编写了一段嵌套交叉验证循环的代码,但不清楚如何将自带CV语句的SequentialFeatureSelector整合其中。我考虑过参考类似space = dict()的实现方式,或是搭配nested_cv库来实现?代码如下:

# 配置交叉验证流程
outer_k = 10
inner_k = 10
random_st = sample(list(np.arange(0,10,1)),1)[0]
#print(random_st)

cv_inner = KFold(n_splits=inner_k, shuffle=True, random_state=random_st)
cv_outer = KFold(n_splits=outer_k, shuffle=True, random_state=random_st+1)

outer_results = []
for outer_train_ix, outer_test_ix in cv_outer.split(X.index):

    inner_results = []
    for inner_train_ix, inner_test_ix in cv_outer.split(outer_train_ix):
        print("inner_train_ix", inner_train_ix)
        print("inner_test_ix",inner_test_ix)
        
        #inner_results.append(inner_errors)
        
    # 从上述循环中选择最佳模型参数
    
    # 用outer_train_ix拟合最佳模型,并用outer_test_ix计算样本外误差
       
    print("outer_train_ix",outer_train_ix)
    print("outer_test_ix",outer_test_ix)
    #outer_results.append(outer_errors)
        
# 选择在外部(样本外)预测中表现最佳的模型        

方案一:手动整合SequentialFeatureSelector到嵌套循环

SequentialFeatureSelector(SFS)本身支持传入cv参数处理内部交叉验证,无需手动编写内循环的特征选择逻辑,只需在外循环的训练集上初始化SFS,让它自动完成内部特征选择与模型评估。

修改后的代码示例:

from sklearn.feature_selection import SequentialFeatureSelector
from sklearn.model_selection import KFold
import numpy as np
from random import sample
from sklearn.linear_model import LinearRegression  # 示例基础模型,可替换为你的模型

base_model = LinearRegression()

# 配置交叉验证流程
outer_k = 10
inner_k = 10
random_st = sample(list(np.arange(0,10,1)),1)[0]

cv_inner = KFold(n_splits=inner_k, shuffle=True, random_state=random_st)
cv_outer = KFold(n_splits=outer_k, shuffle=True, random_state=random_st+1)

outer_results = []
best_models = []

for outer_train_ix, outer_test_ix in cv_outer.split(X.index):
    # 划分外部训练/测试集
    X_outer_train, X_outer_test = X.iloc[outer_train_ix], X.iloc[outer_test_ix]
    y_outer_train, y_outer_test = y.iloc[outer_train_ix], y.iloc[outer_test_ix]
    
    # 初始化SFS,传入内部CV配置
    sfs = SequentialFeatureSelector(
        base_model,
        n_features_to_select='best',  # 自动选择最优特征数量
        cv=cv_inner,
        scoring='neg_mean_squared_error',  # 根据任务替换评分指标(如分类用'accuracy')
        direction='forward'  # 可选'forward'前向或'backward'后向选择
    )
    
    # 在外部训练集上拟合SFS,自动完成内部交叉验证选特征
    sfs.fit(X_outer_train, y_outer_train)
    
    # 获取选中的特征列
    selected_features = X_outer_train.columns[sfs.get_support()]
    print(f"当前外部折选中特征: {selected_features}")
    
    # 用选中特征拟合最终模型
    best_model = base_model.fit(X_outer_train[selected_features], y_outer_train)
    
    # 计算外部测试集误差
    y_pred = best_model.predict(X_outer_test[selected_features])
    outer_error = np.mean((y_pred - y_outer_test)**2)
    outer_results.append(outer_error)
    best_models.append(best_model)
    
    print(f"当前外部测试集MSE: {outer_error}")

# 选择外部交叉验证中误差最小的模型
best_overall_model = best_models[np.argmin(outer_results)]
print(f"所有外部折平均MSE: {np.mean(outer_results)}")

方案二:使用nested_cv库简化流程

如果想用nested_cv库,可以借助NestedCV类直接整合特征选择与嵌套交叉验证,无需手动编写循环:

from nested_cv import NestedCV
from sklearn.linear_model import LinearRegression
from sklearn.feature_selection import SequentialFeatureSelector

# 定义SFS特征选择器
sfs = SequentialFeatureSelector(
    LinearRegression(),
    n_features_to_select='best',
    cv=10,
    scoring='neg_mean_squared_error'
)

# 配置NestedCV
ncv = NestedCV(
    model=LinearRegression(),
    params_grid={},  # 若模型有超参数,可在此定义网格搜索范围
    outer_kfolds=10,
    inner_kfolds=10,
    feature_selector=sfs,
    random_state=random_st,
    scoring='neg_mean_squared_error'
)

# 运行嵌套交叉验证
ncv.fit(X, y)

# 获取结果
print(f"外部交叉验证平均得分: {ncv.best_score_}")
print(f"最终选中特征: {X.columns[ncv.best_estimator_.named_steps['featureselector'].get_support()]}")

关键注意事项

  • 避免重复内循环:SFS的cv参数已处理内部交叉验证,手动编写内循环会导致逻辑冗余甚至数据泄露。
  • 严格隔离数据:外部测试集绝对不能参与任何特征选择或模型训练步骤,所有特征选择操作必须在外部训练集内部完成。
  • 匹配任务的评分指标:回归任务用neg_mean_squared_error、r2等,分类任务用accuracy、f1等。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 18:54:26