Parametr „stratify” z metody „train_test_split” (scikit Learn)

96

Próbuję użyć train_test_splitz pakietu scikit Learn, ale mam problem z parametrem stratify. Poniżej znajduje się kod:

from sklearn import cross_validation, datasets 

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

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

Jednak pojawia się następujący 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])}

Czy ktoś ma pomysł, co się dzieje? Poniżej znajduje się dokumentacja funkcji.

[…]

stratyfikacja : podobna do tablicy lub Brak (domyślnie Brak)

Jeśli nie ma wartości Brak, dane są dzielone w sposób warstwowy, używając tego jako tablicy etykiet.

Nowość w wersji 0.17: podział na warstwy

[…]

Daneel Olivaw
źródło
Nie, wszystko rozwiązane.
Daneel Olivaw

Odpowiedzi:

62

Scikit-Learn po prostu mówi ci, że nie rozpoznaje argumentu „stratyfikacja”, a nie, że używasz go nieprawidłowo. Dzieje się tak, ponieważ parametr został dodany w wersji 0.17, jak wskazano w cytowanej dokumentacji.

Musisz więc tylko zaktualizować Scikit-Learn.

Borja
źródło
Otrzymuję ten sam błąd, chociaż mam wersję 0.21.2 scikit-learn. scikit-learn 0.21.2 py37h2a6a0b8_0 conda-forge
Kareem Jeiroudi
338

Ten stratifyparametr powoduje podział tak, aby proporcja wartości w wytworzonej próbie była taka sama, jak proporcja wartości przekazanych do parametru stratify.

Na przykład, jeśli zmienna yjest binarną zmienną kategorialną z wartościami 0i 1zawiera 25% zer i 75% jedynek, stratify=yupewni się, że losowy podział ma 25% 0i 75% wartości 1.

Fazzolini
źródło
124
To tak naprawdę nie odpowiada na pytanie, ale jest bardzo przydatne do zrozumienia, jak to działa. Dzięki za tonę.
Reed Jessen
6
Nadal trudno mi zrozumieć, dlaczego to rozwarstwienie jest konieczne: jeśli w danych występuje równowaga klas, czy nie zostanie ona zachowana średnio podczas wykonywania losowego podziału danych?
Holger Brandl
15
@HolgerBrandl będzie średnio zachowywany; ze stratyfikacją, na pewno zostanie zachowany.
Yonatan,
7
@HolgerBrandl z bardzo małymi lub bardzo niezrównoważonymi zestawami danych, jest całkiem możliwe, że losowy podział może całkowicie wyeliminować klasę z jednego z podziałów.
cddt
1
@HolgerBrandl Dobre pytanie! Może moglibyśmy najpierw dodać, że musisz podzielić na zbiór treningowy i testowy za pomocą stratify. Następnie, po drugie, aby skorygować nierównowagę, ostatecznie musisz przeprowadzić oversampling lub undersampling na zbiorze uczącym. Wiele klasyfikatorów Sklearn ma parametr zwany wagą klasy, który można ustawić na zrównoważony. Na koniec możesz również wybrać bardziej odpowiednią metrykę niż dokładność dla niezrównoważonego zbioru danych. Spróbuj, F1 lub obszar pod ROC.
Claude COULOMBE
65

Dla mojej przyszłej osoby, która przychodzi tutaj przez Google:

train_test_splitjest teraz w model_selection, stąd:

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)

jest sposobem na użycie go. Ustawienie random_statejest pożądane ze względu na powtarzalność.

Martin Thoma
źródło
To powinna być odpowiedź :) Dzięki
SwimBikeRun
17

W tym kontekście stratyfikacja oznacza, że ​​metoda train_test_split zwraca podzbiory treningowe i testowe, które mają takie same proporcje etykiet klas, jak zbiór danych wejściowych.

X. Wang
źródło
3

Spróbuj uruchomić ten kod, to „po prostu działa”:

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
źródło
@ user5767535 Jak widać, działa na moim komputerze z Ubuntu, z sklearnwersją '0.17', dystrybucją Anaconda dla Pythona 3,5. Mogę tylko zasugerować sprawdzenie jeszcze raz, jeśli poprawnie wprowadzisz kod i zaktualizujesz oprogramowanie.
Siergiej Buszmanow
2
@ user5767535 BTW, „Nowość w wersji 0.17: podział warstwowy” daje mi prawie pewność, że musisz zaktualizować swoje sklearn...
Sergey Bushmanov