#python #pandas #scikit-learn #cross-validation
Вопрос:
У меня есть фрейм данных, который выглядит так.
d = {'col1': [1, 2,3,4,5,6,7,8], 'col2': ['a', 'a','b', 'b', 'c', 'c', 'd', 'd']}
df = pd.DataFrame(data=d)
df
col1 col2
0 1 a
1 2 a
2 3 b
3 4 b
4 5 c
5 6 c
6 7 d
7 8 d
Когда я использую перекрестную проверку k-кратности, я хочу убедиться, что значения в col2 присутствуют либо только в наборе поездов, либо в наборе тестов. То есть во время разделения, если df['col2'][0] = a
, и df['col2'][1] = a
, то строки с индексами 0 и 1 должны быть как в наборе поездов , так и в тестовом наборе. Не должно быть так, чтобы строка 0 находилась в наборе поездов, а строка 1-в наборе тестов.
Есть ли простой способ сделать это?
Изменить: Есть ли способ просто разделить фрейм данных на два, чтобы каждая часть содержала все точки данных, имеющие значение a
col2
в первом фрейме данных или во втором, но не в обоих? Я пытался использовать groupby
, но он возвращает объект, и когда я преобразую его в словарь, я могу получить к нему доступ только с помощью ключей, т. Е. a, b, c, d
Ответ №1:
Вы можете убедиться, что значение переменной присутствует только в наборе, выполнив GroupShuffleSplit
следующее:
from sklearn.model_selection import GroupShuffleSplit
import pandas as pd
d = {'col1': [1, 2,3,4,5,6,7,8],
'col2': ['a', 'a','b', 'b', 'c', 'c', 'd', 'd'],
'label': [1,1,1,1,0,0,0,0]}
df = pd.DataFrame(data=d)
X = df[['col1', 'col2']]
y = df['label']
groups= df['col2']
gss = GroupShuffleSplit(n_splits=2, train_size=.8, random_state=42)
for train_idx, test_idx in gss.split(X, y, groups):
X_train, X_test = X.iloc[train_idx], X.iloc[test_idx]
y_train, y_test = y.iloc[train_idx], y.iloc[test_idx]
Комментарии:
1. Это здорово, большое вам спасибо. Приведет ли это также к стратифицированному разделению между данными поезда и тестовыми данными? Мой ярлык на самом деле является третьей колонкой.
2. Проблема в том, что sklearn предлагает только возможность получить
stratified
илиgroup
разделить. Нет никакого стратифицированного группового разделения. но ты можешь написать свой собственный.3. Спасибо, это действительно приятно знать. Если я напишу свой собственный раздел группы стратификации, будет ли правильным подходом разделить ее на группы, а затем проверить метки в каждом разделении и обменять только эти строки? Или есть другой способ продолжить?
4. Я бы выполнил стратификационное разделение на уникальные значения
col2
, а затем нашел бы образцы X, которые имеют эти значения col2. Но вы не можете быть уверены, что получившаяся группа будет иметь правильный размер. В зависимости от представления одного значения col2 результирующий набор может отличаться.5. похоже, что у sklearn он уже находится на стадии разработки , однако при попытке его использования я получаю ошибку импорта.
Ответ №2:
С помощью @Antoine Dubuis я нашел реализацию sklearn того, что я хотел сделать, — под названием StratifiedGroupKFold.
Он все еще находится в разработке по состоянию на июль 2021 года, но может быть использован в версии для разработки/ночной версии. Я советую создать отдельную виртуальную среду для ее использования.
Я использовал его, и в настоящее время он, похоже, работает, поэтому надеюсь, что скоро он будет выпущен в стабильном выпуске.