使用StratifiedGroupKFold时test_index为空的问题排查
问题原因及解决办法
核心错误:未传入groups参数
StratifiedGroupKFold是分层分组交叉验证,要求在split()方法中必须传入groups参数来指定每个样本所属的分组。你的代码只传入了x和y,缺少分组信息,导致分组逻辑失效,进而出现test_index为空或异常的情况。
另外,load_breast_cancer数据集本身没有自带分组信息,需要手动为样本生成或指定分组。
修正后的代码示例
方案1:模拟分组数据使用StratifiedGroupKFold
如果确实需要分组验证,可以手动为样本分配分组(比如按索引每100个样本为一组):
import pandas as pd from sklearn.model_selection import StratifiedGroupKFold from sklearn.datasets import load_breast_cancer data = load_breast_cancer() x = pd.DataFrame(data.data) y = pd.DataFrame(data.target) # 模拟分组:每100个样本为一组,最后一组不足100也单独成组 groups = [i // 100 for i in range(len(x))] skf = StratifiedGroupKFold(n_splits=5) fold_no = 1 for train_index, test_index in skf.split(x, y, groups=groups): print(f"Fold {fold_no} test_index: {test_index}") train = x.loc[train_index, :] test = x.loc[test_index] # 计算测试集的类别比例(用标签y而非特征x) ratio = y.loc[test_index].mean().values[0] print(f'Fold {fold_no}, Class Ratio: {ratio:.2f}') fold_no += 1
方案2:不需要分组时用StratifiedKFold
如果你的场景不需要分组,仅需分层交叉验证,直接使用StratifiedKFold即可,无需传入groups:
import pandas as pd from sklearn.model_selection import StratifiedKFold from sklearn.datasets import load_breast_cancer data = load_breast_cancer() x = pd.DataFrame(data.data) y = pd.DataFrame(data.target) skf = StratifiedKFold(n_splits=5) fold_no = 1 for train_index, test_index in skf.split(x, y): print(f"Fold {fold_no} test_index: {test_index}") train = x.loc[train_index, :] test = x.loc[test_index] ratio = y.loc[test_index].mean().values[0] print(f'Fold {fold_no}, Class Ratio: {ratio:.2f}') fold_no += 1
额外注意点
- 你原代码中注释的
ratio = sum(test)/len(test)是错误的:test是特征数据集x,并非标签y,必须用y.loc[test_index]计算类别比例。 StratifiedGroupKFold的核心逻辑是:保证每个fold的类别分布与整体数据一致,同时每个分组的样本只会出现在训练集或测试集中的一方,不会跨集。
内容的提问来源于stack exchange,提问作者Infidus
相关产品推荐
相关产品推荐

