来自方法 "train_test_split" 的参数 "stratify" (scikit Learn)

Parameter "stratify" from method "train_test_split" (scikit Learn)

我正在尝试使用包 scikit Learn 中的 train_test_split,但我在使用参数 stratify 时遇到了问题。以下是代码:

from sklearn import cross_validation, datasets 

X = iris.data[:,:2]
y = iris.target

cross_validation.train_test_split(X,y,stratify=y)

但是,我不断遇到以下问题:

raise TypeError("Invalid parameters passed: %s" % str(options))
TypeError: Invalid parameters passed: {'stratify': array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2])}

有人知道发生了什么事吗?下面是函数文档。

[...]

stratify : array-like or None (default is None)

If not None, data is split in a stratified fashion, using this as the labels array.

New in version 0.17: stratify splitting

[...]

试试 运行 这个代码,它 "just works":

from sklearn import cross_validation, datasets 

iris = datasets.load_iris()

X = iris.data[:,:2]
y = iris.target

x_train, x_test, y_train, y_test = cross_validation.train_test_split(X,y,train_size=.8, stratify=y)

y_test

array([0, 0, 0, 0, 2, 2, 1, 0, 1, 2, 2, 0, 0, 1, 0, 1, 1, 2, 1, 2, 0, 2, 2,
       1, 2, 1, 1, 0, 2, 1])

stratify 参数进行拆分,以便生成的样本中值的比例与提供给参数 stratify 的值的比例相同。

例如,如果变量 y 是一个具有值 01 的二元分类变量,并且有 25% 的零和 75% 的一,stratify=y 将确保您的随机拆分具有 0 的 25% 和 1 的 75%。

Scikit-Learn 只是告诉您它无法识别参数 "stratify",并不是说您使用不当。这是因为该参数是在 0.17 版本中添加的,如您引用的文档中所示。

所以你只需要更新 Scikit-Learn。

致通过Google来到这里的未来的自己:

train_test_split 现在在 model_selection,因此:

from sklearn.model_selection import train_test_split

# given:
# features: xs
# ground truth: ys

x_train, x_test, y_train, y_test = train_test_split(xs, ys,
                                                    test_size=0.33,
                                                    random_state=0,
                                                    stratify=ys)

是使用方法。设置 random_state 有利于重现性。

在此上下文中,分层意味着 train_test_split 方法 returns 训练和测试子集与输入数据集具有相同比例的 class 标签。

我可以给出的答案是,分层 保留了数据在目标列中的分布比例 - 并在 train_test_split 中描述了相同的分布比例. 举个例子,如果问题是二元分类问题,目标列的比例为 80% = yes,20% = no.由于目标列中'yes''no'多4倍,通过拆分成train和test而不分层,我们可能 运行 陷入只有 'yes' 落入我们训练集的麻烦,而所有 'no' 落入我们的测试集。(即,训练集的目标列中可能没有 'no'

因此,通过分层,训练集的目标列具有 80% 的 'yes' 和 20% 的 'no',并且 测试集 的目标列具有 80% 的 'yes' 和 20% 的 'no' 分别.

因此,Stratify 使 target(标签)在训练和测试集中均匀分布 - 就像它在原始数据集中的分布一样。

from sklearn.model_selection import train_test_split
X_train, y_train, X_test, y_test = train_test_split(features, target, test-size = 0.25, stratify = target, random_state = 43)