Parameter "stratify" aus der Methode "train_test_split" (scikit Learn)

86

Ich versuche, train_test_splitvon Paket scikit Learn zu verwenden, aber ich habe Probleme mit Parametern stratify. Im Folgenden ist der Code:

from sklearn import cross_validation, datasets 

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

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

Ich bekomme jedoch immer wieder das folgende Problem:

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

Hat jemand eine Idee was los ist? Unten finden Sie die Funktionsdokumentation.

[...]

stratifizieren : Array-ähnlich oder Keine (Standard ist Keine)

Wenn nicht Keine, werden die Daten geschichtet aufgeteilt, wobei dies als Beschriftungsarray verwendet wird.

Neu in Version 0.17: stratify Spaltung

[...]

Daneel Olivaw
quelle
Nein, alles gelöst.
Daneel Olivaw

Antworten:

56

Scikit-Learn sagt Ihnen nur, dass es das Argument "stratifizieren" nicht erkennt, nicht, dass Sie es falsch verwenden. Dies liegt daran, dass der Parameter in Version 0.17 hinzugefügt wurde, wie in der von Ihnen angegebenen Dokumentation angegeben.

Sie müssen also nur Scikit-Learn aktualisieren.

Borja
quelle
Ich erhalte den gleichen Fehler, obwohl ich Version 0.21.2 von scikit-learn habe. scikit-learn 0.21.2 py37h2a6a0b8_0 conda-forge
Kareem Jeiroudi
302

Dieser stratifyParameter teilt sich so auf, dass der Anteil der Werte in der erzeugten Probe dem Anteil der Werte entspricht, die dem Parameter zur Verfügung gestellt werden stratify.

Zum Beispiel, wenn die Variable yist eine binäre kategoriale Variable mit Werten 0und 1ist und 25% von Nullen und 75% von Einsen, stratify=ywird sicherstellen , dass Ihre zufällige Split 25% hat 0‚s und 75% 1‘ s.

Fazzolini
quelle
105
Dies beantwortet die Frage nicht wirklich, ist aber sehr nützlich, um zu verstehen, wie es funktioniert. Danke vielmals.
Reed Jessen
6
Ich habe immer noch Schwierigkeiten zu verstehen, warum diese Schichtung notwendig ist: Wenn die Daten ein Klassenungleichgewicht aufweisen, würden sie bei einer zufälligen Aufteilung der Daten nicht im Durchschnitt beibehalten?
Holger Brandl
12
@HolgerBrandl es wird im Durchschnitt erhalten bleiben; mit stratify wird es sicher erhalten bleiben.
Yonatan
6
@HolgerBrandl mit sehr kleinen oder sehr unausgeglichenen Datensätzen ist es durchaus möglich, dass durch die zufällige Aufteilung eine Klasse vollständig aus einer der Aufteilungen entfernt wird.
cddt
1
@ HolgerBrandl Schöne Frage! Vielleicht können wir das zuerst hinzufügen, Sie müssen sich in Trainings- und Test-Sets mit aufteilen stratify. Zweitens müssen Sie zur Korrektur des Ungleichgewichts eventuell eine Über- oder Unterabtastung des Trainingssatzes durchführen. Viele Sklearn-Klassifikatoren haben einen Parameter namens Klassengewicht, den Sie auf ausgeglichen einstellen können. Schließlich könnten Sie auch eine geeignetere Metrik als die Genauigkeit für einen unausgeglichenen Datensatz verwenden. Versuchen Sie, F1 oder Bereich unter ROC.
Claude COULOMBE
55

Für mein zukünftiges Ich, das über Google hierher kommt:

train_test_splitist jetzt in model_selection, daher:

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)

ist der Weg, es zu benutzen. Das Einstellen von random_stateist für die Reproduzierbarkeit wünschenswert.

Martin Thoma
quelle
Dies sollte die Antwort sein :) Danke
SwimBikeRun
15

In diesem Zusammenhang bedeutet Schichtung, dass die train_test_split-Methode Trainings- und Testteilmengen zurückgibt, die dieselben Anteile an Klassenbezeichnungen wie das Eingabedatensatz haben.

X. Wang
quelle
3

Versuchen Sie, diesen Code auszuführen, er "funktioniert einfach":

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])
Sergey Bushmanov
quelle
@ user5767535 Wie Sie vielleicht sehen, funktioniert es auf meinem Ubuntu-Computer mit sklearnder Version '0.17', Anaconda Distribution für Python 3.5. Ich kann nur empfehlen, noch einmal zu überprüfen, ob Sie den Code korrekt eingegeben und Ihre Software aktualisiert haben.
Sergey Bushmanov
2
@ user5767535 Übrigens, "Neu in Version 0.17: Stratify Splitting" macht mich fast sicher, dass Sie Ihre sklearn...
Sergey Bushmanov