Параметр “stratify” з методу “train_test_split” (scikit Learn)


94

Я намагаюся використовувати train_test_splitпакет scikit Learn, але у мене проблеми з параметром 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 (за замовчуванням None)

Якщо не None, дані поділяються стратифіковано, використовуючи це як масив міток.

Нове у версії 0.17: розшаруйте розділення

[...]


Ні, все вирішено.
Daneel Olivaw

Відповіді:


58

Scikit-Learn просто повідомляє вам, що не розпізнає аргумент "розшарувати", не те, що ви використовуєте його неправильно. Це пов’язано з тим, що параметр додано у версії 0.17, як зазначено у цитованій документації.

Тож вам просто потрібно оновити Scikit-Learn.


Я отримую ту саму помилку, хоча у мене є версія 0.21.2 scikit-learn. scikit-learn 0.21.2 py37h2a6a0b8_0 conda-forge
Карім Джейруді,

326

Цей stratifyпараметр робить розподіл так, що частка значень у створеній вибірці буде такою ж, як частка значень, наданих параметру stratify.

Наприклад, якщо змінна yє двійковою категоріальною змінною зі значеннями 0і, 1і є 25% нулів і 75% одиниць, stratify=yпереконайтеся, що у вашому випадковому розбитті є 25% з 0і 75% з 1.


117
Це насправді не відповідає на запитання, але надзвичайно корисно для простого розуміння того, як це працює. Дякую тонна.
Рід Джессен

6
Я все ще намагаюся зрозуміти, чому необхідна така стратифікація: якщо в даних є баланс класу, чи не буде він збережений в середньому при випадковому розбитті даних?
Holger Brandl

14
@HolgerBrandl це буде збережено в середньому; з розшаруванням він точно збережеться.
Йонатан

7
@HolgerBrandl з дуже малими або дуже незбалансованими наборами даних, цілком можливо, що випадковий поділ може повністю усунути клас з одного з розділів.
cddt

1
@HolgerBrandl Гарне запитання! Можливо, ми могли б додати, що спочатку вам потрібно розділити тренувальний і тестовий набір за допомогою stratify. Потім друге, щоб виправити дисбаланс, зрештою потрібно виконати передискретизацію або недодискретизацію на тренувальному наборі. Багато класифікаторів Sklearn мають параметр, який називається клас-вага, який ви можете встановити збалансованим. Нарешті, ви також можете взяти більш відповідну метрику, ніж точність для незбалансованого набору даних. Спробуйте, F1 або область під ROC.
Клод КУЛОМБ

62

Для мого майбутнього, хто приходить сюди через 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бажано для відтворюваності.


Це має бути відповіддю :) Дякую
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 Як ви бачите, це працює на моїй машині Ubuntu, з sklearnверсією '0.17', розподіл Anaconda для Python 3,5. Я можу запропонувати перевірити ще раз, якщо правильно ввести код та оновити програмне забезпечення.
Сергій Бушманов

2
@ user5767535 BTW, "Нове у версії 0.17: розшарування розбиття" робить мене майже впевненим, що вам доведеться оновити свій sklearn...
Сергій Бушманов,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.