#python #pandas #numpy #dataframe #scikit-learn
#python #pandas #numpy #фрейм данных #scikit-learn
Вопрос:
Я хочу разделить имеющийся у меня набор данных на test / train, одновременно гарантируя, что распределение классифицированных меток одинаково в обоих test / train. Для этого я использую опцию stratify, но она выдает ошибку следующим образом:
X_full_train, X_full_test, Y_full_train, Y_full_test = train_test_split(X_values_full, Y_values, test_size = 0.33, random_state = 42, stratify = True)
Сообщение об ошибке:
TypeError Traceback (most recent call last)
in
19
20
---> 21 X_full_train, X_full_test, Y_full_train, Y_full_test = train_test_split(X_values_full, Y_values, test_size = 0.33, random_state = 42, stratify = True)
22
23
~/anaconda3/lib/python3.8/site-packages/sklearn/model_selection/_split.py in train_test_split(*arrays, **options)
2150 random_state=random_state)
2151
-> 2152 train, test = next(cv.split(X=arrays[0], y=stratify))
2153
2154 return list(chain.from_iterable((_safe_indexing(a, train),
~/anaconda3/lib/python3.8/site-packages/sklearn/model_selection/_split.py in split(self, X, y, groups)
1744 to an integer.
1745 """
-> 1746 y = check_array(y, ensure_2d=False, dtype=None)
1747 return super().split(X, y, groups)
1748
~/anaconda3/lib/python3.8/site-packages/sklearn/utils/validation.py in inner_f(*args, **kwargs)
71 FutureWarning)
72 kwargs.update({k: arg for k, arg in zip(sig.parameters, args)})
---> 73 return f(**kwargs)
74 return inner_f
75
~/anaconda3/lib/python3.8/site-packages/sklearn/utils/validation.py in check_array(array, accept_sparse, accept_large_sparse, dtype, order, copy, force_all_finite, ensure_2d, allow_nd, ensure_min_samples, ensure_min_features, estimator)
647
648 if ensure_min_samples > 0:
--> 649 n_samples = _num_samples(array)
650 if n_samples < ensure_min_samples:
651 raise ValueError("Found array with %d sample(s) (shape=%s) while a"
~/anaconda3/lib/python3.8/site-packages/sklearn/utils/validation.py in _num_samples(x)
194 if hasattr(x, 'shape') and x.shape is not None:
195 if len(x.shape) == 0:
--> 196 raise TypeError("Singleton array %r cannot be considered"
197 " a valid collection." % x)
198 # Check that shape is returning an integer or default to len
TypeError: Singleton array array(True) cannot be considered a valid collection.
Когда я пытаюсь сделать это без опции stratify, это не выдает мне ошибку. Я думал, что это связано с тем, что мои метки Y не имеют минимального количества выборок, необходимого для равномерного распределения меток между тестом / поездом, но:
pp.pprint(Counter(Y_values))
дает:
Counter({13: 1084,
1: 459,
7: 364,
8: 310,
38: 295,
15: 202,
4: 170,
37: 105,
3: 98,
0: 85,
24: 79,
20: 78,
35: 76,
2: 75,
12: 74,
39: 72,
22: 71,
9: 63,
26: 59,
11: 55,
18: 55,
32: 53,
19: 53,
33: 53,
5: 52,
30: 42,
29: 42,
25: 41,
10: 39,
23: 38,
21: 38,
6: 38,
27: 37,
14: 36,
36: 36,
34: 34,
28: 33,
17: 31,
31: 30,
16: 30})
Ответ №1:
Согласно sklearn documentation
:
подобный stratifyarray, по умолчанию= None Если не None, данные разделяются стратифицированным образом, используя это в качестве меток классов.
Таким образом, он принимает не boolean
значение типа True
или False
, а сами метки классов.
Итак, вам нужно изменить:
X_full_train, X_full_test, Y_full_train, Y_full_test = train_test_split(X_values_full, Y_values, test_size = 0.33, random_state = 42, stratify = True)
Для:
X_full_train, X_full_test, Y_full_train, Y_full_test = train_test_split(X_values_full, Y_values, test_size = 0.33, random_state = 42, stratify = Y_values)
Ответ №2:
- Разъяснение ошибки:
Я думаю, что эта ошибка возникает из-за того, что ваша метка является непрерывной, а не категориальной. И по своей природе stratify не может работать с непрерывным столбцом, который имеет много уникальных значений. Простое решение — создать новый столбец, который кодирует ваш Y_label
в категориальный, например Y_label_cat
: Y_values_cat = pd.qcut(Y_values,[0, .25, .5, .75, 1.],labels = ["1st","2nd","3rd","4th"])
, а затем вы можете передать параметр следующим образом: stratify = Y_label_cat
- Окончательный код:
X_full_train, X_full_test, Y_full_train, Y_full_test = train_test_split(X_values_full, Y_values, test_size = 0.33, random_state = 42, stratify = Y_label_cat)