Мне нужно разделить мои данные на обучающий набор (75%) и тестовый набор (25%). В настоящее время я делаю это с помощью кода ниже:
X, Xt, userInfo, userInfo_train = sklearn.cross_validation.train_test_split(X, userInfo)
Однако я хотел бы стратифицировать свой набор тренировочных данных. Как я могу это сделать? Я изучал этот StratifiedKFold
метод, но не позволял мне указывать разделение 75% / 25% и только стратифицировать набор обучающих данных.
TL; DR: используйте StratifiedShuffleSplit с
test_size=0.25
Scikit-learn предоставляет два модуля для стратифицированного разбиения:
n_folds
обучения / тестирования, так что классы одинаково сбалансированы в обоих.Вот код (прямо из документации выше)
>>> skf = cross_validation.StratifiedKFold(y, n_folds=2) #2-fold cross validation >>> len(skf) 2 >>> for train_index, test_index in skf: ... print("TRAIN:", train_index, "TEST:", test_index) ... X_train, X_test = X[train_index], X[test_index] ... y_train, y_test = y[train_index], y[test_index] ... #fit and predict with X_train/test. Use accuracy metrics to check validation performance
n_iter=1
. Здесь вы можете указать размер теста так же, как вtrain_test_split
Код:
>>> sss = StratifiedShuffleSplit(y, n_iter=1, test_size=0.5, random_state=0) >>> len(sss) 1 >>> for train_index, test_index in sss: ... print("TRAIN:", train_index, "TEST:", test_index) ... X_train, X_test = X[train_index], X[test_index] ... y_train, y_test = y[train_index], y[test_index] >>> # fit and predict with your classifier using the above X/y train/test
источник
0.18.x
,n_iter
должно бытьn_splits
дляStratifiedShuffleSplit
- и что для него есть немного другой API: scikit-learn.org/stable/modules/generated/…y
это серия Pandas, используйтеy.iloc[train_index], y.iloc[test_index]
dataframe index: 2,3,5
the first split in sss:[(array([2, 1]), array([0]))]
:(X_train, X_test = X[train_index], X[test_index]
вызове строки она отменяетX_train
иX_test
? Почему тогда не синглnext(sss)
?Вот пример непрерывных / регрессионных данных (пока эта проблема на GitHub не будет решена).
min = np.amin(y) max = np.amax(y) # 5 bins may be too few for larger datasets. bins = np.linspace(start=min, stop=max, num=5) y_binned = np.digitize(y, bins, right=True) X_train, X_test, y_train, y_test = train_test_split( X, y, stratify=y_binned )
start
min иstop
max вашей непрерывной цели.right=True
тогда ваше максимальное значение будет более или менее выделено в отдельную корзину, и ваше разделение всегда будет терпеть неудачу, потому что в этой дополнительной корзине будет слишком мало образцов.источник
Вы можете просто сделать это с помощью
train_test_split()
метода, доступного в Scikit learn:from sklearn.model_selection import train_test_split train, test = train_test_split(X, test_size=0.25, stratify=X['YOUR_COLUMN_LABEL'])
Я также подготовил небольшой GitHub Gist, который показывает, как
stratify
работает опция:https://gist.github.com/SHi-ON/63839f3a3647051a180cb03af0f7d0d9
источник
В дополнение к принятому ответу @Andreas Mueller просто хочу добавить это как @tangy, упомянутый выше:
StratifiedShuffleSplit больше всего похож на train_test_split (stratify = y) с дополнительными функциями:
источник
#train_size is 1 - tst_size - vld_size tst_size=0.15 vld_size=0.15 X_train_test, X_valid, y_train_test, y_valid = train_test_split(df.drop(y, axis=1), df.y, test_size = vld_size, random_state=13903) X_train_test_V=pd.DataFrame(X_train_test) X_valid=pd.DataFrame(X_valid) X_train, X_test, y_train, y_test = train_test_split(X_train_test, y_train_test, test_size=tst_size, random_state=13903)
источник
Обновление ответа @tangy сверху до текущей версии scikit-learn: 0.23.2 ( документация StratifiedShuffleSplit ).
from sklearn.model_selection import StratifiedShuffleSplit n_splits = 1 # We only want a single split in this case sss = StratifiedShuffleSplit(n_splits=n_splits, test_size=0.25, random_state=0) for train_index, test_index in sss.split(X, y): X_train, X_test = X[train_index], X[test_index] y_train, y_test = y[train_index], y[test_index]
источник