Параметр “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.