Scikit-learn: рд╕реНрддрд░реАрдХреГрдд рд╕рдореВрд╣рдХреЗрдлреЛрд▓реНрдб

рдХреЛ рдирд┐рд░реНрдорд┐рдд 11 рдЕрдкреНрд░реИрд▓ 2019  ┬╖  48рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ  ┬╖  рд╕реНрд░реЛрдд: scikit-learn/scikit-learn

рд╡рд┐рд╡рд░рдг

рд╡рд░реНрддрдорд╛рди рдореЗрдВ sklearn рдореЗрдВ рдПрдХ рд╕реНрддрд░реАрдХреГрдд рд╕рдореВрд╣ kfold рд╡рд┐рд╢реЗрд╖рддрд╛ рдирд╣реАрдВ рд╣реИред рдпрд╛ рддреЛ рд╣рдо рд╕реНрддрд░реАрдХрд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдпрд╛ рд╣рдо рд╕рдореВрд╣ kfold рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд╣рд╛рд▓рд╛рдВрдХрд┐, рджреЛрдиреЛрдВ рдХрд╛ рд╣реЛрдирд╛ рдЕрдЪреНрдЫрд╛ рд░рд╣реЗрдЧрд╛ред

рдЕрдЧрд░ рд╣рдо рдЗрд╕реЗ рд▓реЗрдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд░рддреЗ рд╣реИрдВ рддреЛ рдореИрдВ рдЗрд╕реЗ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛ред

рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА

рдпрд╣ рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ рдпрджрд┐ рд░реБрдЪрд┐ рд░рдЦрдиреЗ рд╡рд╛рд▓реЗ рд▓реЛрдЧ рдЕрдкрдиреЗ рдЙрдкрдпреЛрдЧ-рдорд╛рдорд▓реЗ рдХрд╛ рд╡рд░реНрдгрди рдХрд░ рд╕рдХреЗрдВ рдФрд░ рд╡реЗ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЗрд╕рд╕реЗ рдХреНрдпрд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред

рдЬрдм рдЖрдк рдмрд╛рд░-рдмрд╛рд░ рдЙрдкрд╛рдп рдХрд░рддреЗ рд╣реИрдВ рддреЛ рджрд╡рд╛ рдФрд░ рдЬреАрд╡ рд╡рд┐рдЬреНрдЮрд╛рди рдореЗрдВ рдмрд╣реБрдд рд╣реА рд╕рд╛рдорд╛рдиреНрдп рдЙрдкрдпреЛрдЧ-рдорд╛рдорд▓рд╛ рд╣реЛрддрд╛ рд╣реИред
рдПрдХ рдЙрджрд╛рд╣рд░рдг: рдорд╛рди рд▓реЗрдВ рдХрд┐ рдЖрдк рдХрд┐рд╕реА рдмреАрдорд╛рд░реА рдХреЛ рд╡рд░реНрдЧреАрдХреГрдд рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рдЬреИрд╕реЗ рдЕрд▓реНрдЬрд╛рдЗрдорд░ рд░реЛрдЧ (рдПрдбреА) рдмрдирд╛рдо рдПрдордЖрд░ рдЫрд╡рд┐рдпреЛрдВ рд╕реЗ рд╕реНрд╡рд╕реНрде рдирд┐рдпрдВрддреНрд░рдгред рдПрдХ рд╣реА рд╡рд┐рд╖рдп рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЗ рдкрд╛рд╕ рдХрдИ рд╕реНрдХреИрди рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ (рдЕрдиреБрд╡рд░реНрддреА рд╕рддреНрд░реЛрдВ рдпрд╛ рдЕрдиреБрджреИрд░реНрдзреНрдп рдбреЗрдЯрд╛ рд╕реЗ)ред рдорд╛рди рд▓реЗрдВ рдХрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдХреБрд▓ 1000 рд╡рд┐рд╖рдп рд╣реИрдВ, рдЙрдирдореЗрдВ рд╕реЗ 200 рдХрд╛ рдирд┐рджрд╛рди AD (рдЕрд╕рдВрддреБрд▓рд┐рдд рд╡рд░реНрдЧ) рд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИред рдЕрдзрд┐рдХрд╛рдВрд╢ рд╡рд┐рд╖рдпреЛрдВ рдореЗрдВ рдПрдХ рд╕реНрдХреИрди рд╣реЛрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЙрдирдореЗрдВ рд╕реЗ рдХреБрдЫ рдХреЗ рд▓рд┐рдП 2 рдпрд╛ 3 рдЫрд╡рд┐рдпрд╛рдВ рдЙрдкрд▓рдмреНрдз рд╣реЛрддреА рд╣реИрдВред рдХреНрд▓рд╛рд╕рд┐рдлрд╛рдпрд░рд┐рдпрд░ рдХрд╛ рдкреНрд░рд╢рд┐рдХреНрд╖рдг/рдкрд░реАрдХреНрд╖рдг рдХрд░рддреЗ рд╕рдордп, рдЖрдк рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдХрд┐ рдбреЗрдЯрд╛ рд░рд┐рд╕рд╛рд╡ рд╕реЗ рдмрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╣реА рд╡рд┐рд╖рдп рдХреА рдЫрд╡рд┐рдпрд╛рдВ рд╣рдореЗрд╢рд╛ рдПрдХ рд╣реА рддрд╣ рдореЗрдВ рд╣реЛрдВред
рдЗрд╕рдХреЗ рд▓рд┐рдП рд╕реНрдЯреНрд░реИрдЯрд┐рдлрд╛рдЗрдбрдЧреНрд░реБрдкрдХреЗрдлреЛрд▓реНрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рд╣реИ: рд╡рд░реНрдЧ рдЕрд╕рдВрддреБрд▓рди рдХреЗ рд▓рд┐рдП рдЦрд╛рддреЗ рдореЗрдВ рд╕реНрддрд░реАрдХрд░рдг рдХрд░реЗрдВ рд▓реЗрдХрд┐рди рд╕рдореВрд╣ рдХреА рдмрд╛рдзрд╛ рдХреЗ рд╕рд╛рде рдХрд┐ рдПрдХ рд╡рд┐рд╖рдп рдЕрд▓рдЧ-рдЕрд▓рдЧ рддрд╣реЛрдВ рдореЗрдВ рдкреНрд░рдХрдЯ рдирд╣реАрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред
рдПрдирдмреА: рдЗрд╕реЗ рджреЛрд╣рд░рд╛рдиреЗ рдпреЛрдЧреНрдп рдмрдирд╛рдирд╛ рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ред

рдХрд╛рдЧрд▓-рдХрд░реНрдиреЗрд▓ рд╕реЗ рдкреНрд░реЗрд░рд┐рдд рдПрдХ рдЙрджрд╛рд╣рд░рдг рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рдиреАрдЪреЗред

import numpy as np
from collections import Counter, defaultdict
from sklearn.utils import check_random_state

class RepeatedStratifiedGroupKFold():

    def __init__(self, n_splits=5, n_repeats=1, random_state=None):
        self.n_splits = n_splits
        self.n_repeats = n_repeats
        self.random_state = random_state

    # Implementation based on this kaggle kernel:
    #    https://www.kaggle.com/jakubwasikowski/stratified-group-k-fold-cross-validation
    def split(self, X, y=None, groups=None):
        k = self.n_splits
        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)

        rnd = check_random_state(self.random_state)
        for repeat in range(self.n_repeats):
            labels_num = np.max(y) + 1
            y_counts_per_group = defaultdict(lambda: np.zeros(labels_num))
            y_distr = Counter()
            for label, g in zip(y, groups):
                y_counts_per_group[g][label] += 1
                y_distr[label] += 1

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

            groups_and_y_counts = list(y_counts_per_group.items())
            rnd.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

RepeatedStratifiedKFold (рдПрдХ рд╣реА рд╕рдореВрд╣ рдХрд╛ рдирдореВрдирд╛ рджреЛрдиреЛрдВ рддрд╣реЛрдВ рдореЗрдВ рджрд┐рдЦрд╛рдИ рджреЗ рд╕рдХрддрд╛ рд╣реИ) рдХреА рддреБрд▓рдирд╛ RepeatedStratifiedGroupKFold рд╕реЗ рдХрд░рдирд╛:

import matplotlib.pyplot as plt
from sklearn import model_selection

def plot_cv_indices(cv, X, y, group, ax, n_splits, lw=10):
    for ii, (tr, tt) in enumerate(cv.split(X=X, y=y, groups=group)):
        indices = np.array([np.nan] * len(X))
        indices[tt] = 1
        indices[tr] = 0

        ax.scatter(range(len(indices)), [ii + .5] * len(indices),
                   c=indices, marker='_', lw=lw, cmap=plt.cm.coolwarm,
                   vmin=-.2, vmax=1.2)

    ax.scatter(range(len(X)), [ii + 1.5] * len(X), c=y, marker='_',
               lw=lw, cmap=plt.cm.Paired)
    ax.scatter(range(len(X)), [ii + 2.5] * len(X), c=group, marker='_',
               lw=lw, cmap=plt.cm.tab20c)

    yticklabels = list(range(n_splits)) + ['class', 'group']
    ax.set(yticks=np.arange(n_splits+2) + .5, yticklabels=yticklabels,
           xlabel='Sample index', ylabel="CV iteration",
           ylim=[n_splits+2.2, -.2], xlim=[0, 100])
    ax.set_title('{}'.format(type(cv).__name__), fontsize=15)


# demonstration
np.random.seed(1338)
n_splits = 4
n_repeats=5


# Generate the class/group data
n_points = 100
X = np.random.randn(100, 10)

percentiles_classes = [.4, .6]
y = np.hstack([[ii] * int(100 * perc) for ii, perc in enumerate(percentiles_classes)])

# Evenly spaced groups
g = np.hstack([[ii] * 5 for ii in range(20)])


fig, ax = plt.subplots(1,2, figsize=(14,4))

cv_nogrp = model_selection.RepeatedStratifiedKFold(n_splits=n_splits,
                                                   n_repeats=n_repeats,
                                                   random_state=1338)
cv_grp = RepeatedStratifiedGroupKFold(n_splits=n_splits,
                                      n_repeats=n_repeats,
                                      random_state=1338)

plot_cv_indices(cv_nogrp, X, y, g, ax[0], n_splits * n_repeats)
plot_cv_indices(cv_grp, X, y, g, ax[1], n_splits * n_repeats)

plt.show()

RepeatedStratifiedGroupKFold_demo

рд╕рднреА 48 рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

@TomDLT @NicolasHug рдЖрдк рдХреНрдпрд╛ рд╕реЛрдЪрддреЗ рд╣реИрдВ?

рд╕рд┐рджреНрдзрд╛рдВрдд рд░реВрдк рдореЗрдВ рджрд┐рд▓рдЪрд╕реНрдк рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдпрд╣ рд╡реНрдпрд╡рд╣рд╛рд░ рдореЗрдВ рдХрд┐рддрдирд╛ рдЙрдкрдпреЛрдЧреА рд╣реЛрдЧрд╛ред рд╣рдо рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдЗрд╕ рдореБрджреНрджреЗ рдХреЛ рдЦреБрд▓рд╛ рд░рдЦ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдХрд┐рддрдиреЗ рд▓реЛрдЧ рдЗрд╕ рд╕реБрд╡рд┐рдзрд╛ рдХрд╛ рдЕрдиреБрд░реЛрдз рдХрд░рддреЗ рд╣реИрдВ

рдХреНрдпрд╛ рдЖрдк рдорд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рд╕рдореВрд╣ рдПрдХ рд╣реА рдХрдХреНрд╖рд╛ рдореЗрдВ рд╣реИ?

рдпрд╣ рднреА рджреЗрдЦреЗрдВ #9413

@jnothman рд╣рд╛рдБ, рдореЗрд░реЗ рдорди рдореЗрдВ рднреА рдХреБрдЫ рдРрд╕рд╛ рд╣реА рдерд╛ред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдореИрдВ рджреЗрдЦрддрд╛ рд╣реВрдВ рдХрд┐ рдкреБрд▓ рдЕрдиреБрд░реЛрдз рдЕрднреА рднреА рдЦреБрд▓рд╛ рд╣реИред рдореЗрд░рд╛ рдорддрд▓рдм рдерд╛ рдХрд┐ рдПрдХ рд╕рдореВрд╣ рдХреЛ рд╕рд┐рд▓рд╡рдЯреЛрдВ рдореЗрдВ рджреЛрд╣рд░рд╛рдпрд╛ рдирд╣реАрдВ рдЬрд╛рдПрдЧрд╛ред рдпрджрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд╕рдореВрд╣реЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ рдЖрдИрдбреА рд╣реИ рддреЛ рдПрдХ рд╣реА рдЖрдИрдбреА рдХрдИ рддрд╣реЛрдВ рдореЗрдВ рдирд╣реАрдВ рд╣реЛрдЧреА

рдореИрдВ рд╕рдордЭрддрд╛ рд╣реВрдВ рдХрд┐ рдпрд╣ RFECV рдХреЗ рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рд╣реИред
рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдпрд╣ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ StratifiedKFold cv рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред рдЗрд╕рдХрд╛ рдлрд┐рдЯ () рднреА рд╕рдореВрд╣ рд▓реЗрддрд╛ рд╣реИ=
рд╣рд╛рд▓рд╛рдВрдХрд┐: рдРрд╕рд╛ рдкреНрд░рддреАрдд рд╣реЛрддрд╛ рд╣реИ рдХрд┐ рдлрд┐рдЯ() рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рддреЗ рд╕рдордп рд╕рдореВрд╣реЛрдВ рдХрд╛ рд╕рдореНрдорд╛рди рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдХреЛрдИ рдЪреЗрддрд╛рд╡рдиреА рдирд╣реАрдВ (рдПрдХ рдмрдЧ рдорд╛рдирд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ)ред

рдЗрдВрдЯрд░-рд░рд┐рдХреЙрд░реНрдб рдирд┐рд░реНрднрд░рддрд╛ рдХреЗ рд╕рд╛рде рдХрд╛рдлреА рдЕрд╕рдВрддреБрд▓рд┐рдд рдбреЗрдЯрд╛рд╕реЗрдЯ рдХреЗ рд▓рд┐рдП рд╕рдореВрд╣реАрдХрд░рдг рдФрд░ рд╕реНрддрд░реАрдХрд░рдг рдЙрдкрдпреЛрдЧреА рд╣реИрдВ
(рдореЗрд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдПрдХ рд╣реА рд╡реНрдпрдХреНрддрд┐ рдХреЗ рдХрдИ рд░рд┐рдХреЙрд░реНрдб рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЕрднреА рднреА рдмрдбрд╝реА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рд╕рдореВрд╣ рд╣реИрдВ = рд╡рд┐рднрд╛рдЬрди рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЗ рд╕рд╛рдкреЗрдХреНрд╖ рд▓реЛрдЧ; рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рд╕рдорд╕реНрдпрд╛рдПрдВ рд╣реЛрдВрдЧреА рдХреНрдпреЛрдВрдХрд┐ рдЕрд▓реНрдкрд╕рдВрдЦреНрдпрдХ рд╡рд░реНрдЧ рдореЗрдВ рдЕрджреНрд╡рд┐рддреАрдп рд╕рдореВрд╣реЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХрд╣реАрдВ рднреА рд╣реЛ рдЬрд╛рддреА рд╣реИ рд╡рд┐рднрд╛рдЬрди рдХреА рд╕рдВрдЦреНрдпрд╛)ред

рддреЛ: +1!

рдпрд╣ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдЙрдкрдпреЛрдЧреА рд╣реЛрдЧрд╛ред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЕрддреНрдпрдзрд┐рдХ рдЕрд╕рдВрддреБрд▓рд┐рдд рд╕рдордп-рд╢реНрд░реГрдВрдЦрд▓рд╛ рдЪрд┐рдХрд┐рддреНрд╕рд╛ рдбреЗрдЯрд╛ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдирд╛, рд░реЛрдЧрд┐рдпреЛрдВ рдХреЛ рдЕрд▓рдЧ рд░рдЦрдирд╛ рд▓реЗрдХрд┐рди (рд▓рдЧрднрдЧ) рдЕрд╕рдВрддреБрд▓рд┐рдд рд╡рд░реНрдЧ рдХреЛ рдкреНрд░рддреНрдпреЗрдХ рддрд╣ рдореЗрдВ рд╕рдВрддреБрд▓рд┐рдд рдХрд░рдирд╛ред

рдореИрдВрдиреЗ рдпрд╣ рднреА рдкрд╛рдпрд╛ рд╣реИ рдХрд┐ рд╕реНрдЯреНрд░реИрдЯрд┐рдлрд╛рдЗрдбрдХреЗрдлреЛрд▓реНрдб рд╕рдореВрд╣реЛрдВ рдХреЛ рдПрдХ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ рд▓реЗрддрд╛ рд╣реИ рд▓реЗрдХрд┐рди рдЙрдирдХреЗ рдЕрдиреБрд╕рд╛рд░ рд╕рдореВрд╣ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рд╢рд╛рдпрдж рдЗрд╕реЗ рдзреНрд╡рдЬрд╛рдВрдХрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред

рдЗрд╕ рд╕реБрд╡рд┐рдзрд╛ рдХрд╛ рдПрдХ рдФрд░ рдЕрдЪреНрдЫрд╛ рдЙрдкрдпреЛрдЧ рд╡рд┐рддреНрддреАрдп рдбреЗрдЯрд╛ рд╣реЛрдЧрд╛, рдЬреЛ рдЖрдорддреМрд░ рдкрд░ рдмрд╣реБрдд рдЕрд╕рдВрддреБрд▓рд┐рдд рд╣реЛрддрд╛ рд╣реИред рдореЗрд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдореЗрд░реЗ рдкрд╛рд╕ рдПрдХ рд╣реА рдЗрдХрд╛рдИ рдХреЗ рд▓рд┐рдП рдХрдИ рд░рд┐рдХреЙрд░реНрдбреНрд╕ рдХреЗ рд╕рд╛рде рдЕрддреНрдпрдзрд┐рдХ рдЕрд╕рдВрддреБрд▓рд┐рдд рдбреЗрдЯрд╛рд╕реЗрдЯ рд╣реИ (рд╕рдордп рдореЗрдВ рдХреЗрд╡рд▓ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдмрд┐рдВрджреБ)ред рд╣рдо рд░рд┐рд╕рд╛рд╡ рд╕реЗ рдмрдЪрдиреЗ рдХреЗ рд▓рд┐рдП GroupKFold рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╕рд╛рде рд╣реА рд╕реНрддрд░реАрдХрд░рдг рднреА рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдХреНрдпреЛрдВрдХрд┐ рдЙрдЪреНрдЪ рдЕрд╕рдВрддреБрд▓рди рдХреЗ рдХрд╛рд░рдг, рд╣рдо рдмрд╣реБрдд рдХрдо рдпрд╛ рдХреЛрдИ рд╕рдХрд╛рд░рд╛рддреНрдордХ рд╕рдореВрд╣ рд╡рд╛рд▓реЗ рд╕рдореВрд╣реЛрдВ рдХреЗ рд╕рд╛рде рд╕рдорд╛рдкреНрдд рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред

рдпрд╣ рднреА рджреЗрдЦреЗрдВ #14524 рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ?

рд╕реНрдЯреНрд░реЗрдЯрд┐рдлрд╛рдЗрдб рдЧреНрд░реБрдкрд╢рдлрд▓рд╕реНрдкреНрд▓рд┐рдЯ рдФрд░ рдЧреНрд░реБрдкрдХреЗрдлреЛрд▓реНрдб рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрдиреНрдп рдЙрдкрдпреЛрдЧ рдХреЗрд╕ рдЬреИрд╡рд┐рдХ "рджреЛрд╣рд░рд╛рдП рдЧрдП рдЙрдкрд╛рдп" рдбрд┐рдЬрд╛рдЗрди рд╣реИрдВ, рдЬрд╣рд╛рдВ рдЖрдкрдХреЗ рдкрд╛рд╕ рдкреНрд░рддрд┐ рд╡рд┐рд╖рдп рдпрд╛ рдЕрдиреНрдп рдореВрд▓ рдЬреИрд╡рд┐рдХ рдЗрдХрд╛рдИ рдХреЗ рдХрдИ рдирдореВрдиреЗ рд╣реИрдВред рдЬреАрд╡ рд╡рд┐рдЬреНрдЮрд╛рди рдореЗрдВ рдХрдИ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рджреБрдирд┐рдпрд╛ рдХреЗ рдбреЗрдЯрд╛рд╕реЗрдЯ рдореЗрдВ рднреА рд╡рд░реНрдЧ рдЕрд╕рдВрддреБрд▓рди рд╣реИред рдирдореВрдиреЛрдВ рдХреЗ рдкреНрд░рддреНрдпреЗрдХ рд╕рдореВрд╣ рдореЗрдВ рдПрдХ рд╣реА рд╡рд░реНрдЧ рд╣реЛрддрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП рд╕рдореВрд╣реЛрдВ рдХреЛ рдПрдХ рд╕рд╛рде рд░рдЦрдирд╛ рдФрд░ рд░рдЦрдирд╛ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИред

рд╡рд┐рд╡рд░рдг

рд╡рд░реНрддрдорд╛рди рдореЗрдВ sklearn рдореЗрдВ рдПрдХ рд╕реНрддрд░реАрдХреГрдд рд╕рдореВрд╣ kfold рд╡рд┐рд╢реЗрд╖рддрд╛ рдирд╣реАрдВ рд╣реИред рдпрд╛ рддреЛ рд╣рдо рд╕реНрддрд░реАрдХрд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдпрд╛ рд╣рдо рд╕рдореВрд╣ kfold рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд╣рд╛рд▓рд╛рдВрдХрд┐, рджреЛрдиреЛрдВ рдХрд╛ рд╣реЛрдирд╛ рдЕрдЪреНрдЫрд╛ рд░рд╣реЗрдЧрд╛ред

рдЕрдЧрд░ рд╣рдо рдЗрд╕реЗ рд▓реЗрдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд░рддреЗ рд╣реИрдВ рддреЛ рдореИрдВ рдЗрд╕реЗ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛ред

рдирдорд╕реНрддреЗ, рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рджрд╡рд╛ рдПрдордПрд▓ рдХреЗ рд▓рд┐рдП рдХрд╛рдлреА рдЙрдкрдпреЛрдЧреА рд╣реЛрдЧрд╛ред рдХреНрдпрд╛ рдпрд╣ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд▓рд╛рдЧреВ рд╣реИ?

@amueller рдХреНрдпрд╛ рдЖрдкрдХреЛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╣рдореЗрдВ рдЗрд╕реЗ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рдпрд╣ рджреЗрдЦрддреЗ рд╣реБрдП рдХрд┐ рд▓реЛрдЧ рдЗрд╕рдореЗрдВ рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВ?

рдореБрдЭреЗ рднреА рдмрд╣реБрдд рджрд┐рд▓рдЪрд╕реНрдкреА рд╣реИ ... рдпрд╣ рд╕реНрдкреЗрдХреНрдЯреНрд░реЛрд╕реНрдХреЛрдкреА рдореЗрдВ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЙрдкрдпреЛрдЧреА рд╣реЛрдЧрд╛ рдЬрдм рдЖрдкрдХреЗ рдкрд╛рд╕ рдЕрдкрдиреЗ рдкреНрд░рддреНрдпреЗрдХ рдирдореВрдиреЗ рдХреЗ рд▓рд┐рдП рдХрдИ рдкреНрд░рддрд┐рдХреГрддрд┐ рдЙрдкрд╛рдп рд╣реЛрдВрдЧреЗ, рдЙрдиреНрд╣реЗрдВ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХреНрд░реЙрд╕-рд╕рддреНрдпрд╛рдкрди рдХреЗ рджреМрд░рд╛рди рдПрдХ рд╣реА рддрд╣ рдореЗрдВ рд░рд╣рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдФрд░ рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдХрдИ рдЕрд╕рдВрддреБрд▓рд┐рдд рд╡рд░реНрдЧ рд╣реИрдВ рдЬрд┐рдиреНрд╣реЗрдВ рдЖрдк рд╡рд░реНрдЧреАрдХреГрдд рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░ рд░рд╣реЗ рд╣реИрдВ рддреЛ рдЖрдк рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╕реНрддрд░реАрдХрд░рдг рд╕реБрд╡рд┐рдзрд╛ рдХрд╛ рднреА рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рдЗрд╕рд▓рд┐рдП рдореИрдВ рдЗрд╕реЗ рднреА рд╡реЛрдЯ рджреЗрддрд╛ рд╣реВрдВ! рдХреНрд╖рдорд╛ рдХрд░реЗрдВ, рдореИрдВ рд╡рд┐рдХрд╛рд╕ рдореЗрдВ рднрд╛рдЧ рд▓реЗрдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реАрдВ рд╣реВрдВ, рд▓реЗрдХрд┐рди рдЬреЛ рд▓реЛрдЧ рдЗрд╕рдореЗрдВ рднрд╛рдЧ рд▓реЗрдВрдЧреЗ рдЙрдирдХреЗ рд▓рд┐рдП рдЖрдк рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ :-)
рд╕рднреА рдЯреАрдо рдХреЗ рд▓рд┐рдП рдЕрдВрдЧреВрдареЗ рдКрдкрд░ред рдзрдиреНрдпрд╡рд╛рдж!

рдХреГрдкрдпрд╛ рдЗрд╕ рдереНрд░реЗрдб рдореЗрдВ рд╕рдВрджрд░реНрднрд┐рдд рдореБрджреНрджреЛрдВ рдФрд░ рдкреАрдЖрд░ рдХреЛ рджреЗрдЦреЗрдВ рдХреНрдпреЛрдВрдХрд┐ рдХрдо рд╕реЗ рдХрдо StratifiedGroupKFold рдкрд░ рдХрд╛рдо рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдореИрдВрдиреЗ рдкрд╣рд▓реЗ рд╣реА рдПрдХ StratifiedGroupShuffleSplit #15239 рдХрд┐рдпрд╛ рд╣реИ, рдЬрд┐рд╕реЗ рдХреЗрд╡рд▓ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рд▓реЗрдХрд┐рди рдореИрдВрдиреЗ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЕрдкрдиреЗ рдХрд╛рдо рдХреЗ рд▓рд┐рдП рдХрд╛рдлреА рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рд╣реИред

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╣рдореЗрдВ рдЗрд╕реЗ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдореИрдВ рдЕрднреА рднреА рдирд╣реАрдВ рдЬрд╛рдирддрд╛ рдХрд┐ рд╣рдо рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХреНрдпрд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред @hermidalc рдкрд░ рдкреНрд░рддрд┐рдмрдВрдз рд╣реИ рдХрд┐ рдПрдХ рд╣реА рд╕рдореВрд╣ рдХреЗ рд╕рджрд╕реНрдп рдПрдХ рд╣реА рд╡рд░реНрдЧ рдХреЗ рд╣реЛрдиреЗ рдЪрд╛рд╣рд┐рдПред рдпрд╣ рд╕рд╛рдорд╛рдиреНрдп рдорд╛рдорд▓рд╛ рдирд╣реАрдВ рд╣реИ, рд╣реИ рдирд╛?

рдпрд╣ рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ рдпрджрд┐ рд░реБрдЪрд┐ рд░рдЦрдиреЗ рд╡рд╛рд▓реЗ рд▓реЛрдЧ рдЕрдкрдиреЗ рдЙрдкрдпреЛрдЧ-рдорд╛рдорд▓реЗ рдХрд╛ рд╡рд░реНрдгрди рдХрд░ рд╕рдХреЗрдВ рдФрд░ рд╡реЗ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЗрд╕рд╕реЗ рдХреНрдпрд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред

#15239 #14524 рдФрд░ #9413 рд╣реИрдВ рдЬреЛ рдореБрдЭреЗ рдпрд╛рдж рд╣реИ рдХрд┐ рд╕рднреА рдХреЗ рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╢рдмреНрджрд╛рд░реНрде рд╣реИрдВред

@amueller рдЖрдкрдХреЗ рд╕рд╛рде рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕рд╣рдордд рд╣реИ, рдореИрдВрдиреЗ рдЖрдЬ рдХреБрдЫ рдШрдВрдЯреЗ рдмрд┐рддрд╛рдП рд╡рд┐рднрд┐рдиреНрди рд╕рдВрд╕реНрдХрд░рдгреЛрдВ (# 15239 # 14524 рдФрд░ # 9413) рдХреЗ рдмреАрдЪ рдХреБрдЫ рдвреВрдВрдв рд░рд╣реЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдпрд╣ рдирд╣реАрдВ рд╕рдордЭ рд╕рдХрд╛ рдХрд┐ рдЗрдирдореЗрдВ рд╕реЗ рдХреЛрдИ рднреА рдореЗрд░реА рдЬрд╝рд░реВрд░рдд рдХреЗ рдЕрдиреБрд░реВрдк рд╣реЛрдЧрд╛ рдпрд╛ рдирд╣реАрдВред рддреЛ рдпрд╣рд╛рдБ рдореЗрд░рд╛ рдЙрдкрдпреЛрдЧ рдорд╛рдорд▓рд╛ рд╣реИ рдЕрдЧрд░ рдпрд╣ рдорджрдж рдХрд░ рд╕рдХрддрд╛ рд╣реИ:
рдореЗрд░реЗ рдкрд╛рд╕ 1000 рдирдореВрдиреЗ рд╣реИрдВред рдкреНрд░рддреНрдпреЗрдХ рдирдореВрдиреЗ рдХреЛ рдПрдирдЖрдИрдЖрд░ рд╕реНрдкреЗрдХреНрдЯреНрд░реЛрдореАрдЯрд░ рдХреЗ рд╕рд╛рде 3 рдмрд╛рд░ рдорд╛рдкрд╛ рдЧрдпрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдкреНрд░рддреНрдпреЗрдХ рдирдореВрдиреЗ рдореЗрдВ 3 рдкреНрд░рддрд┐рдХреГрддрд┐рдпрд╛рдВ рд╣реИрдВ рдЬрд┐рдиреНрд╣реЗрдВ рдореИрдВ рдПрдХ рд╕рд╛рде рд░рд╣рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ ...
рдпреЗ 1000 рдирдореВрдиреЗ 6 рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╡рд░реНрдЧреЛрдВ рдХреЗ рд╣реИрдВ рдЬрд┐рдирдореЗрдВ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдореЗрдВ рдирдореВрдиреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдмрд╣реБрдд рдЕрд▓рдЧ рд╣реИ:
рдХрдХреНрд╖рд╛ 1: 400 рдирдореВрдиреЗ
рдХрдХреНрд╖рд╛ 2: 300 рдирдореВрдиреЗ
рдХрдХреНрд╖рд╛ 3: 100 рдирдореВрдиреЗ
рдХрдХреНрд╖рд╛ 4: 100 рдирдореВрдиреЗ
рдХрдХреНрд╖рд╛ 5: 70 рдирдореВрдиреЗ
рдХрдХреНрд╖рд╛ 6: 30 рдирдореВрдиреЗ
рдореИрдВ рдкреНрд░рддреНрдпреЗрдХ рд╡рд░реНрдЧ рдХреЗ рд▓рд┐рдП рдПрдХ рдХреНрд▓рд╛рд╕рд┐рдлрд╛рдпрд░рд┐рдпрд░ рдмрдирд╛рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред рддреЛ рдХрдХреНрд╖рд╛ 1 рдмрдирд╛рдо рдЕрдиреНрдп рд╕рднреА рд╡рд░реНрдЧ, рдлрд┐рд░ рдХрдХреНрд╖рд╛ 2 рдмрдирд╛рдо рдЕрдиреНрдп рд╕рднреА рд╡рд░реНрдЧ, рдЖрджрд┐ред
рдореЗрд░реЗ рдкреНрд░рддреНрдпреЗрдХ рдХреНрд▓рд╛рд╕рд┐рдлрд╛рдпрд░рд┐рдпрд░ рдХреА рд╕рдЯреАрдХрддрд╛ рдХреЛ рдЕрдзрд┐рдХрддрдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдпрд╣ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ рдХрд┐ рдореЗрд░реЗ рдкрд╛рд╕ рдкреНрд░рддреНрдпреЗрдХ рдлреЛрд▓реНрдб рдореЗрдВ рджрд░реНрд╢рд╛рдП рдЧрдП 6 рд╡рд░реНрдЧреЛрдВ рдХреЗ рдирдореВрдиреЗ рд╣реЛрдВ, рдХреНрдпреЛрдВрдХрд┐ рдореЗрд░реА рдХрдХреНрд╖рд╛рдПрдВ рдЗрддрдиреА рднрд┐рдиреНрди рдирд╣реАрдВ рд╣реИрдВ рдЗрд╕рд▓рд┐рдП рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ 6 рд╡рд░реНрдЧреЛрдВ рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдЯреАрдХ рд╕реАрдорд╛ рдмрдирд╛рдиреЗ рдореЗрдВ рдорджрдж рдХрд░рддрд╛ рд╣реИ рдкреНрд░рддреНрдпреЗрдХ рддрд╣ рдореЗрдВред

рдпрд╣реА рдХрд╛рд░рдг рд╣реИ рдХрд┐ рдореЗрд░рд╛ рдорд╛рдирдирд╛ тАЛтАЛтАЛтАЛрд╣реИ рдХрд┐ рдПрдХ рд╕реНрддрд░реАрдХреГрдд (рд╣рдореЗрд╢рд╛ рдореЗрд░реА 6 рдХрдХреНрд╖рд╛рдПрдВ рдкреНрд░рддреНрдпреЗрдХ рддрд╣ рдореЗрдВ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рддреА рд╣реИрдВ) рд╕рдореВрд╣ (рдореЗрд░реЗ рдкреНрд░рддреНрдпреЗрдХ рдирдореВрдиреЗ рдХреЗ 3 рдкреНрд░рддрд┐рдХреГрддрд┐ рдЙрдкрд╛рдпреЛрдВ рдХреЛ рд╣рдореЗрд╢рд╛ рдПрдХ рд╕рд╛рде рд░рдЦреЗрдВ) kfold рдмрд╣реБрдд рдЕрдзрд┐рдХ рд▓рдЧрддрд╛ рд╣реИ рдЬреЛ рдореИрдВ рдпрд╣рд╛рдВ рдвреВрдВрдв рд░рд╣рд╛ рд╣реВрдВред
рдХреЛрдИ рд░рд╛рдп?

рдореЗрд░рд╛ рдЙрдкрдпреЛрдЧ рдорд╛рдорд▓рд╛ рдФрд░ рдореИрдВрдиреЗ StratifiedGroupShuffleSplit рдХреНрдпреЛрдВ рд▓рд┐рдЦрд╛, рдпрд╣ рджреЛрд╣рд░рд╛рдП рдЧрдП рдЙрдкрд╛рдпреЛрдВ рдХреЗ рдбрд┐рдЬрд╛рдЗрдиреЛрдВ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣реИ https://en.wikipedia.org/wiki/Repeated_measures_designред рдореЗрд░реЗ рдЙрдкрдпреЛрдЧ рдХреЗ рдорд╛рдорд▓реЛрдВ рдореЗрдВ рдПрдХ рд╣реА рд╕рдореВрд╣ рдХреЗ рд╕рджрд╕реНрдп рдПрдХ рд╣реА рд╡рд░реНрдЧ рдХреЗ рд╣реЛрдиреЗ рдЪрд╛рд╣рд┐рдПред

@fcoppey рдЖрдкрдХреЗ рд▓рд┐рдП, рд╕рдореВрд╣ рдХреЗ рдирдореВрдиреЛрдВ рдореЗрдВ рд╣рдореЗрд╢рд╛ рдПрдХ рд╣реА рдХрдХреНрд╖рд╛ рд╣реЛрддреА рд╣реИ, рд╣реИ рдирд╛?

@hermidalc рдореИрдВ рд╢рдмреНрджрд╛рд╡рд▓реА рд╕реЗ рдмрд╣реБрдд рдкрд░рд┐рдЪрд┐рдд рдирд╣реАрдВ рд╣реВрдВ, рд▓реЗрдХрд┐рди рд╡рд┐рдХрд┐рдкреАрдбрд┐рдпрд╛ рд╕реЗ рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ "рджреЛрд╣рд░рд╛рдпрд╛ рдорд╛рдк рдбрд┐рдЬрд╛рдЗрди" рдХрд╛ рдорддрд▓рдм рдпрд╣ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдПрдХ рд╣реА рд╕рдореВрд╣ рдПрдХ рд╣реА рд╡рд░реНрдЧ рдХреЗ рднреАрддрд░ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдХрд╣рддрд╛ рд╣реИ "рдПрдХ рдХреНрд░реЙрд╕рдУрд╡рд░ рдкрд░реАрдХреНрд╖рдг рдореЗрдВ рджреЛрд╣рд░рд╛рдП рдЧрдП рдЙрдкрд╛рдпреЛрдВ рдХрд╛ рдбрд┐рдЬрд╝рд╛рдЗрди рд╣реЛрддрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рд░реЛрдЧреА рдХреЛ рджреЛ рдпрд╛ рдЕрдзрд┐рдХ рдЙрдкрдЪрд╛рд░реЛрдВ рдХреЗ рдЕрдиреБрдХреНрд░рдо рдХреЗ рд▓рд┐рдП рдирд┐рдпрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд┐рдирдореЗрдВ рд╕реЗ рдПрдХ рдорд╛рдирдХ рдЙрдкрдЪрд╛рд░ рдпрд╛ рдкреНрд▓реЗрд╕реАрдмреЛ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред"
рдЗрд╕реЗ рдПрдХ рдПрдордПрд▓ рд╕реЗрдЯрд┐рдВрдЧ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рдХрд░рддреЗ рд╣реБрдП, рдЖрдк рдпрд╛ рддреЛ рдорд╛рдк рд╕реЗ рдпрд╣ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдХреНрдпрд╛ рдХрд┐рд╕реА рд╡реНрдпрдХреНрддрд┐ рдиреЗ рдЕрднреА-рдЕрднреА рдЙрдкрдЪрд╛рд░ рдпрд╛ рдкреНрд▓реЗрд╕рд┐рдмреЛ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рд╣реИ, рдпрд╛ рдЖрдк рдЙрдкрдЪрд╛рд░ рдХреЗ рдкрд░рд┐рдгрд╛рдо рдХреА рднрд╡рд┐рд╖реНрдпрд╡рд╛рдгреА рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рдЙрдирдореЗрдВ рд╕реЗ рдХрд┐рд╕реА рдХреЗ рд▓рд┐рдП рдПрдХ рд╣реА рд╡реНрдпрдХреНрддрд┐ рдХреЗ рд▓рд┐рдП рд╡рд░реНрдЧ рдмрджрд▓ рд╕рдХрддрд╛ рд╣реИ, рд╣реИ рдирд╛?

рдирд╛рдо рдЪрд╛рд╣реЗ рдЬреЛ рднреА рд╣реЛ, рдореБрдЭреЗ рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЖрдк рджреЛрдиреЛрдВ рдХреЗ рдкрд╛рд╕ рдПрдХ рд╣реА рдЙрдкрдпреЛрдЧ рдХрд╛ рдорд╛рдорд▓рд╛ рд╣реИ, рдЬрдмрдХрд┐ рдореИрдВ рдПрдХ рдРрд╕реЗ рдорд╛рдорд▓реЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪ рд░рд╣рд╛ рдерд╛ рдЬреЛ рдХреНрд░реЙрд╕рдУрд╡рд░ рдЕрдзреНрдпрдпрди рдореЗрдВ рд╡рд░реНрдгрд┐рдд рд╣реИред рдпрд╛ рд╢рд╛рдпрдж рдереЛрдбрд╝рд╛ рдФрд░ рд╕рд░рд▓: рдЖрдк рд╕рдордп рдХреЗ рд╕рд╛рде рдПрдХ рд░реЛрдЧреА рдмреАрдорд╛рд░ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ (рдпрд╛ рдмреЗрд╣рддрд░ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ), рдЗрд╕рд▓рд┐рдП рд░реЛрдЧреА рдХреЗ рд▓рд┐рдП рдкрд░рд┐рдгрд╛рдо рдмрджрд▓ рд╕рдХрддрд╛ рд╣реИред

рдЕрд╕рд▓ рдореЗрдВ рдЖрдк рдЬрд┐рд╕ рд╡рд┐рдХрд┐рдкреАрдбрд┐рдпрд╛ рд▓реЗрдЦ рд╕реЗ рд▓рд┐рдВрдХ рдХрд░рддреЗ рд╣реИрдВ рд╡рд╣ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдХрд╣рддрд╛ рд╣реИ "рдЕрдиреБрджреИрд░реНрдзреНрдп рд╡рд┐рд╢реНрд▓реЗрд╖рдг-рджреЛрд╣рд░рд╛рдП рдЧрдП рдорд╛рдк рдбрд┐рдЬрд╝рд╛рдЗрди рд╢реЛрдзрдХрд░реНрддрд╛рдУрдВ рдХреЛ рдпрд╣ рдирд┐рдЧрд░рд╛рдиреА рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреЗ рд╣реИрдВ рдХрд┐ рдкреНрд░рддрд┐рднрд╛рдЧреА рд╕рдордп рдХреЗ рд╕рд╛рде рдХреИрд╕реЗ рдмрджрд▓рддреЗ рд╣реИрдВ, рджреЛрдиреЛрдВ рд▓рдВрдмреА рдФрд░ рдЫреЛрдЯреА рдЕрд╡рдзрд┐ рдХреА рдкрд░рд┐рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдореЗрдВред", рдЗрд╕рд▓рд┐рдП рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рдХрдХреНрд╖рд╛ рдХреЛ рдмрджрд▓рдирд╛ рд╢рд╛рдорд┐рд▓ рд╣реИред
рдпрджрд┐ рдХреЛрдИ рдЕрдиреНрдп рд╢рдмреНрдж рд╣реИ рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рдорд╛рдк рдЙрдиреНрд╣реАрдВ рдкрд░рд┐рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рддреЛ рд╣рдо рдЙрд╕ рд╢рдмреНрдж рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ?

@amueller рд╣рд╛рдБ рдЖрдк рд╕рд╣реА рдХрд╣ рд░рд╣реЗ рд╣реИрдВ, рдореБрдЭреЗ рдПрд╣рд╕рд╛рд╕ рд╣реБрдЖ рдХрд┐ рдореИрдВрдиреЗ рдКрдкрд░ рдЧрд▓рдд рд▓рд┐рдЦрд╛ рд╣реИ рдЬрд╣рд╛рдБ рдореЗрд░рд╛ рдорддрд▓рдм рдЗрд╕ рдбрд┐рдЬрд╝рд╛рдЗрди рдХреЗ рдЕрдкрдиреЗ рдЙрдкрдпреЛрдЧ рдХреЗ рдорд╛рдорд▓реЛрдВ рдореЗрдВ рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рд╕реЗ рдЗрд╕ рдЙрдкрдпреЛрдЧ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдирд╣реАрдВ рд╣реИред

рджреЛрд╣рд░рд╛рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдЙрдкрд╛рдпреЛрдВ рдХреЗ рдХрдИ рд╡рд┐рд╕реНрддреГрдд рдкреНрд░рдХрд╛рд░ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рджреЛ рдкреНрд░рдХрд╛рд░реЛрдВ рдореЗрдВ рдореБрдЭреЗ StratifiedGroupShuffleSplit рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рд╕рдореВрд╣ рдХреЗ рднреАрддрд░ рд╕рдорд╛рди рд╡рд░реНрдЧ рдкреНрд░рддрд┐рдмрдВрдз (рдЙрдкрдЪрд╛рд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреА рднрд╡рд┐рд╖реНрдпрд╡рд╛рдгреА рдХрд░рддреЗ рд╕рдордп рдЙрдкрдЪрд╛рд░ рд╕реЗ рдкрд╣рд▓реЗ рдФрд░ рдмрд╛рдж рдореЗрдВ рдЕрдиреБрджреИрд░реНрдзреНрдп рдирдореВрдирд╛рдХрд░рдг, рдХрдИ рдкреВрд░реНрд╡-рдЙрдкрдЪрд╛рд░ рдЙрдкрдЪрд╛рд░ рдХреА рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреА рднрд╡рд┐рд╖реНрдпрд╡рд╛рдгреА рдХрд░рддреЗ рд╕рдордп рд╢рд░реАрд░ рдХреЗ рд╡рд┐рднрд┐рдиреНрди рд╕реНрдерд╛рдиреЛрдВ рдкрд░ рдкреНрд░рддрд┐ рд╡рд┐рд╖рдп рдирдореВрдиреЗ)ред

рдореБрдЭреЗ рддреБрд░рдВрдд рдХреБрдЫ рдЪрд╛рд╣рд┐рдП рдерд╛ рдЬреЛ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдЗрд╕рд▓рд┐рдП рдЗрд╕реЗ рджреВрд╕рд░реЛрдВ рдХреЗ рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП рдФрд░ рд╕реНрдХреЗрд▓реЗрд░ рдкрд░ рдХреБрдЫ рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд╣рд╛рдВ рд░рдЦрдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛, рд╕рд╛рде рд╣реА рдЕрдЧрд░ рдореБрдЭреЗ рдЧрд▓рдд рдирд╣реАрдВ рд▓рдЧрддрд╛ рд╣реИ рддреЛ рд╕рдореВрд╣ рд╡рд░реНрдЧ рд▓реЗрдмрд▓ рдХреЗ рднреАрддрд░ рд╕реНрддрд░реАрдХрд░рдг рддрд░реНрдХ рдХреЛ рдбрд┐рдЬрд╛рдЗрди рдХрд░рдирд╛ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред

@amueller рд╣рд╛рдБ рд╣рдореЗрд╢рд╛ред рднрд╡рд┐рд╖реНрдпрд╡рд╛рдгреА рдореЗрдВ рдбрд┐рд╡рд╛рдЗрд╕ рдХреА рдЕрдВрддрдГрдкрд░рд┐рд╡рд░реНрддрдиреАрдпрддрд╛ рдХреЛ рд╢рд╛рдорд┐рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╡реЗ рдПрдХ рд╣реА рдорд╛рдк рдХреА рдкреНрд░рддрд┐рдХреГрддрд┐ рд╣реИрдВред

@hermidalc рд╣рд╛рдБ, рдпрд╣ рдорд╛рдорд▓рд╛ рдмрд╣реБрдд рдЖрд╕рд╛рди рд╣реИред рдпрджрд┐ рдпрд╣ рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ рд╣рдореЗрдВ рдЗрд╕реЗ рдЬреЛрдбрд╝рдиреЗ рдореЗрдВ рдкреНрд░рд╕рдиреНрдирддрд╛ рд╣реЛ рд░рд╣реА рд╣реИред рд╣рдореЗрдВ рдХреЗрд╡рд▓ рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рдирд╛рдо рд╕реЗ рдпрд╣ рдХреБрдЫ рд╣рдж рддрдХ рд╕реНрдкрд╖реНрдЯ рд╣реИ рдХрд┐ рдпрд╣ рдХреНрдпрд╛ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рд╣рдореЗрдВ рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪрдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рдХреНрдпрд╛ рдпреЗ рджреЛрдиреЛрдВ рд╕рдВрд╕реНрдХрд░рдг рдПрдХ рд╣реА рдХрдХреНрд╖рд╛ рдореЗрдВ рд░рд╣рдиреЗ рдЪрд╛рд╣рд┐рдПред

рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП StratifiedKFold рдмрдирд╛рдирд╛ рдХрд╛рдлреА рдЖрд╕рд╛рди рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рджреЛ рд╡рд┐рдХрд▓реНрдк рд╣реИрдВ: рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░реЗрдВ рдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рддрд╣ рдореЗрдВ рд╕рдорд╛рди рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдирдореВрдиреЗ рд╣реИрдВ, рдпрд╛ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░реЗрдВ рдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рддрд╣ рдореЗрдВ рд╕рдорд╛рди рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рд╕рдореВрд╣ рд╣реИрдВред
рджреВрд╕рд░рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЫреЛрдЯрд╛ рд╣реИ (рдХреЗрд╡рд▓ рдкреНрд░рддреНрдпреЗрдХ рд╕рдореВрд╣ рдХрд╛ рдирд╛рдЯрдХ рдХрд░рдХреЗ рдПрдХ рдмрд┐рдВрджреБ рд╣реИ рдФрд░ StratifiedKFold рдкрд░ рдЬрд╛ рд░рд╣рд╛ рд╣реИ)ред рдЖрдк рдЕрдкрдиреЗ рдкреАрдЖрд░ рдореЗрдВ рдпрд╣реА рдХрд░рддреЗ рд╣реИрдВ, рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИред

GroupKFold рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ рд╕рдмрд╕реЗ рдЫреЛрдЯреА рддрд╣ рдореЗрдВ рдЬреЛрдбрд╝рдХрд░ рдЙрди рджреЛрдиреЛрдВ рдХреЛ рд╣реНрдпреБрд░рд┐рд╕реНрдЯрд┐рдХ рд░реВрдк рд╕реЗ рдмрдВрдж рдХрд░ рджреЗрддрд╛ рд╣реИред рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдпрд╣ рдХреИрд╕реЗ рд╕реНрддрд░реАрдХреГрдд рдорд╛рдорд▓реЗ рдореЗрдВ рдЕрдиреБрд╡рд╛рдж рдХрд░реЗрдЧрд╛, рдЗрд╕рд▓рд┐рдП рдореИрдВ рдЖрдкрдХреЗ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЦреБрд╢ рд╣реВрдВред

рдХреНрдпрд╛ рд╣рдореЗрдВ рдЙрд╕реА рдкреАрдЖрд░ рдореЗрдВ GroupStratifiedKFold рднреА рдЬреЛрдбрд╝рдирд╛ рдЪрд╛рд╣рд┐рдП? рдпрд╛ рдЗрд╕реЗ рдмрд╛рдж рдХреЗ рд▓рд┐рдП рдЫреЛрдбрд╝ рджреЗрдВ?
рдЕрдиреНрдп рдкреАрдЖрд░ рдХреЗ рд▓рдХреНрд╖реНрдп рдереЛрдбрд╝реЗ рдЕрд▓рдЧ рд╣реИрдВред рдпрд╣ рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ рдпрджрд┐ рдХреЛрдИ рдпрд╣ рд▓рд┐рдЦ рд╕рдХреЗ рдХрд┐ рд╡рд┐рднрд┐рдиреНрди рдЙрдкрдпреЛрдЧ-рдорд╛рдорд▓реЗ рдХреНрдпрд╛ рд╣реИрдВ (рд╢рд╛рдпрдж рдореЗрд░реЗ рдкрд╛рд╕ рдЕрднреА рд╕рдордп рдирд╣реАрдВ рд╣реИ)ред

+1 рд╕рдореВрд╣ рдХреА рдмрд╛рдзрд╛ рдХреЛ рдЕрд▓рдЧ рд╕реЗ рд╕рдВрднрд╛рд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд╣рд╛рдВ рд╕рднреА рдирдореВрдиреЛрдВ рдХреА рдПрдХ рд╣реА рдХрдХреНрд╖рд╛ рд╣реЛрддреА рд╣реИред

@hermidalc рд╣рд╛рдБ, рдпрд╣ рдорд╛рдорд▓рд╛ рдмрд╣реБрдд рдЖрд╕рд╛рди рд╣реИред рдпрджрд┐ рдпрд╣ рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ рд╣рдореЗрдВ рдЗрд╕реЗ рдЬреЛрдбрд╝рдиреЗ рдореЗрдВ рдкреНрд░рд╕рдиреНрдирддрд╛ рд╣реЛ рд░рд╣реА рд╣реИред рд╣рдореЗрдВ рдХреЗрд╡рд▓ рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рдирд╛рдо рд╕реЗ рдпрд╣ рдХреБрдЫ рд╣рдж рддрдХ рд╕реНрдкрд╖реНрдЯ рд╣реИ рдХрд┐ рдпрд╣ рдХреНрдпрд╛ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рд╣рдореЗрдВ рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪрдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рдХреНрдпрд╛ рдпреЗ рджреЛрдиреЛрдВ рд╕рдВрд╕реНрдХрд░рдг рдПрдХ рд╣реА рдХрдХреНрд╖рд╛ рдореЗрдВ рд░рд╣рдиреЗ рдЪрд╛рд╣рд┐рдПред

рдореИрдВ рдЗрд╕реЗ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдирд╣реАрдВ рд╕рдордЭ рд░рд╣рд╛ рд╣реВрдВ, рдПрдХ StratifiedGroupShuffleSplit рдФрд░ StratifiedGroupKFold рдЬрд╣рд╛рдВ рдЖрдк рдкреНрд░рддреНрдпреЗрдХ рд╕рдореВрд╣ рдХреЗ рд╕рджрд╕реНрдп рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╡рд░реНрдЧреЛрдВ рдХреЗ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ, рдЬрдм рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╕рднреА рд╕рдореВрд╣ рд╕рджрд╕реНрдпреЛрдВ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддрд╛ рд╣реИ рддреЛ рд╕рдЯреАрдХ рд╕рдорд╛рди рд╡рд┐рднрд╛рдЬрди рд╡реНрдпрд╡рд╣рд╛рд░ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рдПрдХ рд╣реА рд╡рд░реНрдЧ рдХреЗред рдмрд╕ рдмрд╛рдж рдореЗрдВ рдХрдм рдЖрдВрддрд░рд┐рдХ рд╕реБрдзрд╛рд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдореМрдЬреВрджрд╛ рд╡реНрдпрд╡рд╣рд╛рд░ рд╡рд╣реА рд╣реЛрдЧрд╛?

рджреВрд╕рд░рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЫреЛрдЯрд╛ рд╣реИ (рдХреЗрд╡рд▓ рдкреНрд░рддреНрдпреЗрдХ рд╕рдореВрд╣ рдХрд╛ рдирд╛рдЯрдХ рдХрд░рдХреЗ рдПрдХ рдмрд┐рдВрджреБ рд╣реИ рдФрд░ StratifiedKFold рдкрд░ рдЬрд╛ рд░рд╣рд╛ рд╣реИ)ред рдЖрдк рдЕрдкрдиреЗ рдкреАрдЖрд░ рдореЗрдВ рдпрд╣реА рдХрд░рддреЗ рд╣реИрдВ, рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИред

GroupKFold рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ рд╕рдмрд╕реЗ рдЫреЛрдЯреА рддрд╣ рдореЗрдВ рдЬреЛрдбрд╝рдХрд░ рдЙрди рджреЛрдиреЛрдВ рдХреЛ рд╣реНрдпреБрд░рд┐рд╕реНрдЯрд┐рдХ рд░реВрдк рд╕реЗ рдмрдВрдж рдХрд░ рджреЗрддрд╛ рд╣реИред рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдпрд╣ рдХреИрд╕реЗ рд╕реНрддрд░реАрдХреГрдд рдорд╛рдорд▓реЗ рдореЗрдВ рдЕрдиреБрд╡рд╛рдж рдХрд░реЗрдЧрд╛, рдЗрд╕рд▓рд┐рдП рдореИрдВ рдЖрдкрдХреЗ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЦреБрд╢ рд╣реВрдВред

рдХреНрдпрд╛ рд╣рдореЗрдВ рдЙрд╕реА рдкреАрдЖрд░ рдореЗрдВ GroupStratifiedKFold рднреА рдЬреЛрдбрд╝рдирд╛ рдЪрд╛рд╣рд┐рдП? рдпрд╛ рдЗрд╕реЗ рдмрд╛рдж рдХреЗ рд▓рд┐рдП рдЫреЛрдбрд╝ рджреЗрдВ?
рдЕрдиреНрдп рдкреАрдЖрд░ рдХреЗ рд▓рдХреНрд╖реНрдп рдереЛрдбрд╝реЗ рдЕрд▓рдЧ рд╣реИрдВред рдпрд╣ рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ рдпрджрд┐ рдХреЛрдИ рдпрд╣ рд▓рд┐рдЦ рд╕рдХреЗ рдХрд┐ рд╡рд┐рднрд┐рдиреНрди рдЙрдкрдпреЛрдЧ-рдорд╛рдорд▓реЗ рдХреНрдпрд╛ рд╣реИрдВ (рд╢рд╛рдпрдж рдореЗрд░реЗ рдкрд╛рд╕ рдЕрднреА рд╕рдордп рдирд╣реАрдВ рд╣реИ)ред

рдореИрдВ "рдкреНрд░рддреНрдпреЗрдХ рд╕рдореВрд╣ рдПрдХрд▓ рдирдореВрдирд╛" рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ StatifiedGroupKFold рдЬреЛрдбрд╝реВрдВрдЧрд╛ рдЬрд┐рд╕рдХрд╛ рдореИрдВрдиреЗ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдерд╛ред

рдпрд╣ рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ рдпрджрд┐ рд░реБрдЪрд┐ рд░рдЦрдиреЗ рд╡рд╛рд▓реЗ рд▓реЛрдЧ рдЕрдкрдиреЗ рдЙрдкрдпреЛрдЧ-рдорд╛рдорд▓реЗ рдХрд╛ рд╡рд░реНрдгрди рдХрд░ рд╕рдХреЗрдВ рдФрд░ рд╡реЗ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЗрд╕рд╕реЗ рдХреНрдпрд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред

рдЬрдм рдЖрдк рдмрд╛рд░-рдмрд╛рд░ рдЙрдкрд╛рдп рдХрд░рддреЗ рд╣реИрдВ рддреЛ рджрд╡рд╛ рдФрд░ рдЬреАрд╡ рд╡рд┐рдЬреНрдЮрд╛рди рдореЗрдВ рдмрд╣реБрдд рд╣реА рд╕рд╛рдорд╛рдиреНрдп рдЙрдкрдпреЛрдЧ-рдорд╛рдорд▓рд╛ рд╣реЛрддрд╛ рд╣реИред
рдПрдХ рдЙрджрд╛рд╣рд░рдг: рдорд╛рди рд▓реЗрдВ рдХрд┐ рдЖрдк рдХрд┐рд╕реА рдмреАрдорд╛рд░реА рдХреЛ рд╡рд░реНрдЧреАрдХреГрдд рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рдЬреИрд╕реЗ рдЕрд▓реНрдЬрд╛рдЗрдорд░ рд░реЛрдЧ (рдПрдбреА) рдмрдирд╛рдо рдПрдордЖрд░ рдЫрд╡рд┐рдпреЛрдВ рд╕реЗ рд╕реНрд╡рд╕реНрде рдирд┐рдпрдВрддреНрд░рдгред рдПрдХ рд╣реА рд╡рд┐рд╖рдп рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЗ рдкрд╛рд╕ рдХрдИ рд╕реНрдХреИрди рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ (рдЕрдиреБрд╡рд░реНрддреА рд╕рддреНрд░реЛрдВ рдпрд╛ рдЕрдиреБрджреИрд░реНрдзреНрдп рдбреЗрдЯрд╛ рд╕реЗ)ред рдорд╛рди рд▓реЗрдВ рдХрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдХреБрд▓ 1000 рд╡рд┐рд╖рдп рд╣реИрдВ, рдЙрдирдореЗрдВ рд╕реЗ 200 рдХрд╛ рдирд┐рджрд╛рди AD (рдЕрд╕рдВрддреБрд▓рд┐рдд рд╡рд░реНрдЧ) рд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИред рдЕрдзрд┐рдХрд╛рдВрд╢ рд╡рд┐рд╖рдпреЛрдВ рдореЗрдВ рдПрдХ рд╕реНрдХреИрди рд╣реЛрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЙрдирдореЗрдВ рд╕реЗ рдХреБрдЫ рдХреЗ рд▓рд┐рдП 2 рдпрд╛ 3 рдЫрд╡рд┐рдпрд╛рдВ рдЙрдкрд▓рдмреНрдз рд╣реЛрддреА рд╣реИрдВред рдХреНрд▓рд╛рд╕рд┐рдлрд╛рдпрд░рд┐рдпрд░ рдХрд╛ рдкреНрд░рд╢рд┐рдХреНрд╖рдг/рдкрд░реАрдХреНрд╖рдг рдХрд░рддреЗ рд╕рдордп, рдЖрдк рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдХрд┐ рдбреЗрдЯрд╛ рд░рд┐рд╕рд╛рд╡ рд╕реЗ рдмрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╣реА рд╡рд┐рд╖рдп рдХреА рдЫрд╡рд┐рдпрд╛рдВ рд╣рдореЗрд╢рд╛ рдПрдХ рд╣реА рддрд╣ рдореЗрдВ рд╣реЛрдВред
рдЗрд╕рдХреЗ рд▓рд┐рдП рд╕реНрдЯреНрд░реИрдЯрд┐рдлрд╛рдЗрдбрдЧреНрд░реБрдкрдХреЗрдлреЛрд▓реНрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рд╣реИ: рд╡рд░реНрдЧ рдЕрд╕рдВрддреБрд▓рди рдХреЗ рд▓рд┐рдП рдЦрд╛рддреЗ рдореЗрдВ рд╕реНрддрд░реАрдХрд░рдг рдХрд░реЗрдВ рд▓реЗрдХрд┐рди рд╕рдореВрд╣ рдХреА рдмрд╛рдзрд╛ рдХреЗ рд╕рд╛рде рдХрд┐ рдПрдХ рд╡рд┐рд╖рдп рдЕрд▓рдЧ-рдЕрд▓рдЧ рддрд╣реЛрдВ рдореЗрдВ рдкреНрд░рдХрдЯ рдирд╣реАрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред
рдПрдирдмреА: рдЗрд╕реЗ рджреЛрд╣рд░рд╛рдиреЗ рдпреЛрдЧреНрдп рдмрдирд╛рдирд╛ рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ред

рдХрд╛рдЧрд▓-рдХрд░реНрдиреЗрд▓ рд╕реЗ рдкреНрд░реЗрд░рд┐рдд рдПрдХ рдЙрджрд╛рд╣рд░рдг рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рдиреАрдЪреЗред

import numpy as np
from collections import Counter, defaultdict
from sklearn.utils import check_random_state

class RepeatedStratifiedGroupKFold():

    def __init__(self, n_splits=5, n_repeats=1, random_state=None):
        self.n_splits = n_splits
        self.n_repeats = n_repeats
        self.random_state = random_state

    # Implementation based on this kaggle kernel:
    #    https://www.kaggle.com/jakubwasikowski/stratified-group-k-fold-cross-validation
    def split(self, X, y=None, groups=None):
        k = self.n_splits
        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)

        rnd = check_random_state(self.random_state)
        for repeat in range(self.n_repeats):
            labels_num = np.max(y) + 1
            y_counts_per_group = defaultdict(lambda: np.zeros(labels_num))
            y_distr = Counter()
            for label, g in zip(y, groups):
                y_counts_per_group[g][label] += 1
                y_distr[label] += 1

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

            groups_and_y_counts = list(y_counts_per_group.items())
            rnd.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

RepeatedStratifiedKFold (рдПрдХ рд╣реА рд╕рдореВрд╣ рдХрд╛ рдирдореВрдирд╛ рджреЛрдиреЛрдВ рддрд╣реЛрдВ рдореЗрдВ рджрд┐рдЦрд╛рдИ рджреЗ рд╕рдХрддрд╛ рд╣реИ) рдХреА рддреБрд▓рдирд╛ RepeatedStratifiedGroupKFold рд╕реЗ рдХрд░рдирд╛:

import matplotlib.pyplot as plt
from sklearn import model_selection

def plot_cv_indices(cv, X, y, group, ax, n_splits, lw=10):
    for ii, (tr, tt) in enumerate(cv.split(X=X, y=y, groups=group)):
        indices = np.array([np.nan] * len(X))
        indices[tt] = 1
        indices[tr] = 0

        ax.scatter(range(len(indices)), [ii + .5] * len(indices),
                   c=indices, marker='_', lw=lw, cmap=plt.cm.coolwarm,
                   vmin=-.2, vmax=1.2)

    ax.scatter(range(len(X)), [ii + 1.5] * len(X), c=y, marker='_',
               lw=lw, cmap=plt.cm.Paired)
    ax.scatter(range(len(X)), [ii + 2.5] * len(X), c=group, marker='_',
               lw=lw, cmap=plt.cm.tab20c)

    yticklabels = list(range(n_splits)) + ['class', 'group']
    ax.set(yticks=np.arange(n_splits+2) + .5, yticklabels=yticklabels,
           xlabel='Sample index', ylabel="CV iteration",
           ylim=[n_splits+2.2, -.2], xlim=[0, 100])
    ax.set_title('{}'.format(type(cv).__name__), fontsize=15)


# demonstration
np.random.seed(1338)
n_splits = 4
n_repeats=5


# Generate the class/group data
n_points = 100
X = np.random.randn(100, 10)

percentiles_classes = [.4, .6]
y = np.hstack([[ii] * int(100 * perc) for ii, perc in enumerate(percentiles_classes)])

# Evenly spaced groups
g = np.hstack([[ii] * 5 for ii in range(20)])


fig, ax = plt.subplots(1,2, figsize=(14,4))

cv_nogrp = model_selection.RepeatedStratifiedKFold(n_splits=n_splits,
                                                   n_repeats=n_repeats,
                                                   random_state=1338)
cv_grp = RepeatedStratifiedGroupKFold(n_splits=n_splits,
                                      n_repeats=n_repeats,
                                      random_state=1338)

plot_cv_indices(cv_nogrp, X, y, g, ax[0], n_splits * n_repeats)
plot_cv_indices(cv_grp, X, y, g, ax[1], n_splits * n_repeats)

plt.show()

RepeatedStratifiedGroupKFold_demo

рд╕реНрддрд░реАрдХреГрдд GroupKfold рдХреЗ рд▓рд┐рдП +1ред рдореИрдВ samrt рдШрдбрд╝реА рд╕реЗ рд╕реЗрдВрд╕рд░ рд▓реЗрдХрд░ рд╡рд░рд┐рд╖реНрдареЛрдВ рдХреЗ рдЧрд┐рд░рдиреЗ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣рд╛ рд╣реВрдВред рдЪреВрдВрдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдмрд╣реБрдд рдЕрдзрд┐рдХ рдЧрд┐рд░рд╛рд╡рдЯ рдбреЗрдЯрд╛ рдирд╣реАрдВ рд╣реИ - рд╣рдо рдЕрд▓рдЧ-рдЕрд▓рдЧ рдШрдбрд╝рд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рд╕рд┐рдореБрд▓реЗрд╢рди рдХрд░рддреЗ рд╣реИрдВ рдЬрд┐рдиреНрд╣реЗрдВ рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╡рд░реНрдЧ рдорд┐рд▓рддреЗ рд╣реИрдВред рдореИрдВ рдЗрд╕реЗ рдкреНрд░рд╢рд┐рдХреНрд╖рд┐рдд рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдбреЗрдЯрд╛ рдореЗрдВ рд╡реГрджреНрдзрд┐ рднреА рдХрд░рддрд╛ рд╣реВрдВред рдкреНрд░рддреНрдпреЗрдХ рдбреЗрдЯрд╛ рдмрд┐рдВрджреБ рд╕реЗ рдореИрдВ 9 рдЕрдВрдХ рдмрдирд╛рддрд╛ рд╣реВрдВ- рдФрд░ рдпрд╣ рдПрдХ рд╕рдореВрд╣ рд╣реИред рдпрд╣ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ рдХрд┐ рдПрдХ рд╕рдореВрд╣ рдЯреНрд░реЗрди рдФрд░ рдкрд░реАрдХреНрд╖рдг рджреЛрдиреЛрдВ рдореЗрдВ рдирд╣реАрдВ рд╣реЛрдЧрд╛ рдЬреИрд╕рд╛ рдХрд┐ рд╕рдордЭрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ

рдореИрдВ рд╕реНрдЯреНрд░реИрдЯрд┐рдлрд╛рдЗрдбрдЧреНрд░реБрдкрдХреЗрдлреЛрд▓реНрдб рдХрд╛ рднреА рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред рдореИрдВ рд╡рд┐рддреНрддреАрдп рд╕рдВрдХрдЯреЛрдВ рдХреА рднрд╡рд┐рд╖реНрдпрд╡рд╛рдгреА рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдбреЗрдЯрд╛рд╕реЗрдЯ рджреЗрдЦ рд░рд╣рд╛ рд╣реВрдВ, рдЬрд╣рд╛рдВ рд╡рд░реНрд╖реЛрдВ рдкрд╣рд▓реЗ, рдкреНрд░рддреНрдпреЗрдХ рд╕рдВрдХрдЯ рдХреЗ рдмрд╛рдж рдФрд░ рдЙрд╕рдХреЗ рджреМрд░рд╛рди рдЙрд╕рдХрд╛ рдЕрдкрдирд╛ рд╕рдореВрд╣ рд╣реЛрддрд╛ рд╣реИред рдкреНрд░рд╢рд┐рдХреНрд╖рдг рдФрд░ рдХреНрд░реЙрд╕-рд╕рддреНрдпрд╛рдкрди рдХреЗ рджреМрд░рд╛рди, рдкреНрд░рддреНрдпреЗрдХ рд╕рдореВрд╣ рдХреЗ рд╕рджрд╕реНрдпреЛрдВ рдХреЛ рд╕рд┐рд▓рд╡рдЯреЛрдВ рдХреЗ рдмреАрдЪ рд░рд┐рд╕рд╛рд╡ рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред

рд╡рд╣рд╛рдБ рд╡реИрд╕реЗ рднреА рд╕рд╛рдорд╛рдиреНрдпреАрдХреГрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣реИ рдХрд┐ рдмрд╣реБрд▓реЗрдмрд▓ рдкрд░рд┐рджреГрд╢реНрдп рдХреЗ рд▓рд┐рдП (Multilabel_
рд╕реНрддрд░реАрдХреГрддрдЧреНрд░реБрдкрдХреЗрдлреЛрд▓реНрдб)?

рдЗрд╕рдХреЗ рд▓рд┐рдП +1ред рд╣рдо рд╕реНрдкреИрдо рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЦрд╛рддреЛрдВ рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рд╣рдо рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рджреНрд╡рд╛рд░рд╛ рд╕рдореВрд╣ рдмрдирд╛рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╕реНрддрд░реАрдХрд░рдг рднреА рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдХреНрдпреЛрдВрдХрд┐ рд╕реНрдкреИрдо рдЕрдкреЗрдХреНрд╖рд╛рдХреГрдд рдХрдо рдШрдЯрдирд╛ рд╣реИред рд╣рдорд╛рд░реЗ рдЙрдкрдпреЛрдЧ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдХреЛрдИ рднреА рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЬреЛ рдПрдХ рдмрд╛рд░ рд╕реНрдкреИрдо рдХрд░рддрд╛ рд╣реИ, рдЙрд╕реЗ рд╕рднреА рдбреЗрдЯрд╛ рдореЗрдВ рд╕реНрдкреИрдорд░ рдХреЗ рд░реВрдк рдореЗрдВ рдлрд╝реНрд▓реИрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╕рдореВрд╣ рдХреЗ рд╕рджрд╕реНрдп рдХреЗ рдкрд╛рд╕ рд╣рдореЗрд╢рд╛ рдПрдХ рд╣реА рд▓реЗрдмрд▓ рд╣реЛрдЧрд╛ред

рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реАрдХрд░рдг рдХреЛ рдлреНрд░реЗрдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреНрд▓рд╛рд╕рд┐рдХ рдЙрдкрдпреЛрдЧ рдХреЗрд╕ рдкреНрд░рджрд╛рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж,
@ рдлрд┐рд▓рд┐рдк-iv!

рдореИрдВрдиреЗ рдЕрдкрдиреЗ рд╕рдорд╛рди рдкреАрдЖрд░ #15239 рдореЗрдВ StratifiedGroupShuffleSplit рдХреЗ рд░реВрдк рдореЗрдВ $ StratifiedGroupKFold рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЬреЛрдбрд╝рд╛ред

рдпрджреНрдпрдкрд┐ рдЖрдк рдкреАрдЖрд░ рдореЗрдВ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рджреЛрдиреЛрдВ рдХреЗ рд▓рд┐рдП рддрд░реНрдХ https://github.com/scikit-learn/scikit-learn/issues/13621#issuecomment -557802602 рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдмрд╣реБрдд рд╕рд░рд▓ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдореЗрд░рд╛ рдХреЗрд╡рд▓ рд╕рдореВрд╣реЛрдВ рдХреЗ рдкреНрд░рддрд┐рд╢рдд рдХреЛ рд╕рдВрд░рдХреНрд╖рд┐рдд рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рддрд╛ рд╣реИ рдкреНрд░рддреНрдпреЗрдХ рд╡рд░реНрдЧ (рдирдореВрдиреЗ рдХрд╛ рдкреНрд░рддрд┐рд╢рдд рдирд╣реАрдВ) рддрд╛рдХрд┐ рдореИрдВ рдореМрдЬреВрджрд╛ StratifiedKFold рдФрд░ StratifiedShuffleSplit рдХреЛрдб рдХреЛ рдЕрджреНрд╡рд┐рддреАрдп рд╕рдореВрд╣ рдЬрд╛рдирдХрд╛рд░реА рдкрд╛рд╕ рдХрд░рдХреЗ рд▓рд╛рдн рдЙрдард╛ рд╕рдХреВрдВред рд▓реЗрдХрд┐рди рджреЛрдиреЛрдВ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╕рд┐рд▓рд╡рдЯреЛрдВ рдХрд╛ рдЙрддреНрдкрд╛рджрди рдХрд░рддреЗ рд╣реИрдВ рдЬрд╣рд╛рдВ рдкреНрд░рддреНрдпреЗрдХ рд╕рдореВрд╣ рдХреЗ рдирдореВрдиреЗ рдПрдХ рд╣реА рддрд╣ рдореЗрдВ рдПрдХ рд╕рд╛рде рд░рд╣рддреЗ рд╣реИрдВред

рд╣рд╛рд▓рд╛рдВрдХрд┐ рдореИрдВ https://github.com/scikit-learn/scikit-learn/issues/13621#issuecomment -557802602 рдкрд░ рдЖрдзрд╛рд░рд┐рдд рдЕрдзрд┐рдХ рдкрд░рд┐рд╖реНрдХреГрдд рддрд░реАрдХреЛрдВ рдХреЗ рд▓рд┐рдП рд╡реЛрдЯ рдХрд░реВрдВрдЧрд╛ред

рдпрд╣рд╛рдВ @mrunibe рдХреЛрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ StratifiedGroupKFold рдФрд░ RepeatedStratifiedGroupKFold рдХреЗ рдкреВрд░реНрдг рд╕рдВрд╕реНрдХрд░рдг рджрд┐рдП рдЧрдП рд╣реИрдВ, рдЬрд┐рдиреНрд╣реЗрдВ рдореИрдВрдиреЗ рдФрд░ рд╕рд░рд▓ рдмрдирд╛рдпрд╛ рдФрд░ рдХреБрдЫ рдЪреАрдЬреЛрдВ рдХреЛ рдмрджрд▓ рджрд┐рдпрд╛ред рдпреЗ рдХрдХреНрд╖рд╛рдПрдВ рдЗрд╕ рдбрд┐рдЬрд╛рдЗрди рдХрд╛ рднреА рдкрд╛рд▓рди рдХрд░рддреА рд╣реИрдВ рдХрд┐ рдЙрд╕реА рдкреНрд░рдХрд╛рд░ рдХреЗ рдЕрдиреНрдп рд╕реНрдХреЗрд▓реЗрд░ рд╕реАрд╡реА рдХрдХреНрд╖рд╛рдПрдВ рдХреИрд╕реЗ рдХреА рдЬрд╛рддреА рд╣реИрдВред

class StratifiedGroupKFold(_BaseKFold):
    """Stratified K-Folds iterator variant with non-overlapping groups.

    This cross-validation object is a variation of StratifiedKFold that returns
    stratified folds with non-overlapping groups. The folds are made by
    preserving the percentage of samples for each class.

    The same group will not appear in two different folds (the number of
    distinct groups has to be at least equal to the number of folds).

    The difference between GroupKFold and StratifiedGroupKFold is that
    the former attempts to create balanced folds such that the number of
    distinct groups is approximately the same in each fold, whereas
    StratifiedGroupKFold attempts to create folds which preserve the
    percentage of samples for each class.

    Read more in the :ref:`User Guide <cross_validation>`.

    Parameters
    ----------
    n_splits : int, default=5
        Number of folds. Must be at least 2.

    shuffle : bool, default=False
        Whether to shuffle each class's samples before splitting into batches.
        Note that the samples within each split will not be shuffled.

    random_state : int or RandomState instance, default=None
        When `shuffle` is True, `random_state` affects the ordering of the
        indices, which controls the randomness of each fold for each class.
        Otherwise, leave `random_state` as `None`.
        Pass an int for reproducible output across multiple function calls.
        See :term:`Glossary <random_state>`.

    Examples
    --------
    >>> import numpy as np
    >>> from sklearn.model_selection import StratifiedGroupKFold
    >>> X = np.ones((17, 2))
    >>> y = np.array([0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0])
    >>> groups = np.array([1, 1, 2, 2, 3, 3, 3, 4, 5, 5, 5, 5, 6, 6, 7, 8, 8])
    >>> cv = StratifiedGroupKFold(n_splits=3)
    >>> for train_idxs, test_idxs in cv.split(X, y, groups):
    ...     print("TRAIN:", groups[train_idxs])
    ...     print("      ", y[train_idxs])
    ...     print(" TEST:", groups[test_idxs])
    ...     print("      ", y[test_idxs])
    TRAIN: [2 2 4 5 5 5 5 6 6 7]
           [1 1 1 0 0 0 0 0 0 0]
     TEST: [1 1 3 3 3 8 8]
           [0 0 1 1 1 0 0]
    TRAIN: [1 1 3 3 3 4 5 5 5 5 8 8]
           [0 0 1 1 1 1 0 0 0 0 0 0]
     TEST: [2 2 6 6 7]
           [1 1 0 0 0]
    TRAIN: [1 1 2 2 3 3 3 6 6 7 8 8]
           [0 0 1 1 1 1 1 0 0 0 0 0]
     TEST: [4 5 5 5 5]
           [1 0 0 0 0]

    See also
    --------
    StratifiedKFold: Takes class information into account to build folds which
        retain class distributions (for binary or multiclass classification
        tasks).

    GroupKFold: K-fold iterator variant with non-overlapping groups.
    """

    def __init__(self, n_splits=5, shuffle=False, random_state=None):
        super().__init__(n_splits=n_splits, shuffle=shuffle,
                         random_state=random_state)

    # Implementation based on this kaggle kernel:
    # https://www.kaggle.com/jakubwasikowski/stratified-group-k-fold-cross-validation
    def _iter_test_indices(self, X, y, groups):
        labels_num = np.max(y) + 1
        y_counts_per_group = defaultdict(lambda: np.zeros(labels_num))
        y_distr = Counter()
        for label, group in zip(y, groups):
            y_counts_per_group[group][label] += 1
            y_distr[label] += 1

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

        groups_and_y_counts = list(y_counts_per_group.items())
        rng = check_random_state(self.random_state)
        if self.shuffle:
            rng.shuffle(groups_and_y_counts)

        for group, 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(self.n_splits):
                y_counts_per_fold[i] += y_counts
                std_per_label = []
                for label in range(labels_num):
                    std_per_label.append(np.std(
                        [y_counts_per_fold[j][label] / y_distr[label]
                         for j in range(self.n_splits)]))
                y_counts_per_fold[i] -= y_counts
                fold_eval = np.mean(std_per_label)
                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(group)

        for i in range(self.n_splits):
            test_indices = [idx for idx, group in enumerate(groups)
                            if group in groups_per_fold[i]]
            yield test_indices


class RepeatedStratifiedGroupKFold(_RepeatedSplits):
    """Repeated Stratified K-Fold cross validator.

    Repeats Stratified K-Fold with non-overlapping groups n times with
    different randomization in each repetition.

    Read more in the :ref:`User Guide <cross_validation>`.

    Parameters
    ----------
    n_splits : int, default=5
        Number of folds. Must be at least 2.

    n_repeats : int, default=10
        Number of times cross-validator needs to be repeated.

    random_state : int or RandomState instance, default=None
        Controls the generation of the random states for each repetition.
        Pass an int for reproducible output across multiple function calls.
        See :term:`Glossary <random_state>`.

    Examples
    --------
    >>> import numpy as np
    >>> from sklearn.model_selection import RepeatedStratifiedGroupKFold
    >>> X = np.ones((17, 2))
    >>> y = np.array([0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0])
    >>> groups = np.array([1, 1, 2, 2, 3, 3, 3, 4, 5, 5, 5, 5, 6, 6, 7, 8, 8])
    >>> cv = RepeatedStratifiedGroupKFold(n_splits=2, n_repeats=2,
    ...                                   random_state=36851234)
    >>> for train_index, test_index in cv.split(X, y, groups):
    ...     print("TRAIN:", groups[train_idxs])
    ...     print("      ", y[train_idxs])
    ...     print(" TEST:", groups[test_idxs])
    ...     print("      ", y[test_idxs])
    TRAIN: [2 2 4 5 5 5 5 8 8]
           [1 1 1 0 0 0 0 0 0]
     TEST: [1 1 3 3 3 6 6 7]
           [0 0 1 1 1 0 0 0]
    TRAIN: [1 1 3 3 3 6 6 7]
           [0 0 1 1 1 0 0 0]
     TEST: [2 2 4 5 5 5 5 8 8]
           [1 1 1 0 0 0 0 0 0]
    TRAIN: [3 3 3 4 7 8 8]
           [1 1 1 1 0 0 0]
     TEST: [1 1 2 2 5 5 5 5 6 6]
           [0 0 1 1 0 0 0 0 0 0]
    TRAIN: [1 1 2 2 5 5 5 5 6 6]
           [0 0 1 1 0 0 0 0 0 0]
     TEST: [3 3 3 4 7 8 8]
           [1 1 1 1 0 0 0]

    Notes
    -----
    Randomized CV splitters may return different results for each call of
    split. You can make the results identical by setting `random_state`
    to an integer.

    See also
    --------
    RepeatedStratifiedKFold: Repeats Stratified K-Fold n times.
    """

    def __init__(self, n_splits=5, n_repeats=10, random_state=None):
        super().__init__(StratifiedGroupKFold, n_splits=n_splits,
                         n_repeats=n_repeats, random_state=random_state)

@hermidalc рдореИрдВ рд╕рдордп-рд╕рдордп рдкрд░ рдЗрд╕ рдкрд░ рдкреАрдЫреЗ рдореБрдбрд╝рдХрд░ рджреЗрдЦрдиреЗ рдкрд░ рдХрд╛рдлреА рдЙрд▓рдЭрди рдореЗрдВ рд╣реВрдВ рдХрд┐ рд╣рдордиреЗ рдХреНрдпрд╛ рд╣рд▓ рдХрд┐рдпрд╛ рд╣реИред (рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ рдореЗрд░рд╛ рд╕рдордп рд╡рд╣ рдирд╣реАрдВ рд╣реИ рдЬреЛ рдкрд╣рд▓реЗ рд╣реБрдЖ рдХрд░рддрд╛ рдерд╛!) тАЛтАЛрдХреНрдпрд╛ рдЖрдк рдореБрдЭреЗ рдЗрд╕ рдмрд╛рдд рдХрд╛ рдЕрдВрджрд╛рдЬрд╛ рджреЗ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдЖрдк рд╕реНрдХрд┐рдХрд┐рдЯ-рд▓рд░реНрди рдореЗрдВ рдХреНрдпрд╛ рд╢рд╛рдорд┐рд▓ рдХрд░рдиреЗ рдХреА рд╕рд▓рд╛рд╣ рджреЗрдВрдЧреЗ?

@hermidalc рдореИрдВ рд╕рдордп-рд╕рдордп рдкрд░ рдЗрд╕ рдкрд░ рдкреАрдЫреЗ рдореБрдбрд╝рдХрд░ рджреЗрдЦрдиреЗ рдкрд░ рдХрд╛рдлреА рдЙрд▓рдЭрди рдореЗрдВ рд╣реВрдВ рдХрд┐ рд╣рдордиреЗ рдХреНрдпрд╛ рд╣рд▓ рдХрд┐рдпрд╛ рд╣реИред (рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ рдореЗрд░рд╛ рд╕рдордп рд╡рд╣ рдирд╣реАрдВ рд╣реИ рдЬреЛ рдкрд╣рд▓реЗ рд╣реБрдЖ рдХрд░рддрд╛ рдерд╛!) тАЛтАЛрдХреНрдпрд╛ рдЖрдк рдореБрдЭреЗ рдЗрд╕ рдмрд╛рдд рдХрд╛ рдЕрдВрджрд╛рдЬрд╛ рджреЗ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдЖрдк рд╕реНрдХрд┐рдХрд┐рдЯ-рд▓рд░реНрди рдореЗрдВ рдХреНрдпрд╛ рд╢рд╛рдорд┐рд▓ рдХрд░рдиреЗ рдХреА рд╕рд▓рд╛рд╣ рджреЗрдВрдЧреЗ?

рдореИрдВрдиреЗ #15239 рдореЗрдВ рдЬреЛ рдХрд┐рдпрд╛ рдЙрд╕рд╕реЗ рдмреЗрд╣рддрд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред рдЙрд╕ рдкреАрдЖрд░ рдореЗрдВ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рд▓реЗрдХрд┐рди рддрд░реНрдХ рдХреЛ рд╕реАрдзрд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдореВрд╣реЛрдВ рдкрд░ рд╕реНрддрд░реАрдХрд░рдг рдХрд░рддрд╛ рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдпрд╣ рдЖрджрд░реНрд╢ рдирд╣реАрдВ рд╣реИред

рддреЛ рдореИрдВрдиреЗ рдКрдкрд░ рдЬреЛ рдХрд┐рдпрд╛ (рдЬрдХреБрдмрд╡рд╛рд╕рд┐рдХреЛрд╡реНрд╕реНрдХреА рд╕реЗ @mrunibe рдФрд░ kaggle рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж) StratifiedGroupKFold рдХрд╛ рдмреЗрд╣рддрд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реИ рдЬреЛ рдирдореВрдиреЛрдВ рдкрд░ рд╕реНрддрд░реАрдХреГрдд рдХрд░рддрд╛ рд╣реИред рдореИрдВ рдмреЗрд╣рддрд░ StratifiedGroupShuffleSplit рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрд╕реА рддрд░реНрдХ рдХреЛ рдкреЛрд░реНрдЯ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдФрд░ рдлрд┐рд░ рдпрд╣ рддреИрдпрд╛рд░ рд╣реЛ рдЬрд╛рдПрдЧрд╛ред рдореИрдВ рдкреБрд░рд╛рдиреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдирдпрд╛ рдХреЛрдб #15239 рдореЗрдВ рдбрд╛рд▓реВрдВрдЧрд╛ред

рдореИрдВ рдЕрдкрдиреЗ рдкреАрдЖрд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреНрд╖рдорд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдЬреЛ рдЕрдзреВрд░реЗ рд╣реИрдВ, рдореИрдВ рдЕрдкрдиреА рдкреАрдПрдЪрдбреА рдкреНрд░рд╛рдкреНрдд рдХрд░ рд░рд╣рд╛ рд╣реВрдВ рдЗрд╕рд▓рд┐рдП рдореЗрд░реЗ рдкрд╛рд╕ рдХрднреА рд╕рдордп рдирд╣реАрдВ рд╣реИ!

рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдкреНрд░рджрд╛рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП @hermidalc рдФрд░ @mrunibe рдХреЛ рдзрдиреНрдпрд╡рд╛рджред рдореИрдВ рдЪрд┐рдХрд┐рддреНрд╕рд╛ рдбреЗрдЯрд╛ рд╕реЗ рдирд┐рдкрдЯрдиреЗ рдХреЗ рд▓рд┐рдП StratifiedGroupKFold рд╡рд┐рдзрд┐ рдХреА рднреА рддрд▓рд╛рд╢ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ рдЬрд┐рд╕рдореЗрдВ рдордЬрдмреВрдд рд╡рд░реНрдЧ рдЕрд╕рдВрддреБрд▓рди рдФрд░ рдкреНрд░рддрд┐ рд╡рд┐рд╖рдп рдирдореВрдиреЛрдВ рдХреА рдПрдХ рдмрд╣реБрдд рднрд┐рдиреНрди рд╕рдВрдЦреНрдпрд╛ рд╣реИред GroupKFold рдЕрдкрдиреЗ рдЖрдк рдореЗрдВ рдХреЗрд╡рд▓ рдПрдХ рд╡рд░реНрдЧ рд╡рд╛рд▓реЗ рдкреНрд░рд╢рд┐рдХреНрд╖рдг рдбреЗрдЯрд╛ рдЙрдк-рд╕реЗрдЯ рдмрдирд╛рддрд╛ рд╣реИред

рдореИрдВ рдмреЗрд╣рддрд░ рд╕реНрдЯреНрд░реИрдЯрд┐рдлрд╛рдЗрдбрдЧреНрд░реБрдкрд╢рдлрд▓рд╕реНрдкреНрд▓рд┐рдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрд╕реА рддрд░реНрдХ рдХреЛ рдкреЛрд░реНрдЯ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдФрд░ рдлрд┐рд░ рдпрд╣ рддреИрдпрд╛рд░ рд╣реЛ рдЬрд╛рдПрдЧрд╛ред

StratifiedGroupShuffleSplit рддреИрдпрд╛рд░ рд╣реЛрдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рд╣рдо рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ StratifiedGroupKFold рдХреЛ рдорд░реНрдЬ рдХрд░рдиреЗ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдореИрдВ рдЕрдкрдиреЗ рдкреАрдЖрд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреНрд╖рдорд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдЬреЛ рдЕрдзреВрд░реЗ рд╣реИрдВ, рдореИрдВ рдЕрдкрдиреА рдкреАрдПрдЪрдбреА рдкреНрд░рд╛рдкреНрдд рдХрд░ рд░рд╣рд╛ рд╣реВрдВ рдЗрд╕рд▓рд┐рдП рдореЗрд░реЗ рдкрд╛рд╕ рдХрднреА рд╕рдордп рдирд╣реАрдВ рд╣реИ!

рдЕрдЧрд░ рдЖрдк рдЗрд╕реЗ рдкреВрд░рд╛ рдХрд░рдиреЗ рдореЗрдВ рд╕рд╣рд╛рдпрддрд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рддреЛ рд╣рдореЗрдВ рдмрддрд╛рдПрдВ!

рдФрд░ рдЖрдкрдХреЗ рдкреАрдПрдЪрдбреА рдХрд╛рд░реНрдп рдХреЗ рд▓рд┐рдП рд╢реБрднрдХрд╛рдордирд╛рдПрдБ

рдпрд╣рд╛рдВ @mrunibe рдХреЛрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ StratifiedGroupKFold рдФрд░ RepeatedStratifiedGroupKFold рдХреЗ рдкреВрд░реНрдг рд╕рдВрд╕реНрдХрд░рдг рджрд┐рдП рдЧрдП рд╣реИрдВ, рдЬрд┐рдиреНрд╣реЗрдВ рдореИрдВрдиреЗ рдФрд░ рд╕рд░рд▓ рдмрдирд╛рдпрд╛ рдФрд░ рдХреБрдЫ рдЪреАрдЬреЛрдВ рдХреЛ рдмрджрд▓ рджрд┐рдпрд╛ред рдпреЗ рдХрдХреНрд╖рд╛рдПрдВ рдЗрд╕ рдбрд┐рдЬрд╛рдЗрди рдХрд╛ рднреА рдкрд╛рд▓рди рдХрд░рддреА рд╣реИрдВ рдХрд┐ рдЙрд╕реА рдкреНрд░рдХрд╛рд░ рдХреЗ рдЕрдиреНрдп рд╕реНрдХреЗрд▓реЗрд░ рд╕реАрд╡реА рдХрдХреНрд╖рд╛рдПрдВ рдХреИрд╕реЗ рдХреА рдЬрд╛рддреА рд╣реИрдВред

рдХреНрдпрд╛ рдЗрд╕реЗ рдЖрдЬрдорд╛рдирд╛ рд╕рдВрднрд╡ рд╣реИ? рдореИрдВрдиреЗ рдХреБрдЫ рд╡рд┐рднрд┐рдиреНрди рдирд┐рд░реНрднрд░рддрд╛рдУрдВ рдХреЗ рд╕рд╛рде рдХрдЯ рдФрд░ рдкреЗрд╕реНрдЯ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреА рд▓реЗрдХрд┐рди рдпрд╣ рдХрднреА рдЦрддреНрдо рдирд╣реАрдВ рд╣реБрдЖред рдореИрдВ рдЗрд╕ рдХрдХреНрд╖рд╛ рдХреЛ рдЕрдкрдиреЗ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдореЗрдВ рдЖрдЬрдорд╛рдирд╛ рдкрд╕рдВрдж рдХрд░реВрдВрдЧрд╛ред рдмрд╕ рдпрд╣ рджреЗрдЦрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ рдХрд┐ рдРрд╕рд╛ рдХрд░рдиреЗ рдХрд╛ рдХреЛрдИ рддрд░реАрдХрд╛ рдЙрдкрд▓рдмреНрдз рд╣реИ рдпрд╛ рдирд╣реАрдВред

@hermidalc рдЖрд╢рд╛ рд╣реИ рдХрд┐ рдЖрдкрдХрд╛ рдкреАрдПрдЪрдбреА рдХрд╛рд░реНрдп рд╕рдлрд▓ рд╣реЛ рдЧрдпрд╛ рд╣реИ!
рдореИрдВ рдЗрд╕ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рджреЗрдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдЙрддреНрд╕реБрдХ рд╣реВрдВ рдХреНрдпреЛрдВрдХрд┐ рднреВрд╡рд┐рдЬреНрдЮрд╛рди рдореЗрдВ рдореЗрд░реЗ рдкреАрдПрдЪрдбреА рдХрд╛рд░реНрдп рдХреЛ рд╕рдореВрд╣ рдирд┐рдпрдВрддреНрд░рдг рдХреЗ рд╕рд╛рде рдЗрд╕ рд╕реНрддрд░реАрдХрд░рдг рд╕реБрд╡рд┐рдзрд╛ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдореИрдВрдиреЗ рдЕрдкрдиреЗ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдкрд░ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рдиреЗ рдХреЗ рдЗрд╕ рд╡рд┐рдЪрд╛рд░ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдореЗрдВ рдХреБрдЫ рдШрдВрдЯреЗ рдмрд┐рддрд╛рдП рд╣реИрдВред рд▓реЗрдХрд┐рди рдореИрдВрдиреЗ рдЙрд╕реА рд╡рдЬрд╣ рд╕реЗ рдЗрд╕реЗ рдЦрддреНрдо рдХрд░рдирд╛ рдЫреЛрдбрд╝ рджрд┐рдпрд╛...рдкреАрдПрдЪрдбреА рдХреА рдкреНрд░рдЧрддрд┐ред рдЗрд╕рд▓рд┐рдП, рдореИрдВ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕рдордЭ рд╕рдХрддрд╛ рд╣реВрдВ рдХрд┐ рдХреИрд╕реЗ рдкреАрдПрдЪрдбреА рдХрд╛ рдХрд╛рдо рдХрд┐рд╕реА рд╡реНрдпрдХреНрддрд┐ рдХреЗ рд╕рдордп рдХреЛ рдЦрд░рд╛рдм рдХрд░ рд╕рдХрддрд╛ рд╣реИред рдПрд▓рдУрдПрд▓ рдХреЛрдИ рджрдмрд╛рд╡ рдирд╣реАрдВред рдЕрднреА рдХреЗ рд▓рд┐рдП, рдореИрдВ рдПрдХ рд╡рд┐рдХрд▓реНрдк рдХреЗ рд░реВрдк рдореЗрдВ GroupShuffleSplit рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВред

рдЪрд┐рдпрд░реНрд╕

@bfeeny @dispink рдКрдкрд░ рд▓рд┐рдЦреА рдЧрдИ рджреЛ рдХрдХреНрд╖рд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдмрд╣реБрдд рдЖрд╕рд╛рди рд╣реИред рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЗ рд╕рд╛рде рдПрдХ рдлрд╝рд╛рдЗрд▓ рдмрдирд╛рдПрдВ рдЬреИрд╕реЗ split.py ред рдлрд┐рд░ рдЖрдкрдХреЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛрдб рдореЗрдВ рдпрджрд┐ рд╕реНрдХреНрд░рд┐рдкреНрдЯ split.py рдХреЗ рд╕рдорд╛рди рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдореЗрдВ рд╣реИ рддреЛ рдЖрдк рдмрд╕ from split import StratifiedGroupKFold, RepeatedStratifiedGroupKFold рдЖрдпрд╛рдд рдХрд░рддреЗ рд╣реИрдВ

from collections import Counter, defaultdict

import numpy as np

from sklearn.model_selection._split import _BaseKFold, _RepeatedSplits
from sklearn.utils.validation import check_random_state


class StratifiedGroupKFold(_BaseKFold):
    """Stratified K-Folds iterator variant with non-overlapping groups.

    This cross-validation object is a variation of StratifiedKFold that returns
    stratified folds with non-overlapping groups. The folds are made by
    preserving the percentage of samples for each class.

    The same group will not appear in two different folds (the number of
    distinct groups has to be at least equal to the number of folds).

    The difference between GroupKFold and StratifiedGroupKFold is that
    the former attempts to create balanced folds such that the number of
    distinct groups is approximately the same in each fold, whereas
    StratifiedGroupKFold attempts to create folds which preserve the
    percentage of samples for each class.

    Read more in the :ref:`User Guide <cross_validation>`.

    Parameters
    ----------
    n_splits : int, default=5
        Number of folds. Must be at least 2.

    shuffle : bool, default=False
        Whether to shuffle each class's samples before splitting into batches.
        Note that the samples within each split will not be shuffled.

    random_state : int or RandomState instance, default=None
        When `shuffle` is True, `random_state` affects the ordering of the
        indices, which controls the randomness of each fold for each class.
        Otherwise, leave `random_state` as `None`.
        Pass an int for reproducible output across multiple function calls.
        See :term:`Glossary <random_state>`.

    Examples
    --------
    >>> import numpy as np
    >>> from sklearn.model_selection import StratifiedGroupKFold
    >>> X = np.ones((17, 2))
    >>> y = np.array([0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0])
    >>> groups = np.array([1, 1, 2, 2, 3, 3, 3, 4, 5, 5, 5, 5, 6, 6, 7, 8, 8])
    >>> cv = StratifiedGroupKFold(n_splits=3)
    >>> for train_idxs, test_idxs in cv.split(X, y, groups):
    ...     print("TRAIN:", groups[train_idxs])
    ...     print("      ", y[train_idxs])
    ...     print(" TEST:", groups[test_idxs])
    ...     print("      ", y[test_idxs])
    TRAIN: [2 2 4 5 5 5 5 6 6 7]
           [1 1 1 0 0 0 0 0 0 0]
     TEST: [1 1 3 3 3 8 8]
           [0 0 1 1 1 0 0]
    TRAIN: [1 1 3 3 3 4 5 5 5 5 8 8]
           [0 0 1 1 1 1 0 0 0 0 0 0]
     TEST: [2 2 6 6 7]
           [1 1 0 0 0]
    TRAIN: [1 1 2 2 3 3 3 6 6 7 8 8]
           [0 0 1 1 1 1 1 0 0 0 0 0]
     TEST: [4 5 5 5 5]
           [1 0 0 0 0]

    See also
    --------
    StratifiedKFold: Takes class information into account to build folds which
        retain class distributions (for binary or multiclass classification
        tasks).

    GroupKFold: K-fold iterator variant with non-overlapping groups.
    """

    def __init__(self, n_splits=5, shuffle=False, random_state=None):
        super().__init__(n_splits=n_splits, shuffle=shuffle,
                         random_state=random_state)

    # Implementation based on this kaggle kernel:
    # https://www.kaggle.com/jakubwasikowski/stratified-group-k-fold-cross-validation
    def _iter_test_indices(self, X, y, groups):
        labels_num = np.max(y) + 1
        y_counts_per_group = defaultdict(lambda: np.zeros(labels_num))
        y_distr = Counter()
        for label, group in zip(y, groups):
            y_counts_per_group[group][label] += 1
            y_distr[label] += 1

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

        groups_and_y_counts = list(y_counts_per_group.items())
        rng = check_random_state(self.random_state)
        if self.shuffle:
            rng.shuffle(groups_and_y_counts)

        for group, 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(self.n_splits):
                y_counts_per_fold[i] += y_counts
                std_per_label = []
                for label in range(labels_num):
                    std_per_label.append(np.std(
                        [y_counts_per_fold[j][label] / y_distr[label]
                         for j in range(self.n_splits)]))
                y_counts_per_fold[i] -= y_counts
                fold_eval = np.mean(std_per_label)
                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(group)

        for i in range(self.n_splits):
            test_indices = [idx for idx, group in enumerate(groups)
                            if group in groups_per_fold[i]]
            yield test_indices


class RepeatedStratifiedGroupKFold(_RepeatedSplits):
    """Repeated Stratified K-Fold cross validator.

    Repeats Stratified K-Fold with non-overlapping groups n times with
    different randomization in each repetition.

    Read more in the :ref:`User Guide <cross_validation>`.

    Parameters
    ----------
    n_splits : int, default=5
        Number of folds. Must be at least 2.

    n_repeats : int, default=10
        Number of times cross-validator needs to be repeated.

    random_state : int or RandomState instance, default=None
        Controls the generation of the random states for each repetition.
        Pass an int for reproducible output across multiple function calls.
        See :term:`Glossary <random_state>`.

    Examples
    --------
    >>> import numpy as np
    >>> from sklearn.model_selection import RepeatedStratifiedGroupKFold
    >>> X = np.ones((17, 2))
    >>> y = np.array([0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0])
    >>> groups = np.array([1, 1, 2, 2, 3, 3, 3, 4, 5, 5, 5, 5, 6, 6, 7, 8, 8])
    >>> cv = RepeatedStratifiedGroupKFold(n_splits=2, n_repeats=2,
    ...                                   random_state=36851234)
    >>> for train_index, test_index in cv.split(X, y, groups):
    ...     print("TRAIN:", groups[train_idxs])
    ...     print("      ", y[train_idxs])
    ...     print(" TEST:", groups[test_idxs])
    ...     print("      ", y[test_idxs])
    TRAIN: [2 2 4 5 5 5 5 8 8]
           [1 1 1 0 0 0 0 0 0]
     TEST: [1 1 3 3 3 6 6 7]
           [0 0 1 1 1 0 0 0]
    TRAIN: [1 1 3 3 3 6 6 7]
           [0 0 1 1 1 0 0 0]
     TEST: [2 2 4 5 5 5 5 8 8]
           [1 1 1 0 0 0 0 0 0]
    TRAIN: [3 3 3 4 7 8 8]
           [1 1 1 1 0 0 0]
     TEST: [1 1 2 2 5 5 5 5 6 6]
           [0 0 1 1 0 0 0 0 0 0]
    TRAIN: [1 1 2 2 5 5 5 5 6 6]
           [0 0 1 1 0 0 0 0 0 0]
     TEST: [3 3 3 4 7 8 8]
           [1 1 1 1 0 0 0]

    Notes
    -----
    Randomized CV splitters may return different results for each call of
    split. You can make the results identical by setting `random_state`
    to an integer.

    See also
    --------
    RepeatedStratifiedKFold: Repeats Stratified K-Fold n times.
    """

    def __init__(self, n_splits=5, n_repeats=10, random_state=None):
        super().__init__(StratifiedGroupKFold, n_splits=n_splits,
                         n_repeats=n_repeats, random_state=random_state)

@hermidalc рд╕рдХрд╛рд░рд╛рддреНрдордХ рдЙрддреНрддрд░ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж!
рдЬреИрд╕рд╛ рдЖрдкрдиреЗ рд╡рд░реНрдгрди рдХрд┐рдпрд╛ рд╣реИ, рдореИрдВ рдЗрд╕реЗ рдЬрд▓реНрджреА рд╕реЗ рдЕрдкрдирд╛ рд▓реЗрддрд╛ рд╣реВрдВред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдореИрдВ рдХреЗрд╡рд▓ рдЙрди рд╡рд┐рднрд╛рдЬрдиреЛрдВ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВ рдЬрд┐рдирдХреЗ рдкрд╛рд╕ рдХреЗрд╡рд▓ рдкреНрд░рд╢рд┐рдХреНрд╖рдг рдпрд╛ рдкрд░реАрдХреНрд╖рдг рд╕реЗрдЯ рдореЗрдВ рдбреЗрдЯрд╛ рд╣реИред рдЬрд╣рд╛рдВ рддрдХ тАЛтАЛтАЛтАЛрдореИрдВ рдХреЛрдб рд╡рд┐рд╡рд░рдг рдХреЛ рд╕рдордЭрддрд╛ рд╣реВрдВ, рдкреНрд░рд╢рд┐рдХреНрд╖рдг рдФрд░ рдкрд░реАрдХреНрд╖рдг рд╕реЗрдЯ рдХреЗ рдмреАрдЪ рдЕрдиреБрдкрд╛рдд рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЛрдИ рдкреИрд░рд╛рдореАрдЯрд░ рдирд╣реАрдВ рд╣реИ, рд╣реИ рдирд╛?
рдореБрдЭреЗ рдкрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рд╕реНрддрд░реАрдХрд░рдг, рд╕рдореВрд╣ рдирд┐рдпрдВрддреНрд░рдг рдФрд░ рдбреЗрдЯрд╛рд╕реЗрдЯ рдЕрдиреБрдкрд╛рдд рдХреЗ рдмреАрдЪ рдПрдХ рд╕рдВрдШрд░реНрд╖ рд╣реИ... рдЗрд╕рд▓рд┐рдП рдореИрдВрдиреЗ рдЬрд╛рд░реА рд░рдЦрдирд╛ рдЫреЛрдбрд╝ рджрд┐рдпрд╛... рд▓реЗрдХрд┐рди рд╢рд╛рдпрдж рд╣рдо рдЕрднреА рднреА рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдордЭреМрддрд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
image

рднрд╡рджреАрдп

@hermidalc рд╕рдХрд╛рд░рд╛рддреНрдордХ рдЙрддреНрддрд░ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж!
рдЬреИрд╕рд╛ рдЖрдкрдиреЗ рд╡рд░реНрдгрди рдХрд┐рдпрд╛ рд╣реИ, рдореИрдВ рдЗрд╕реЗ рдЬрд▓реНрджреА рд╕реЗ рдЕрдкрдирд╛ рд▓реЗрддрд╛ рд╣реВрдВред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдореИрдВ рдХреЗрд╡рд▓ рдЙрди рд╡рд┐рднрд╛рдЬрдиреЛрдВ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВ рдЬрд┐рдирдХреЗ рдкрд╛рд╕ рдХреЗрд╡рд▓ рдкреНрд░рд╢рд┐рдХреНрд╖рдг рдпрд╛ рдкрд░реАрдХреНрд╖рдг рд╕реЗрдЯ рдореЗрдВ рдбреЗрдЯрд╛ рд╣реИред рдЬрд╣рд╛рдВ рддрдХ тАЛтАЛтАЛтАЛрдореИрдВ рдХреЛрдб рд╡рд┐рд╡рд░рдг рдХреЛ рд╕рдордЭрддрд╛ рд╣реВрдВ, рдкреНрд░рд╢рд┐рдХреНрд╖рдг рдФрд░ рдкрд░реАрдХреНрд╖рдг рд╕реЗрдЯ рдХреЗ рдмреАрдЪ рдЕрдиреБрдкрд╛рдд рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЛрдИ рдкреИрд░рд╛рдореАрдЯрд░ рдирд╣реАрдВ рд╣реИ, рд╣реИ рдирд╛?
рдореБрдЭреЗ рдкрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рд╕реНрддрд░реАрдХрд░рдг, рд╕рдореВрд╣ рдирд┐рдпрдВрддреНрд░рдг рдФрд░ рдбреЗрдЯрд╛рд╕реЗрдЯ рдЕрдиреБрдкрд╛рдд рдХреЗ рдмреАрдЪ рдПрдХ рд╕рдВрдШрд░реНрд╖ рд╣реИ... рдЗрд╕рд▓рд┐рдП рдореИрдВрдиреЗ рдЬрд╛рд░реА рд░рдЦрдирд╛ рдЫреЛрдбрд╝ рджрд┐рдпрд╛... рд▓реЗрдХрд┐рди рд╢рд╛рдпрдж рд╣рдо рдЕрднреА рднреА рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдордЭреМрддрд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдореИрдВрдиреЗ split.py рдмрдирд╛рдпрд╛ рдФрд░ рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рдХреЛ ipython рдореЗрдВ рдЪрд▓рд╛рдпрд╛ рдФрд░ рдпрд╣ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рдореИрдВ рд▓рдВрдмреЗ рд╕рдордп рд╕реЗ рдЕрдкрдиреЗ рдХрд╛рдо рдореЗрдВ рдЗрди рдХрд╕реНрдЯрдо рд╕реАрд╡реА рдЗрдЯрд░реЗрдЯрд░реНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ рдФрд░ рдЙрдиреНрд╣реЗрдВ рдореЗрд░реА рддрд░рдл рд╕реЗ рдХреЛрдИ рд╕рдорд╕реНрдпрд╛ рдирд╣реАрдВ рд╣реИред BTW рдореИрдВ scikit-learn 0.22.2 0.23.x рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ, рдЗрд╕рд▓рд┐рдП рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдирд╣реАрдВ рд╣реИ рдХрд┐ рдпрд╣ рд╕рдорд╕реНрдпрд╛ рдХрд╛ рдХрд╛рд░рдг рд╣реИ рдпрд╛ рдирд╣реАрдВред рдХреНрдпрд╛ рдЖрдк рдХреГрдкрдпрд╛ рдиреАрдЪреЗ рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рдХреЛ рдЪрд▓рд╛рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдХреНрдпрд╛ рдЖрдк рдЗрд╕реЗ рдкреБрди: рдкреЗрд╢ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ? рдпрджрд┐ рдЖрдк рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рдЖрдкрдХреЗ рдХрд╛рдо рдореЗрдВ y рдФрд░ groups рдХреЗ рд╕рд╛рде рдХреБрдЫ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред

In [6]: import numpy as np 
   ...: from split import StratifiedGroupKFold 
   ...:  
   ...: X = np.ones((17, 2)) 
   ...: y = np.array([0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]) 
   ...: groups = np.array([1, 1, 2, 2, 3, 3, 3, 4, 5, 5, 5, 5, 6, 6, 7, 8, 8]) 
   ...: cv = StratifiedGroupKFold(n_splits=3, shuffle=True, random_state=777) 
   ...: for train_idxs, test_idxs in cv.split(X, y, groups): 
   ...:     print("TRAIN:", groups[train_idxs]) 
   ...:     print("      ", y[train_idxs]) 
   ...:     print(" TEST:", groups[test_idxs]) 
   ...:     print("      ", y[test_idxs]) 
   ...:                                                                                                                                                                                                    
TRAIN: [2 2 4 5 5 5 5 6 6 7]
       [1 1 1 0 0 0 0 0 0 0]
 TEST: [1 1 3 3 3 8 8]
       [0 0 1 1 1 0 0]
TRAIN: [1 1 3 3 3 4 5 5 5 5 8 8]
       [0 0 1 1 1 1 0 0 0 0 0 0]
 TEST: [2 2 6 6 7]
       [1 1 0 0 0]
TRAIN: [1 1 2 2 3 3 3 6 6 7 8 8]
       [0 0 1 1 1 1 1 0 0 0 0 0]
 TEST: [4 5 5 5 5]
       [1 0 0 0 0]

рдЗрд╕ рд╕реБрд╡рд┐рдзрд╛ рдореЗрдВ рдирд┐рдпрдорд┐рдд рд░реБрдЪрд┐ рдкреНрд░рддреАрдд рд╣реЛрддреА рд╣реИ, @hermidalc , рдФрд░ рд╣рдо
рдпрджрд┐ рдЖрдк рдмреБрд░рд╛ рди рдорд╛рдиреЗрдВ рддреЛ рдЗрд╕реЗ рдЦрддреНрдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рд╕реА рдХреЛ рдвреВрдВрдв рд╕рдХрддреЗ рд╣реИрдВред

@hermidalc 'рдЖрдкрдХреЛ рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдирд╛ рд╣реЛрдЧрд╛ рдХрд┐ рдПрдХ рд╣реА рд╕рдореВрд╣ рдХреЗ рдкреНрд░рддреНрдпреЗрдХ рдирдореВрдиреЗ рдореЗрдВ рд╕рдорд╛рди рд╡рд░реНрдЧ рд▓реЗрдмрд▓ рд╣реЛред' рдЬрд╛рд╣рд┐рд░ рд╣реИ рдпрд╣реА рд╕рдорд╕реНрдпрд╛ рд╣реИред рдПрдХ рд╣реА рд╕рдореВрд╣ рдореЗрдВ рдореЗрд░реЗ рдирдореВрдиреЗ рд╕рдорд╛рди рдХрдХреНрд╖рд╛ рд╕рд╛рдЭрд╛ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВред рдордореНрдо...рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рд╡рд┐рдХрд╛рд╕ рдХреА рдПрдХ рдФрд░ рд╢рд╛рдЦрд╛ рд╣реИред
рд╡реИрд╕реЗ рднреА рдЖрдкрдХрд╛ рдмрд╣реБрдд-рдмрд╣реБрдд рдзрдиреНрдпрд╡рд╛рджред

@hermidalc 'рдЖрдкрдХреЛ рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдирд╛ рд╣реЛрдЧрд╛ рдХрд┐ рдПрдХ рд╣реА рд╕рдореВрд╣ рдХреЗ рдкреНрд░рддреНрдпреЗрдХ рдирдореВрдиреЗ рдореЗрдВ рд╕рдорд╛рди рд╡рд░реНрдЧ рд▓реЗрдмрд▓ рд╣реЛред' рдЬрд╛рд╣рд┐рд░ рд╣реИ рдпрд╣реА рд╕рдорд╕реНрдпрд╛ рд╣реИред рдПрдХ рд╣реА рд╕рдореВрд╣ рдореЗрдВ рдореЗрд░реЗ рдирдореВрдиреЗ рд╕рдорд╛рди рдХрдХреНрд╖рд╛ рд╕рд╛рдЭрд╛ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВред рдордореНрдо...рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рд╡рд┐рдХрд╛рд╕ рдХреА рдПрдХ рдФрд░ рд╢рд╛рдЦрд╛ рд╣реИред
рд╡реИрд╕реЗ рднреА рдЖрдкрдХрд╛ рдмрд╣реБрдд-рдмрд╣реБрдд рдзрдиреНрдпрд╡рд╛рджред

рд╣рд╛рдБ, рдпрд╣рд╛рдБ рд╡рд┐рднрд┐рдиреНрди рдзрд╛рдЧреЛрдВ рдореЗрдВ рдЗрд╕ рдкрд░ рдЪрд░реНрдЪрд╛ рдХреА рдЧрдИ рд╣реИред рдпрд╣ рдПрдХ рдФрд░ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рдЙрдкрдпреЛрдЧ рдХрд╛ рдорд╛рдорд▓рд╛ рд╣реИ рдЬреЛ рдЙрдкрдпреЛрдЧреА рд╣реИ, рд▓реЗрдХрд┐рди рдореЗрд░реЗ рдЬреИрд╕реЗ рдХрдИ рд▓реЛрдЧреЛрдВ рдХреЛ рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдЙрд╕ рдЙрдкрдпреЛрдЧ рдХреЗ рдорд╛рдорд▓реЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдХреБрдЫ рдХреА рдЬрд░реВрд░рдд рд╣реИ рдЬреЛ рд╕рдореВрд╣реЛрдВ рдХреЛ рдПрдХ рд╕рд╛рде рд░рдЦрддрд╛ рд╣реИ рдлрд┐рд░ рднреА рдирдореВрдиреЛрдВ рдкрд░ рд╕реНрддрд░реАрдХреГрдд рдХрд░рддрд╛ рд╣реИред рдЙрдкрд░реЛрдХреНрдд рдХреЛрдб рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдпрд╣ рд╣реИ рдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рд╕рдореВрд╣ рдХреЗ рд╕рднреА рдирдореВрдиреЗ рдПрдХ рд╣реА рд╡рд░реНрдЧ рдХреЗ рд╣реЛрдВред

рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ @dispink рдореИрдВ рдЧрд▓рдд рдерд╛, рдЗрд╕ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдПрдХ рд╕рдореВрд╣ рдХреЗ рд╕рднреА рд╕рджрд╕реНрдп рдПрдХ рд╣реА рд╡рд░реНрдЧ рдХреЗ рд╣реЛрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП:

In [2]: X = np.ones((17, 2)) 
   ...: y =      np.array([0, 2, 1, 1, 2, 0, 0, 1, 2, 1, 1, 1, 0, 2, 0, 1, 0]) 
   ...: groups = np.array([1, 1, 2, 2, 3, 3, 3, 4, 5, 5, 5, 5, 6, 6, 7, 8, 8]) 
   ...: cv = StratifiedGroupKFold(n_splits=3) 
   ...: for train_idxs, test_idxs in cv.split(X, y, groups): 
   ...:     print("TRAIN:", groups[train_idxs]) 
   ...:     print("      ", y[train_idxs]) 
   ...:     print(" TEST:", groups[test_idxs]) 
   ...:     print("      ", y[test_idxs]) 
   ...:                                                                                                                                                                                                    
TRAIN: [1 1 2 2 3 3 3 4 8 8]
       [0 2 1 1 2 0 0 1 1 0]
 TEST: [5 5 5 5 6 6 7]
       [2 1 1 1 0 2 0]
TRAIN: [1 1 4 5 5 5 5 6 6 7 8 8]
       [0 2 1 2 1 1 1 0 2 0 1 0]
 TEST: [2 2 3 3 3]
       [1 1 2 0 0]
TRAIN: [2 2 3 3 3 5 5 5 5 6 6 7]
       [1 1 2 0 0 2 1 1 1 0 2 0]
 TEST: [1 1 4 8 8]
       [0 2 1 1 0]

рдЗрд╕рд▓рд┐рдП рдореБрдЭреЗ рдкреВрд░рд╛ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдЖрдкрдХреЗ рдбреЗрдЯрд╛ рдХреЗ рд╕рд╛рде рдХреНрдпрд╛ рд╣реЛ рд░рд╣рд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЖрдкрдХреЗ рд╕реНрдХреНрд░реАрдирд╢реЙрдЯ рд╕реЗ рднреА рдЖрдк рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдпрд╣ рдирд╣реАрдВ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдЖрдкрдХрд╛ рдбреЗрдЯрд╛ рд▓реЗрдЖрдЙрдЯ рдХреНрдпрд╛ рд╣реИ рдФрд░ рдХреНрдпрд╛ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдореЗрд░рд╛ рд╕реБрдЭрд╛рд╡ рд╣реИ рдХрд┐ рдЖрдк рдкрд╣рд▓реЗ рдЙрди рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреЛ рдкреБрди: рдкреЗрд╢ рдХрд░реЗрдВ рдЬрд┐рдиреНрд╣реЗрдВ рдореИрдВрдиреЗ рдпрд╣рд╛рдВ рджрд┐рдЦрд╛рдпрд╛ рдерд╛ рддрд╛рдХрд┐ рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рд╣реЛ рд╕рдХреЗ рдХрд┐ рдпрд╣ рдПрдХ рд╡рд┐рдЬреНрдЮрд╛рди-рд╕реАрдЦрдиреЗ рд╡рд╛рд▓рд╛ рд╕рдВрд╕реНрдХрд░рдг рдореБрджреНрджрд╛ рдирд╣реАрдВ рд╣реИ (рдХреНрдпреЛрдВрдХрд┐ рдореИрдВ 0.22.2 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ) рдФрд░ рдпрджрд┐ рдЖрдк рдЗрд╕реЗ рдкреБрди: рдкреЗрд╢ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рддреЛ рдореЗрд░рд╛ рд╕реБрдЭрд╛рд╡ рд╣реИ рдХрд┐ рдЖрдк рдЕрдкрдиреЗ рдЫреЛрдЯреЗ рд╣рд┐рд╕реНрд╕реЛрдВ рд╕реЗ рд╢реБрд░реВ рдХрд░реЗрдВ рдбреЗрдЯрд╛ рдФрд░ рдЗрд╕рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░реЗрдВред ~104k рдирдореВрдиреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╕рдорд╕реНрдпрд╛ рдирд┐рд╡рд╛рд░рдг рдХреЗ рд▓рд┐рдП рдХрдард┐рди рд╣реИред

@hermidalc рдЙрддреНрддрд░ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж!
рдореИрдВ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЙрдкрд░реЛрдХреНрдд рдкрд░рд┐рдгрд╛рдо рдХреЛ рдкреБрди: рдЙрддреНрдкрдиреНрди рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВ, рдЗрд╕рд▓рд┐рдП рдореИрдВ рдЕрдм рдПрдХ рдЫреЛрдЯреЗ рдбреЗрдЯрд╛ рдХреЗ рд╕рд╛рде рд╕рдорд╕реНрдпрд╛ рдирд┐рд╡рд╛рд░рдг рдХрд░ рд░рд╣рд╛ рд╣реВрдВред

+1

рдХрд┐рд╕реА рдХреЛ рднреА рдмреБрд░рд╛ рд▓рдЧрддрд╛ рд╣реИ рдЕрдЧрд░ рдореИрдВ рдЗрд╕ рдореБрджреНрджреЗ рдХреЛ рдЙрдард╛рдКрдВ?
рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ #15239 https://github.com/scikit-learn/scikit-learn/issues/13621#issuecomment -600894432 рдХреЗ рд╕рд╛рде рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдПрдХ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реИ рдФрд░ рдХреЗрд╡рд▓ рдпреВрдирд┐рдЯ рдкрд░реАрдХреНрд╖рдг рдХрд░рдирд╛ рдмрд╛рдХреА рд╣реИред

рдХреНрдпрд╛ рдпрд╣ рдкреГрд╖реНрда рдЙрдкрдпреЛрдЧреА рдерд╛?
0 / 5 - 0 рд░реЗрдЯрд┐рдВрдЧреНрд╕

рд╕рдВрдмрдВрдзрд┐рдд рдореБрджреНрджреЛрдВ

StevenLOL picture StevenLOL  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

murata-yu picture murata-yu  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

vitorcoliveira picture vitorcoliveira  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

yinruiqing picture yinruiqing  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

celiafish picture celiafish  ┬╖  4рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ