【问题标题】:How to combine Scikit Learn's GroupKFold and StratifieKFold如何结合 Scikit Learn 的 GroupKFold 和 StratifieKFold
【发布时间】:2020-12-19 05:23:08
【问题描述】:

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

【问题讨论】:

    标签: scikit-learn data-science k-fold


    【解决方案1】:
    def stratified_group_k_fold(X, y, groups, k, seed=None):
        """Source: https://www.kaggle.com/jakubwasikowski/stratified-group-k-fold-cross-validation """
        labels_num = np.max(y) + 1
        y_counts_per_group = collections.defaultdict(lambda: np.zeros(labels_num))
        y_distr = collections.Counter()
        for label, g in zip(y, groups):
            y_counts_per_group[g][label] += 1
            y_distr[label] += 1
    
        y_counts_per_fold = collections.defaultdict(lambda: np.zeros(labels_num))
        groups_per_fold = collections.defaultdict(set)
    
        def eval_y_counts_per_fold(y_counts, fold):
            y_counts_per_fold[fold] += y_counts
            std_per_label = []
            for label in range(labels_num):
                label_std = np.std([y_counts_per_fold[i][label] / y_distr[label] for i in range(k)])
                std_per_label.append(label_std)
            y_counts_per_fold[fold] -= y_counts
            return np.mean(std_per_label)
    
        groups_and_y_counts = list(y_counts_per_group.items())
        random.Random(seed).shuffle(groups_and_y_counts)
    
        for g, y_counts in sorted(groups_and_y_counts, key=lambda x: -np.std(x[1])):
            best_fold = None
            min_eval = None
            for i in range(k):
                fold_eval = eval_y_counts_per_fold(y_counts, i)
                if min_eval is None or fold_eval < min_eval:
                    min_eval = fold_eval
                    best_fold = i
            y_counts_per_fold[best_fold] += y_counts
            groups_per_fold[best_fold].add(g)
    
        all_groups = set(groups)
        for i in range(k):
            train_groups = all_groups - groups_per_fold[i]
            test_groups = groups_per_fold[i]
    
            train_indices = [i for i, g in enumerate(groups) if g in train_groups]
            test_indices = [i for i, g in enumerate(groups) if g in test_groups]
    
            yield train_indices, test_indices
    

    【讨论】:

      猜你喜欢
      • 2017-04-10
      • 2018-06-16
      • 2014-09-10
      • 2016-03-21
      • 2017-06-20
      • 2018-08-02
      • 2018-06-21
      • 2013-01-29
      • 2019-12-09
      相关资源
      最近更新 更多