Scikit-learn: 局化GroupKFold

䜜成日 2019幎04月11日  Â·  48コメント  Â·  ゜ヌス: scikit-learn/scikit-learn

説明

珟圚、sklearnには局化されたグルヌプkfold機胜がありたせん。 局化を䜿甚するか、グルヌプkfoldを䜿甚できたす。 ただし、䞡方があればよいでしょう。

私たちがそれを持っおいるず決めたら、私はそれを実装したいず思いたす。

最も参考になるコメント

興味のある人が自分のナヌスケヌスず、これから本圓に䜕を望んでいるのかを説明できればよいでしょう。

反埩枬定を行った堎合の医孊および生物孊での非垞に䞀般的な䜿甚䟋。
䟋MR画像からアルツハむマヌ病ADず健康な察照などの病気を分類したいずしたす。 同じ䞻題に぀いお、フォロヌアップセッションたたは瞊断的デヌタからの耇数のスキャンがある堎合がありたす。 合蚈1000人の被隓者がいお、そのうち200人がAD䞍均衡なクラスず蚺断されおいるず仮定したす。 ほずんどの被隓者は1回のスキャンを行いたすが、䞀郚の被隓者では2぀たたは3぀の画像を䜿甚できたす。 分類噚をトレヌニング/テストするずきは、デヌタの挏掩を防ぐために、同じ被写䜓からの画像が垞に同じ折り畳みにあるこずを確認する必芁がありたす。
これにはStratifiedGroupKFoldを䜿甚するのが最適です。局化しおクラスの䞍均衡を考慮したすが、サブゞェクトが異なるフォヌルドに衚瀺されおはならないずいうグルヌプ制玄がありたす。
NBそれを繰り返し可胜にするずいいでしょう。

以䞋の実装䟋は、 kaggle-kernelに觊発されおいたす。

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はい、私は同じようなこずを考えおいたした。 ただし、プルリク゚ストはただ開いおいるようです。 私は、グルヌプがフォヌルドを越えお繰り返されないこずを意味したした。 グルヌプずしおIDがある堎合、同じIDが耇数のフォヌルドにたたがっお発生するこずはありたせん

これはRFECVの䜿甚に関連しおいるこずを理解しおいたす。
珟圚、これはデフォルトでStratifiedKFoldcvを䜿甚したす。 そのfitもgroups =を取りたす
ただし、fitを実行するずきにグルヌプが尊重されないようです。 譊告なしバグず芋なされる堎合がありたす。

グルヌプ化ず階局化は、レコヌド間の䟝存関係がある非垞に䞍均衡なデヌタセットに圹立ちたす
私の堎合、同じ個人が耇数のレコヌドを持っおいたすが、分割の数に比べおただ倚数のグルヌプ=人がいたす。少数掟クラスの䞀意のグルヌプの数がどこかに近づくに぀れお、実際的な問題があるず思いたす分割数。

だから+1

これは間違いなく䟿利です。 たずえば、非垞に䞍均衡な時系列の医療デヌタを䜿甚しお、患者を分離したすが、ほが各フォヌルドで䞍均衡なクラスのバランスを取りたす。

たた、StratifiedKFoldはグルヌプをパラメヌタヌずしお受け取りたすが、グルヌプに埓っおグルヌプ化しないため、フラグを立おる必芁があるこずもわかりたした。

この機胜のもう1぀の良い䜿い方は、財務デヌタです。これは通垞、非垞に䞍均衡です。 私の堎合、同じ゚ンティティ異なる時点の耇数のレコヌドを持぀非垞に䞍均衡なデヌタセットがありたす。 リヌクを回避するためにGroupKFoldを実行したすが、䞍均衡が倧きいために、ポゞティブがほずんどたたはたったくないグルヌプになる可胜性があるため、階局化したす。

14524も参照しおください。

局化GroupShuffleSplitおよびGroupKFoldのもう1぀の䜿甚䟋は、生物孊的「反埩枬定」蚭蚈です。この蚭蚈では、被隓者たたは他の芪の生物孊的単䜍ごずに耇数のサンプルがありたす。 たた、生物孊の倚くの実䞖界のデヌタセットには、クラスの䞍均衡がありたす。 サンプルの各グルヌプには同じクラスがありたす。 したがっお、グルヌプを階局化しおたずめるこずが重芁です。

説明

珟圚、sklearnには局化されたグルヌプkfold機胜がありたせん。 局化を䜿甚するか、グルヌプkfoldを䜿甚できたす。 ただし、䞡方があればよいでしょう。

私たちがそれを持っおいるず決めたら、私はそれを実装したいず思いたす。

こんにちは、私はそれが医孊MLに非垞に圹立぀ず思いたす。 すでに実装されおいたすか

@amueller人々がこれに興味を持っおいるこずを考えるず、これを実装する必芁があるず思いたすか

私も非垞に興味がありたす...サンプルごずに耇数の耇補枬定倀がある堎合、分光法で非垞に圹立ちたす。亀差怜定の間、それらは実際に同じフォヌルドにずどたる必芁がありたす。 たた、分類しようずしおいる䞍均衡なクラスがいく぀かある堎合は、階局化機胜も䜿甚する必芁がありたす。 したがっお、私もそれに投祚したす 申し蚳ありたせんが、私は開発に参加するのに十分ではありたせんが、参加する人にずっおは、それが䜿甚されるこずを確信できたす:-)
すべおのチヌムに賛成です。 ありがずう

少なくずもStratifiedGroupKFoldで䜜業が詊みられおいるため、このスレッドで参照されおいる問題ずPRを確認しおください。 私はすでにStratifiedGroupShuffleSplit 15239を実行したしたが、これはテストが必芁ですが、私はすでに自分の䜜業にかなり䜿甚しおいたす。

実装すべきだず思いたすが、実際に䜕が欲しいのかはただわかりたせん。 @hermidalcには、同じグルヌプのメンバヌが同じクラスでなければならないずいう制限がありたす。 それは䞀般的なケヌスではありたせんよね

興味のある人が自分のナヌスケヌスず、これから本圓に䜕を望んでいるのかを説明できればよいでしょう。

1523914524ず9413がありたすが、これらはすべお異なるセマンティクスを持っおいるこずを芚えおいたす。

@amuellerはあなたに完党に同意したす。今日、利甚可胜なさたざたなバヌゞョン1523914524ず9413の間で䜕かを探しおいたしたが、これらのいずれかが私のニヌズに合うかどうかを本圓に理解できたせんでした。 それで、それが圹立぀なら、これが私のナヌスケヌスです
私は1000のサンプルを持っおいたす。 各サンプルはNIR分光蚈で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私はこの甚語にあたり粟通しおいたせんが、りィキペディアから「反埩枬定デザむン」は、「クロスオヌバヌ詊隓には反埩枬定デザむンがあり、同じクラス内に同じグルヌプが含たれおいる必芁がある」ずいう意味ではないようです。各患者は2぀以䞊の治療のシヌケンスに割り圓おられ、そのうちの1぀は暙準治療たたはプラセボである可胜性がありたす。」
これをML蚭定に関連付けるず、個人が治療を受けたばかりかプラセボを受けたかを枬定倀から予枬するか、治療を受けた結果を予枬するこずができたす。
どちらの堎合も、同じ個人のクラスが倉わる可胜性がありたすよね

名前に関係なく、クロスオヌバヌ詊隓で説明されおいるのず同様のケヌスに぀いお考えおいたずきに、どちらも同じナヌスケヌスを持っおいるように思えたす。 あるいは、もう少し単玔なこずかもしれたせん。時間の経過ずずもに患者が病気になるたたは良くなる可胜性があるため、患者の転垰が倉わる可胜性がありたす。

実際、リンク先のりィキペディアの蚘事には、「瞊断分析-反埩枬定デザむンにより、研究者は長期および短期の䞡方の状況で参加者が時間の経過ずずもにどのように倉化するかを監芖できたす」ず明瀺的に蚘茉されおいるため、クラスの倉曎が含たれおいるず思いたす。
同じ条件で枬定が行われるこずを意味する別の単語がある堎合、その単語を䜿甚できたすか

@amuellerはい、その通りです。このデザむンのナヌスケヌスでは、䞀般的なナヌスケヌスではなく、䞊蚘の誀った曞き方をしおいるこずに気付きたした。

反埩枬定の蚭蚈には非垞に耇雑なタむプが倚数ありStratifiedGroupShuffleSplitが、2぀のタむプでは、グルヌプ内で同じクラス制限が適甚されたす治療反応を予枬する際の治療前埌の瞊断サンプリング、耇数の前治療治療反応を予枬する際の、異なる身䜓䜍眮での被隓者ごずのサンプル。

すぐに機胜するものが必芁だったので、他の人が䜿甚したり、sklearnで䜕かを始めたりできるようにしたいず思いたした。さらに、間違いがなければ、グルヌプ内のクラスラベルが異なる堎合は、階局化ロゞックの蚭蚈がより耇雑になりたす。

@amuellerはい垞にそうです。 これらは、予枬にデバむスの内郚倉動性を含めるための同じ枬定倀の耇補です。

@hermidalcはい、この堎合ははるかに簡単です。 それが䞀般的なニヌズである堎合、私たちはそれを远加しおうれしいです。 名前から、それが䜕をするのかがある皋床明確であるこずを確認する必芁がありたす。たた、これら2぀のバヌゞョンが同じクラスに存圚する必芁があるかどうかを怜蚎する必芁がありたす。

StratifiedKFoldにこれを行わせるのは非垞に簡単なはずです。 2぀のオプションがありたす。各フォヌルドに同じ数のサンプルが含たれおいるこずを確認するか、各フォヌルドに同じ数のグルヌプが含たれおいるこずを確認したす。
2番目の方法は簡単です各グルヌプが単䞀のポむントであるず停っおStratifiedKFoldに枡すだけです。 それはあなたがあなたのPRでしおいるこずです、それはのように芋えたす。

GroupKFold最初に最小のフォヌルドに远加するこずで、ヒュヌリスティックに2぀をトレヌドオフするず思いたす。 それが局化されたケヌスにどのように倉換されるかはわかりたせんので、あなたのアプロヌチを䜿甚しお満足しおいたす。

同じPRにGroupStratifiedKFoldも远加する必芁がありたすか それずも埌でそれを残したすか
他のPRの目暙は少し異なりたす。 誰かがさたざたなナヌスケヌスが䜕であるかを曞き留めるこずができれば、それは良いこずです私はおそらく今は時間がありたせん。

すべおのサンプルが同じクラスを持぀グルヌプ制玄を個別に凊理する堎合は+1。

@hermidalcはい、この堎合ははるかに簡単です。 それが䞀般的なニヌズである堎合、私たちはそれを远加しおうれしいです。 名前から、それが䜕をするのかがある皋床明確であるこずを確認する必芁がありたす。たた、これら2぀のバヌゞョンが同じクラスに存圚する必芁があるかどうかを怜蚎する必芁がありたす。

私はこれを完党には理解しおいたせん。各グルヌプのメンバヌを異なるクラスにするこずができるStratifiedGroupShuffleSplitずStratifiedGroupKFoldは、ナヌザヌがすべおのグルヌプメンバヌを指定したずきに、たったく同じ分割動䜜をする必芁がありたす。同じクラスの。 埌で内郚を改善するこずができ、既存の動䜜は同じになるのはい぀ですか

2番目の方法は簡単です各グルヌプが単䞀のポむントであるず停っおStratifiedKFoldに枡すだけです。 それはあなたがあなたのPRでしおいるこずです、それはのように芋えたす。

GroupKFold最初に最小のフォヌルドに远加するこずで、ヒュヌリスティックに2぀をトレヌドオフするず思いたす。 それが局化されたケヌスにどのように倉換されるかはわかりたせんので、あなたのアプロヌチを䜿甚しお満足しおいたす。

同じPRにGroupStratifiedKFoldも远加する必芁がありたすか それずも埌でそれを残したすか
他のPRの目暙は少し異なりたす。 誰かがさたざたなナヌスケヌスが䜕であるかを曞き留めるこずができれば、それは良いこずです私はおそらく今は時間がありたせん。

䜿甚した「各グルヌプの単䞀サンプル」アプロヌチを䜿甚しお、 StatifiedGroupKFoldを远加したす。

興味のある人が自分のナヌスケヌスず、これから本圓に䜕を望んでいるのかを説明できればよいでしょう。

反埩枬定を行った堎合の医孊および生物孊での非垞に䞀般的な䜿甚䟋。
䟋MR画像からアルツハむマヌ病ADず健康な察照などの病気を分類したいずしたす。 同じ䞻題に぀いお、フォロヌアップセッションたたは瞊断的デヌタからの耇数のスキャンがある堎合がありたす。 合蚈1000人の被隓者がいお、そのうち200人がAD䞍均衡なクラスず蚺断されおいるず仮定したす。 ほずんどの被隓者は1回のスキャンを行いたすが、䞀郚の被隓者では2぀たたは3぀の画像を䜿甚できたす。 分類噚をトレヌニング/テストするずきは、デヌタの挏掩を防ぐために、同じ被写䜓からの画像が垞に同じ折り畳みにあるこずを確認する必芁がありたす。
これにはStratifiedGroupKFoldを䜿甚するのが最適です。局化しおクラスの䞍均衡を考慮したすが、サブゞェクトが異なるフォヌルドに衚瀺されおはならないずいうグルヌプ制玄がありたす。
NBそれを繰り返し可胜にするずいいでしょう。

以䞋の実装䟋は、 kaggle-kernelに觊発されおいたす。

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

stratifiedGroupKfoldの堎合は+1。 サムルトりォッチからセンサヌを取り出しお、高霢者の転倒を怜出しようずしおいたす。 萜䞋デヌタがあたりないため、さたざたなクラスを取埗するさたざたな時蚈を䜿甚しおシミュレヌションを実行したす。 たた、デヌタをトレヌニングする前に、デヌタの拡匵も行いたす。 各デヌタポむントから9぀のポむントを䜜成したす-これはグルヌプです。 説明されおいるように、グルヌプがトレヌニングずテストの䞡方に参加しないこずが重芁です

StratifiedGroupKFoldも䜿甚できるようにしたいず思いたす。 私は金融危機を予枬するためのデヌタセットを芋おいたす。ここで、各危機の数幎前、埌、および最䞭は独自のグルヌプです。 トレヌニングおよび盞互怜蚌䞭、各グルヌプのメンバヌはフォヌルド間でリヌクしないようにする必芁がありたす。

マルチラベルシナリオMultilabel_
stratifiedGroupKfold

このために+1。 スパムのナヌザヌアカりントを分析しおいるので、ナヌザヌごずにグルヌプ化したすが、スパムの発生率は比范的䜎いため、局別化したす。 私たちのナヌスケヌスでは、䞀床スパムを送信したナヌザヌはすべおのデヌタでスパマヌずしおフラグが立おられるため、グルヌプメンバヌは垞に同じラベルを持ちたす。

ドキュメントを組み立おるための叀兞的なナヌスケヌスを提䟛しおくれおありがずう、
@ philip-iv

StratifiedGroupShuffleSplitず同じPR15239にStratifiedGroupKFoldの実装を远加したした。

PRでわかるように、䞡方のロゞックは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の本栌的なバヌゞョンを次に瀺したす。これをさらに簡略化しお、いく぀か倉曎したした。 これらのクラスは、同じタむプの他のsklearnCVクラスがどのように実行されるかの蚭蚈にも準拠しおいたす。

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時々これを振り返るず、私たちが解決したこずに぀いおかなり混乱しおいたす。 残念ながら、私の時間は以前ずは異なりたすscikit-learnに含めるこずをお勧めするものに぀いお教えおください。

@hermidalc時々これを振り返るず、私たちが解決したこずに぀いおかなり混乱しおいたす。 残念ながら、私の時間は以前ずは異なりたすscikit-learnに含めるこずをお勧めするものに぀いお教えおください。

15239で行ったよりも優れた実装をしたいず思っおいたした。 そのPRでの実装は機胜したすが、論理を単玔化するためにグルヌプを階局化したすが、これは理想的ではありたせん。

したがっお、䞊蚘で行ったこずjakubwasikowskiの@mrunibeずkaggleのおかげでは、サンプルを階局化するStratifiedGroupKFoldのより良い実装です。 同じロゞックを移怍しおより良いStratifiedGroupShuffleSplitを実行したいので、準備が敎いたす。 叀い実装を眮き換えるために、新しいコヌドを15239に配眮したす。

未完成のPRに぀いおお詫び申し䞊げたす。博士号を取埗しおいるので、時間がありたせん。

実装を提䟛しおくれた@hermidalcず@mrunibeに感謝したす。 たた、クラスの䞍均衡が匷く、被隓者ごずのサンプル数が倧きく異なる医療デヌタを凊理するためのStratifiedGroupKFoldメ゜ッドを探しおいたした。 GroupKFold 、それ自䜓で、1぀のクラスのみを含むトレヌニングデヌタサブセットを䜜成したす。

同じロゞックを移怍しおより良いStratifiedGroupShuffleSplitを実行したいので、準備が敎いたす。

StratifiedGroupShuffleSplitの準備が敎う前に、$ StratifiedGroupKFoldをマヌゞするこずを怜蚎できたす。

未完成のPRに぀いおお詫び申し䞊げたす。博士号を取埗しおいるので、時間がありたせん。

サポヌトが必芁な堎合はお知らせください。

そしおあなたの博士号の仕事で頑匵っおください

提䟛されたコヌド@mrunibeを䜿甚したStratifiedGroupKFoldずRepeatedStratifiedGroupKFoldの本栌的なバヌゞョンを次に瀺したす。これをさらに簡略化しお、いく぀か倉曎したした。 これらのクラスは、同じタむプの他のsklearnCVクラスがどのように実行されるかの蚭蚈にも準拠しおいたす。

これを詊すこずは可胜ですか さたざたな䟝存関係のいく぀かを䜿甚しおカットアンドペヌストを詊みたしたが、終了したせんでした。 このクラスを私のプロゞェクトで詊しおみたいず思いたす。 それを行うために今利甚できる方法があるかどうかを確認しようずしおいたす。

@hermidalc博士号取埗が成功したこずを願っおいたす
地球科孊の博士号取埗にはグルヌプ制埡を備えたこの階局化機胜が必芁なので、この実装も行われるのを楜しみにしおいたす。 プロゞェクトで手動で分割するずいうこのアむデアの実装に数時間を費やしたした。 しかし、私は同じ理由でそれを終えるこずをあきらめたした...博士号の進歩。 ですから、博士号の仕事がどのように人の時間を苊しめるこずができるかを完党に理解するこずができたす。 笑プレッシャヌなし。 今のずころ、代わりにGroupShuffleSplitを䜿甚しおいたす。

也杯

@ bfeeny @ dispink䞊蚘の2぀のクラスを䜿甚するのは非垞に簡単です。 次のようなファむルを䜜成したす䟋 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で実行するず、機胜したす。 私は長い間これらのカスタムCVむテレヌタヌを仕事で䜿甚しおきたしたが、問題はありたせん。 ずころで、私は0.23.xではなくscikit-learn 0.22.2を䜿甚しおいるので、それが問題の原因であるかどうかはわかりたせん。 以䞋の䟋を実行しお、再珟できるかどうかを確認しおください。 可胜であれば、それはあなたの仕事に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 '同じグルヌプ内のすべおのサンプルが同じクラスラベルを持っおいるこずを確認する必芁がありたす。 明らかにそれが問題です。 同じグルヌプの私のサンプルは同じクラスを共有しおいたせん。 うヌん...それは開発の別のブランチのようです。
ずにかくありがずうございたした。

はい、これはここのさたざたなスレッドで議論されおいたす。 これは䟿利なもう1぀のより耇雑なナヌスケヌスですが、私のような倚くの人は珟圚そのナヌスケヌスを必芁ずしたせんが、グルヌプをたずめながらサンプルを階局化する䜕かが必芁です。 䞊蚘のコヌドの芁件は、各グルヌプのすべおのサンプルが同じクラスに属しおいるこずです。

実際、 @ 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]

したがっお、スクリヌンショットを䜿甚しおも、デヌタレむアりトが䜕であり、䜕が起こっおいるのかを実際に確認するこずはできないため、デヌタで䜕が起こっおいるのかよくわかりたせん。 ここで瀺した䟋を最初に再珟しお、scikit-learnバヌゞョンの問題ではないこずを確認するこずをお勧めしたす0.22.2を䜿甚しおいるため。再珟できる堎合は、デヌタずそれをテストしたす。 〜104kのサンプルを䜿甚するず、トラブルシュヌティングが困難になりたす。

@hermidalc返信ありがずうございたす
䞊蚘の結果を実際に再珟できるので、珟圚はより小さなデヌタでトラブルシュヌティングを行っおいたす。

+1

私がこの問題を取り䞊げおもいいですか
15239ずhttps://github.com/scikit-learn/scikit-learn/issues/13621#issuecomment -600894432にはすでに実装があり、単䜓テストのみを実行する必芁があるようです。

このペヌゞは圹に立ちたしたか
0 / 5 - 0 評䟡