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

多输出场景下Repeated Stratified K Fold的使用及替代方案

多输出场景下的交叉验证与特征选择方案

核心结论:RepeatedStratifiedKFold不能直接用于多输出任务

RepeatedStratifiedKFold是为单标签分类任务设计的,它要求目标变量y是一维数组(单类别标签),通过维持训练/测试集的类别分布一致实现分层。如果你的任务是多输出场景(比如多标签分类、多任务分类),直接调用会报错,因为它无法处理二维的目标数组。

替代方案分场景选择

根据你的多输出任务类型,对应选择不同的交叉验证策略:

1. 多标签分类任务(单个样本对应多个标签,比如一张图片同时标记为"猫"和"宠物")

使用sklearn.model_selection.MultiLabelStratifiedKFold,它专门针对多标签场景设计,能保证每个折叠中标签组合的分布与原数据集一致,维持分层的有效性。

2. 多任务分类/回归任务(单个样本对应多个独立输出,比如同时预测用户的年龄组和性别)

这类场景没有专门的分层折叠工具,可选择以下两种方式:

  • 普通RepeatedKFold:不做分层,随机划分数据集,适合输出分布相对均衡的情况。
  • 基于核心输出变量分层:如果某一个输出是任务的核心指标,可基于该变量使用RepeatedStratifiedKFold,同时尽量保证其他输出在划分中的合理性。

针对你的代码的修改示例

假设你的任务是多标签分类,修改后的代码如下:

from sklearn import datasets
from numpy import mean, std
from sklearn.datasets import make_classification
from sklearn.model_selection import cross_val_score, MultiLabelStratifiedKFold
from sklearn.feature_selection import RFE
from sklearn.tree import DecisionTreeClassifier
from sklearn.pipeline import Pipeline
from matplotlib import pyplot
from sklearn.multioutput import MultiOutputClassifier  # 多输出分类器包装器

def get_models():
    models = dict()
    for i in range(4,20):
        rfe = RFE(estimator=DecisionTreeClassifier(), n_features_to_select=i)
        # 用MultiOutputClassifier包装单输出模型,适配多输出场景
        model = MultiOutputClassifier(DecisionTreeClassifier())
        models[str(i)] = Pipeline(steps=[('s', rfe), ('m', model)])
    return models

# 假设y是二维多标签数组(示例中取多列作为输出)
x = imp_data.iloc[:,:34]
y = imp_data.iloc[:,39:]  # 修改为多输出列

def evaluate_model(model,x,y):
    # 针对多标签场景使用MultiLabelStratifiedKFold
    cv = MultiLabelStratifiedKFold(n_splits=5, n_repeats=3, random_state=0)
    # 多标签场景下可选择更合适的评分指标,比如'f1_macro'
    scores = cross_val_score(model, x, y, scoring='accuracy', cv=cv, n_jobs=-1, error_score='raise')
    return scores

models = get_models()
results, names = list(), list()
for name,model in models.items():
    scores = evaluate_model(model,x,y)
    results.append(scores)
    names.append(name)
    print('>%s %.3f (%.3f)' % (name, mean(scores), std(scores)))

如果你的任务是多任务分类(多个独立单标签输出),可改用RepeatedKFold:

def evaluate_model(model,x,y):
    cv = RepeatedKFold(n_splits=5, n_repeats=3, random_state=0)
    scores = cross_val_score(model, x, y, scoring='accuracy', cv=cv, n_jobs=-1, error_score='raise')
    return scores

额外注意点

  • 特征选择:RFE默认基于所有输出的综合性能选择特征,如果需要针对每个输出单独做特征选择,需要自定义多输出特征选择逻辑。
  • 评分指标:多输出场景下accuracy可能不是最优选择,建议根据任务需求选用f1_macro、roc_auc等更合适的指标。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 18:21:30