scikit-learn 中的 StratifiedKFold 与 KFold

Posted

技术标签:

【中文标题】scikit-learn 中的 StratifiedKFold 与 KFold【英文标题】:StratifiedKFold vs KFold in scikit-learn 【发布时间】:2022-01-20 16:00:12 【问题描述】:

我用这段代码测试KFoldStratifiedKFold

import numpy as np
from sklearn.model_selection import KFold,StratifiedKFold

X = np.array([
    [1,2,3,4],
    [11,12,13,14],
    [21,22,23,24],
    [31,32,33,34],
    [41,42,43,44],
    [51,52,53,54],
    [61,62,63,64],
    [71,72,73,74]
])

y = np.array([0,0,0,0,1,1,1,1])

sfolder = StratifiedKFold(n_splits=4,random_state=0,shuffle=False)
floder = KFold(n_splits=4,random_state=0,shuffle=False)

for train, test in sfolder.split(X,y):
    print('Train: %s | test: %s' % (train, test))
print("StratifiedKFold done")

for train, test in floder.split(X,y):
    print('Train: %s | test: %s' % (train, test))
print("KFold done")

我发现StratifiedKFold可以保持标签比例,而KFold不能。

Train: [1 2 3 5 6 7] | test: [0 4]
Train: [0 2 3 4 6 7] | test: [1 5]
Train: [0 1 3 4 5 7] | test: [2 6]
Train: [0 1 2 4 5 6] | test: [3 7]
StratifiedKFold done
Train: [2 3 4 5 6 7] | test: [0 1]
Train: [0 1 4 5 6 7] | test: [2 3]
Train: [0 1 2 3 6 7] | test: [4 5]
Train: [0 1 2 3 4 5] | test: [6 7]
KFold done

好像StratifiedKFold比较好,那KFold是不是应该不用了?

何时使用KFold 而不是StratifiedKFold

【问题讨论】:

there 也提供了很好的答案(如果您还想在 StratifiedShuffleSplit 除了StratifiedKFoldKFold 之外潜水)。 【参考方案1】:

我认为您应该问“何时使用 StratifiedKFold 而不是 KFold?”。

您首先需要知道什么是“KFold”和“Stratified”。

KFold 是一个交叉验证器,将数据集分成 k 个折叠。

分层是为了保证数据集的每一折都有相同的 具有给定标签的观察比例。

所以,这意味着StratifiedKFoldKFold的改进版

因此,这个问题的答案是在处理具有不平衡类分布的分类任务时,我们应该更喜欢 StratifiedKFold 而不是 KFold


举例

假设有一个包含 16 个数据点且类别分布不平衡的数据集。在数据集中,12 个数据点属于 A 类,其余(即 4 个)属于 B 类。B 类与 A 类的比例为 1/3。如果我们使用 StratifiedKFold 并设置 k = 4,那么训练集将包括来自 A 类的 9 个数据点和来自 B 类的 3 个数据点,而测试集将包括来自 A 类的 3 个数据点和 1 个数据B类的点。

如我们所见,StratifiedKFold 保留了数据集的类分布,而 KFold 没有考虑到这一点。

【讨论】:

【参考方案2】:
Assume Classification problem, Having 3 class(A,B,C) to predict.

Class  No_of_instance

 A           50 
 B           50
 C           50

**StratifiedKFold**

If data-set is  divided  into 5 fold. Then each fold will contains 10 instance from each class, i.e. no of instance per class is equal and follow  uniform distribution.

**KFold**

it will randomly took 30 instance and no of instance per class may or may not be equal or uniform.

**When to use**

Classification task use StratifiedKFold, and regression task use Kfold .
 
But if dataset contains  large number of instance, both StratifiedKFold and Kfold can be used in classification task.

【讨论】:

【参考方案3】:

StratifiedKFold: 这个交叉验证对象是返回分层折叠的 KFold 的变体。通过保留每个类的样本百分比来进行折叠

KFold: 将数据集拆分为 k 个连续折叠。

StratifiedKFold 在训练和测试中需要balance of percentage each class 时使用。如果不需要,则使用KFOld

【讨论】:

以上是关于scikit-learn 中的 StratifiedKFold 与 KFold的主要内容,如果未能解决你的问题,请参考以下文章

scikit-learn 中的 DBSCAN(仅使用指标)

scikit-learn 中的不平衡

混淆矩阵中的 Scikit-learn 变化阈值

GradientBoostingClassifier 与 scikit-learn 中的 BaseEstimator?

如何修复 scikit-learn 中的令牌模式?

scikit-learn 中的测试集分区