多输出场景下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
相关产品推荐
相关产品推荐

