Scikit learn 如何结合Scikit学习';s组文件夹和分层文件夹

Scikit learn 如何结合Scikit学习';s组文件夹和分层文件夹,scikit-learn,data-science,k-fold,Scikit Learn,Data Science,K Fold,我正在处理一个不平衡的数据集,该数据集具有来自同一组用户的多个观测值。我想确保在培训和测试集中没有相同的用户,同时尽可能多地保持原始分布。 我一直在尝试结合Sklearn的GroupKFold和StratifiedFold函数,但我有点不知所措。有人知道我如何组合这两个函数吗?def-travelized\u-group\u-k\u fold(X,y,groups,k,seed=None): def stratified_group_k_fold(X, y, groups, k, seed=No

我正在处理一个不平衡的数据集,该数据集具有来自同一组用户的多个观测值。我想确保在培训和测试集中没有相同的用户,同时尽可能多地保持原始分布。 我一直在尝试结合Sklearn的GroupKFold和StratifiedFold函数,但我有点不知所措。有人知道我如何组合这两个函数吗?

def-travelized\u-group\u-k\u fold(X,y,groups,k,seed=None):
def stratified_group_k_fold(X, y, groups, k, seed=None):
    """Source: https://www.kaggle.com/jakubwasikowski/stratified-group-k-fold-cross-validation """
    labels_num = np.max(y) + 1
    y_counts_per_group = collections.defaultdict(lambda: np.zeros(labels_num))
    y_distr = collections.Counter()
    for label, g in zip(y, groups):
        y_counts_per_group[g][label] += 1
        y_distr[label] += 1

    y_counts_per_fold = collections.defaultdict(lambda: np.zeros(labels_num))
    groups_per_fold = collections.defaultdict(set)

    def eval_y_counts_per_fold(y_counts, fold):
        y_counts_per_fold[fold] += y_counts
        std_per_label = []
        for label in range(labels_num):
            label_std = np.std([y_counts_per_fold[i][label] / y_distr[label] for i in range(k)])
            std_per_label.append(label_std)
        y_counts_per_fold[fold] -= y_counts
        return np.mean(std_per_label)

    groups_and_y_counts = list(y_counts_per_group.items())
    random.Random(seed).shuffle(groups_and_y_counts)

    for g, y_counts in sorted(groups_and_y_counts, key=lambda x: -np.std(x[1])):
        best_fold = None
        min_eval = None
        for i in range(k):
            fold_eval = eval_y_counts_per_fold(y_counts, i)
            if min_eval is None or fold_eval < min_eval:
                min_eval = fold_eval
                best_fold = i
        y_counts_per_fold[best_fold] += y_counts
        groups_per_fold[best_fold].add(g)

    all_groups = set(groups)
    for i in range(k):
        train_groups = all_groups - groups_per_fold[i]
        test_groups = groups_per_fold[i]

        train_indices = [i for i, g in enumerate(groups) if g in train_groups]
        test_indices = [i for i, g in enumerate(groups) if g in test_groups]

        yield train_indices, test_indices
资料来源:https://www.kaggle.com/jakubwasikowski/stratified-group-k-fold-cross-validation """ 标签数量=np.最大值(y)+1 y_counts_per_group=collections.defaultdict(lambda:np.zeros(labels_num)) y_Disr=集合。计数器() 对于标签,zip中的g(y,组): 每个组的y_计数[g][label]+=1 y_Disr[标签]+=1 y_counts_per_fold=collections.defaultdict(lambda:np.zeros(labels_num)) 分组每折叠=集合。默认DICT(集合) def eval_y_计数/折叠(y_计数,折叠): y_计数每_折叠[折叠]+=y_计数 标准每标签=[] 对于范围内的标签(标签数量): label_std=np.std([y_counts_per_fold[i][label]/y_distr[label]用于范围(k)]内的i) 标准每标签。附加(标签标准) y_计数每_折叠[折叠]-=y_计数 返回np.平均值(每个标签的标准值) groups_和y_counts=列表(y_counts_per_group.items()) 随机。随机(种子)。洗牌(组和组计数) 对于g,排序后的y_计数(组和y_计数,key=lambda x:-np.std(x[1]): 最佳折叠=无 最小值=无 对于范围(k)内的i: fold\u eval=每折叠一次的评估数量(y数量,i) 如果min_eval为None或fold_eval
def分层组k折叠(X,y,组,k,种子=无):
资料来源:https://www.kaggle.com/jakubwasikowski/stratified-group-k-fold-cross-validation """
标签数量=np.最大值(y)+1
y_counts_per_group=collections.defaultdict(lambda:np.zeros(labels_num))
y_Disr=集合。计数器()
对于标签,zip中的g(y,组):
每个组的y_计数[g][label]+=1
y_Disr[标签]+=1
y_counts_per_fold=collections.defaultdict(lambda:np.zeros(labels_num))
分组每折叠=集合。默认DICT(集合)
def eval_y_计数/折叠(y_计数,折叠):
y_计数每_折叠[折叠]+=y_计数
标准每标签=[]
对于范围内的标签(标签数量):
label_std=np.std([y_counts_per_fold[i][label]/y_distr[label]用于范围(k)]内的i)
标准每标签。附加(标签标准)
y_计数每_折叠[折叠]-=y_计数
返回np.平均值(每个标签的标准值)
groups_和y_counts=列表(y_counts_per_group.items())
随机。随机(种子)。洗牌(组和组计数)
对于g,排序后的y_计数(组和y_计数,key=lambda x:-np.std(x[1]):
最佳折叠=无
最小值=无
对于范围(k)内的i:
fold\u eval=每折叠一次的评估数量(y数量,i)
如果min_eval为None或fold_eval