メソッド「train_test_split」のパラメーター「stratify」(scikit Learn)


94

train_test_splitパッケージscikitLearnから使用しようとしていますが、パラメーターに問題があります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:配列のようなまたはなし(デフォルトはなし)

Noneでない場合、データは、これをラベル配列として使用して、階層化された方法で分割されます。

バージョン0.17の新機能:分割の階層化

[...]


いいえ、すべて解決しました。
ダニールオリボー

回答:


58

Scikit-Learnは、引数「stratify」を認識しないと言っているだけであり、誤って使用しているわけではありません。これは、引用したドキュメントに示されているように、パラメーターがバージョン0.17で追加されたためです。

したがって、Scikit-Learnを更新する必要があります。


scikit-learnのバージョン0.21.2を使用していますが、同じエラーが発生します。 scikit-learn 0.21.2 py37h2a6a0b8_0 conda-forge
カリームジェイロウディ

325

このstratifyパラメーターは、生成されたサンプルの値の比率がパラメーターに提供された値の比率と同じになるように分割しますstratify

変数は、たとえば、y値を持つバイナリカテゴリ変数である01し、ゼロの25%と1の75%が存在し、stratify=yあなたのランダムな分割は25%持っていることを確認してます0さんとの75%1のを。


117
これは実際には質問に答えませんが、それがどのように機能するかを理解するのに非常に役立ちます。トンありがとう。
リードジェッセン2018年

6
なぜこの階層化が必要なのか、私はまだ理解するのに苦労しています。データにクラスのバランスが取れていない場合、データをランダムに分割するときに平均して保持されませんか?
Holger Brandl 2018年

14
@HolgerBrandl平均して保存されます。stratifyを使用すると、確実に保存されます。
ヨナタン

7
@HolgerBrandlのデータセットが非常に小さいか、非常に不均衡な場合、ランダム分割によって分割の1つからクラスが完全に削除される可能性があります。
CDDT

1
@HolgerBrandlいい質問です!最初にそれを追加できるかもしれませんstratify。を使用してトレーニングセットとテストセットに分割する必要があります。次に、不均衡を修正するには、最終的にトレーニングセットでオーバーサンプリングまたはアンダーサンプリングを実行する必要があります。多くのSklearn分類器には、balancedに設定できるclass-weightというパラメーターがあります。最後に、不均衡なデータセットの精度よりも適切なメトリックを使用することもできます。F1またはROCの下の領域を試してください。
クロード・コーロンブ

62

グーグル経由でここに来る私の将来の自己のために:

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再現性のために望ましいです。


これが答えになるはずです:)ありがとう
SwimBikeRun

15

このコンテキストでは、階層化とは、train_test_splitメソッドが、入力データセットと同じ比率のクラスラベルを持つトレーニングサブセットとテストサブセットを返すことを意味します。


3

このコードを実行してみてください、それは「うまくいく」:

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])

@ user5767535ご覧のとおりsklearn、「0.17」バージョンのPython3,5用のAnacondaディストリビューションのUbuntuマシンで動作しています。コードを正しく入力してソフトウェアを更新した場合にのみ、もう一度確認することをお勧めします。
セルゲイブッシュマノフ2016年

2
@ user5767535ところで、「バージョン0.17の新機能:分割の階層化」により、更新する必要があることがほぼ確実になりますsklearn...
Sergey
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.